I just want to ask how I can include popper.js in my bootstrap 5 using rollup compiler. Here is my rollup.config.js file . but It always said that "popper is not defined in my browser console . thanks
'use strict'
const path = require('path')
const { babel } = require('#rollup/plugin-babel')
const { nodeResolve } = require('#rollup/plugin-node-resolve')
import multi from '#rollup/plugin-multi-entry'
const banner = require('./banner.js')
let fileDest = 'child-theme.js'
const external = ['jquery','#popperjs/core']
const plugins = [
babel({
// Only transpile our source code
exclude: 'node_modules/**',
// Include the helpers in the bundle, at most one copy of each
babelHelpers: 'bundled'
}),
nodeResolve(),
multi()
]
const globals = {
jquery: 'jQuery', // Ensure we use jQuery which is always available even in noConflict mode
'#popperjs/core': 'Popper'
}
module.exports = {
input: [path.resolve(__dirname, '../js/bootstrap.js'), path.resolve(__dirname, '../js/skip-link-focus-fix.js'), path.resolve(__dirname, '../js/custom-javascript.js')],
output: {
banner,
file: path.resolve(__dirname, `../../js/${fileDest}`),
format: 'umd',
globals,
name: 'understrap'
},
external,
plugins
}
Related
I am converting a project to use webpack. But this project has two externally loaded scripts that i do not controll. These scripts require a library I provide via webpack to be global. So I use the expose-loader plugin to accomplish this but it is not working for me.
See project details below:
webpack config:
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
const PATHS = {
src: path.join(__dirname, 'src/'), //absolute path to RepoDir/src
dist: path.join(__dirname, 'dist/') //absolute path to RepoDir/dist
}
module.exports = {
entry: {
main: PATHS.src + 'javascript/app.js'
},
output: {
path: PATHS.dist,
filename: 'bundle.js'
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: 'src/images', to: 'images' },
{ from: 'src/models', to: 'models' }
]
}),
new webpack.ProvidePlugin({
THREE: 'three',
})
],
module: {
rules: [
{
test: require.resolve('three'),
loader: 'expose-loader',
options: {
exposes: 'THREE',
},
},
]
}
}
My index.html file:
<!-- 8th wall AR cdn scripts. -->
<!-- THESE two scripts below require THREE to be global (window.THREE) -->
<script src="https://cdn.8thwall.com/web/xrextras/xrextras.js"></script>
<script async src="https://apps.8thwall.com/xrweb?appKey=PRIVATEKEY"></script>
<script src="dist/bundle.js"></script>
App.js the entry file:
import THREE from 'three'
import { ARManager } from './modules/arManager';
const manager = new ARManager();
manager.startExperience('X1');
Just to make sure this is the error i am getting:
window.THREE does not exist but is required by xxx
If more context or information is needed please let me know so i can clarify.
I am a complete newb to webpack so all help and suggestions are much appreciated!
I'm bundling JS and CSS (compiled from SCSS) into two separate bundles, one for 3rd party (vendor) and one for the project code (company). I'm able to access jQuery via $ successfully from scripts in the company bundle as a global, such as from some-other-script.js, without any issues. However when trying to call the stickyTableHeaders function from the StickyTableHeaders plugin in table-headers.js: Uncaught TypeError: $(...).stickyTableHeaders is not a function. I don't get any other errors about loading scripts etc. and I can see that vendor.bundle.js includes the plugin code.
Additionally I see from the bottom of the plugin source that the function is meant to be added to $ as follows:
$.fn[name] = function ( options ) {
return this.each(function () {
var instance = $.data(this, 'plugin_' + name);
if (instance) {
if (typeof options === 'string') {
instance[options].apply(instance);
} else {
instance.updateOptions(options);
}
} else if(options !== 'destroy') {
$.data(this, 'plugin_' + name, new Plugin( this, options ));
}
});
};
Any ideas why it can't find the function on the $ (jQuery) object?
This question seems similar, however the poster was having trouble with the plugin not being able to find jQuery in that case. Additionally I'm not sure if using the import-loader as per one of the suggestions is the right approach in my case, or if I'm doing something fundamentally wrong. You can see commented out lines in the webpack.config.js below where I've tried to register sticky-table-headers as a plugin with webpack without success - same result.
My webpack.config.js is as follows:
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var extractSass = new ExtractTextPlugin({
filename: "[name].bundle.css",
disable: process.env.NODE_ENV === "development"
});
module.exports = function (env) {
env = env || {};
var isProd = env.NODE_ENV === 'production';
// Setup base config for all environments
var config = {
entry: {
vendor: './Client/js/vendor',
company: './Client/js/company' // Includes all SCSS, which ends up in company.bundle.css via extract-text-webpack-plugin.
},
output: {
// ReSharper disable once UseOfImplicitGlobalInFunctionScope
path: path.join(__dirname, 'wwwroot/dist'),
filename: '[name].bundle.js'
},
devtool: 'eval-source-map',
mode: "development",
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx'],
alias: {
"jquery.validation": "jquery-validation/dist/jquery.validate.js",
//"sticky-table-headers": "sticky-table-headers/js/jquery.stickytableheaders.js"
}
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default'],
//"sticky-table-headers": ["sticky-table-headers", "default"]
}),
extractSass
],
module: {
rules: [
{
test: /\.scss$/,
use: extractSass.extract({
use: [{
loader: "css-loader"
}, {
loader: "sass-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
}
]
}
}
// Alter config for prod environment
if (isProd) {
config.devtool = 'source-map'; // SourceMap emitted as a separate file.
//Normally disallow access on webserver or use (none) instead. Internal
//app so leaving them accessible for easier support.
config.mode = "production";
}
return config;
};
Then in vendor.js I have:
import 'jquery';
import 'popper.js';
import 'bootstrap';
import "jquery-validation";
import "jquery-validation-unobtrusive";
import "sticky-table-headers";
In company.js I have:
import '../scss/site.scss';
import './site';
import './some-other-script';
import './table-headers';
Finally in table-headers.js I have:
(function () {
$(function () {
if ($(".my-sticky-table-header").length === 0) return;
var offset = $('.navbar').height();
$(".my-sticky-table-header").stickyTableHeaders({
fixedOffset:offset});
});
})();
Thanks.
Looks like there was a fundamental flaw with this setup. I ended up adding:
import './vendor';
to the top of company.js and then using the SplitChunks plugin mentioned here to avoid everything in the vendor bundle being duplicated. This allowed library functions to be called from the company bundle.
(Something like this may have worked but it seems messy).
Hi I am currently using webpack to bundle my project files into a single file. However, I do not want webpack to bundle my config.js file where all my config is set. I would like to this remain separate in the output folder but not sure out to achieve this.
my current setup is
//index.js file
#!/usr/bin/env node
'use strict';
let config = require('config.js);
let read = require('read.js);
console.log('i am running through command line');
//read.js file
'use strict'
console.log('read a text file');
//config.js
'use strict';
module.exports = {
name: 'test'
}
//webpack.config.js
let webpack = require('webpack');
let path = require('path');
let fs = require('fs');
let nodeModules = {};
fs.readdirSync('node_modules')
.filter(function (x) {
return [ '.bin' ].indexOf(x) === -1;
})
.forEach(function (mod) {
nodeModules[mod] = 'commonjs ' + mod;
});
module.exports = {
entry: [ 'babel-polyfill', './index.js' ],
target: 'node',
node: {
__dirname: true
},
output: {
path: path.join(__dirname, 'webpack_bundle'),
filename: '[name].js',
libraryTarget: 'commonjs'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'shebang-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: [ 'es2015' ]
}
} ]
},
resolve: {
extensions: [ '.js' ]
},
plugins: [
new webpack.BannerPlugin({banner: '#!/usr/bin/env node', raw: true
})
]
,
externals: nodeModules
};
Note: I have significantly simplified the code example for brevity
Currently when i run the webpack command i get a folder webpack_bundle which contains an index.js file - the index.js file includes the dependencies config.js and read.js. However, what i would like is for the read.js dependency to be bundled into the index.js file but the config.js dependency to stay external in a separate file which gets required by the bundled webpack output. So the folder webpack_bundle should contain two files after running the webpack command - index.js and config.js. I have already tried to modify the externals by adding the following key value to the externals object config: './config.js' but this did not work. I also created an extra entrypoint by specifying config.js as the entrypoint but this also did not work. I can't figure this out and the webpack docs are not that clear on how to achieve this. Please help!
If you want your config in a separate bundle, you can create a split point, by importing dynamically your config.js file with require.ensure:
require.ensure([], function() {
let config = require('./config.js');
});
Your config will then be in a separate bundle.
Documentation about Code splitting (warning: Webpack 1.x is deprecated).
Documentation about Code Splitting (Webpack 2).
Edit:
If you don't want your config file to be bundled by Webpack, I think you can use IgnorePlugin:
module.exports = {
//...
plugins: [new webpack.IgnorePlugin(/^\.\/config\.js$/)]
}
And use copy-webpack-plugin to copy your config.js file.
I am trying to remove script tags for javascript libraries from my html, and so have removed underscore.js from a template page.
To replace this, within my index.js (webpack entry point), I have the following
import 'underscore';
The size of the webpack outputted bundle.js file increases by 50k when I do this, so I know that the library is in bundle.js. However, underscore is not available when I try to use it in the console on a page which has the bundle.js included.
Any thoughts would be appreciated.
const webpack = require('webpack');
const path = require('path');
const precss = require('precss');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const postcssImport = require('postcss-import');
module.exports = {
context: __dirname + '/frontend',
devtool: 'source-map',
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, './static'),
},
module: {
loaders: [
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/, query: { presets: ['es2015'] } },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap&importLoaders=1!postcss') },
],
},
vendor: [
'underscore',
],
plugins: [
new ExtractTextPlugin('si-styles.css'),
new webpack.ProvidePlugin({
underscore: 'underscore',
}),
],
postcss: function(webpack) {
return [
postcssImport({ addDependencyTo: webpack }), // Must be first item in list
precss,
autoprefixer({ browsers: ['last 2 versions'] }),
];
},
};
In order to achieve that you can use this webpack plugin:
new webpack.ProvidePlugin({
underscore: "underscore"
})
by the way it is not necessary that you import the library in the index file of your directory. You will have access to the library also specifying a new entry point in your webpack config file.. You could then put all your vendor code in a vendor.js boundle like so:
entry: {
main: [
'./app/js/main.js'
],
vendor: [
'underscore',
'lodash',
'my-awesome-library!'
]
}
UPDATE: There is a very good tutorial in how to use webpack in production on egghead.io.. Try to check it out!
I'm new to Django and ReactJS, was trying to compile a simple JSX code to JS using this tutorial : http://geezhawk.github.io/2016/02/02/using-react-with-django-rest-framework.html
Didn't work, so I used npm run dev to compile, now it worked but giving error in browser console : Uncaught ReferenceError: react is not defined
Here is my webpack.config.js
var path = require('path');
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var nodeExternals = require('webpack-node-externals');
module.exports = {
//the base directory (absolute path) for resolving the entry option
context: __dirname,
//the entry point we created earlier. Note that './' means
//your current directory. You don't have to specify the extension now,
//because you will specify extensions later in the `resolve` section
entry: './assets/js/index',
output: {
//where you want your compiled bundle to be stored
path: path.resolve('./assets/bundles/'),
//naming convention webpack should use for your files
filename: '[name]-[hash].js',
},
target: 'node', // in order to ignore built-in modules like path, fs, etc.
externals: {
react: 'react'
}, // in order to ignore all modules in node_modules folder
plugins: [
//tells webpack where to store data about your bundles.
new BundleTracker({filename: './webpack-stats.json'}),
//makes jQuery available in every module
new webpack.ProvidePlugin({
//React: "react",
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
],
module: {
loaders: [
//a regexp that tells webpack use the following loaders on all
//.js and .jsx files
{test: /\.jsx?$/,
//we definitely don't want babel to transpile all the files in
//node_modules. That would take a long time.
/*exclude: /node_modules/,*/
//use the babel loader
loader: 'babel-loader',
query: {
//specify that we will be dealing with React code
presets: ['react']
}
}
]
},
resolve: {
//tells webpack where to look for modules
modulesDirectories: ['node_modules'],
//extensions that should be used to resolve modules
extensions: ['', '.js', '.jsx']
}
}
And assets/bundles/index.js
var React = require('react')
var ReactDOM = require('react-dom')
//snaha//
var BooksList = React.createClass({
loadBooksFromServer: function(){
console.log(123454657);
$.ajax({
url: this.props.url,
datatype: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this)
})
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadBooksFromServer();
setInterval(this.loadBooksFromServer,
this.props.pollInterval)
},
render: function() {
if (this.state.data) {
console.log('DATA!')
var bookNodes = this.state.data.map(function(book){
return <li> {book.title} </li>
})
}
return (
<div>
<h1>Hello React!</h1>
<ul>
{bookNodes}
</ul>
</div>
)
}
})
ReactDOM.render(<BooksList url='/api/' pollInterval={1000} />,
document.getElementById('container'))
And templates/body.html
{% load render_bundle from webpack_loader %}
<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<meta charset="UTF-8">
<title>Hello React
{% block content %}
{{ id }}
{% endblock %}
</title>
</head>
<body>
<div id="container"></div>
{% render_bundle 'main' %}
</body>
</html>
Anything I'm missing? here is my Django project structure
Finally I've solved it!
Problem was : it was trying to get variable react where as React.js on browser was providing variable React!
So I simple change of externals of webpack.config.js to
externals: {
React: 'react'
},
solved the issue!
Next Problem Faced :
"process was not defined"
Solution : added
var env = process.env.WEBPACK_ENV;
to top of webpack.config.js
and
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': '"production"'
}
})
into the plugins part of model.export
So Final webpack.config.js would be :
var path = require('path');
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var nodeExternals = require('webpack-node-externals');
var env = process.env.WEBPACK_ENV;
module.exports = {
//the base directory (absolute path) for resolving the entry option
context: __dirname,
//the entry point we created earlier. Note that './' means
//your current directory. You don't have to specify the extension now,
//because you will specify extensions later in the `resolve` section
entry: './assets/js/index',
output: {
//where you want your compiled bundle to be stored
path: path.resolve('./assets/bundles/'),
//naming convention webpack should use for your files
filename: '[name]-[hash].js',
},
target: 'node', // in order to ignore built-in modules like path, fs, etc.
externals: {
React: 'react'
}, // in order to ignore all modules in node_modules folder
plugins: [
//tells webpack where to store data about your bundles.
new BundleTracker({filename: './webpack-stats.json'}),
//makes jQuery available in every module
new webpack.ProvidePlugin({
//React: "react",
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': '"production"'
}
})
],
module: {
loaders: [
//a regexp that tells webpack use the following loaders on all
//.js and .jsx files
{test: /\.jsx?$/,
//we definitely don't want babel to transpile all the files in
//node_modules. That would take a long time.
/*exclude: /node_modules/,*/
//use the babel loader
loader: 'babel-loader',
query: {
//specify that we will be dealing with React code
presets: ['react']
}
}
]
},
resolve: {
//tells webpack where to look for modules
modulesDirectories: ['node_modules'],
//extensions that should be used to resolve modules
extensions: ['', '.js', '.jsx']
}
}
Now Enjoy React! Happy Coding :-)
Can you look if you have all the requirements installed.
Look inside package.json. You should have react noted in requirements if you do run.
npm install
If you don't, then run
npm install react --save
ps: in my option if you are running Webpack try to add babel to Webpack presets and write javascript in ES2015 specification.