I have a project that makes use of a large bundle (dexie.js not that it's important to this question), that I'd like to 'split out' into it's own bundle that I can include manually, because it's only needed in a few of my entry point scripts.
Just so that you know: my webpack config uses multiple modules, with multiple (6) entry points, so this is a cut-down sample of my webpack.config.js
:
{
context: path.join(__dirname, 'src'),
entry: {
'js/contentscript.js' : './js/contentscript.js',
'js/background.js' : './js/background.js',
'js/popup.js' : './js/popup.js',
'js/options.js' : './js/options.js',
},
output: {
path: path.join(__dirname, 'dist'),
filename: "[name]"
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "dexie",
filename: "js/dexie.js",
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.includes("node_modules/dexie");
}
}),
... // other non relevant plugins here
]
}
The problem is that I have no typical 'vendor' nor 'common' requirement, like many other projects to. It's only in a few cases that I want to include the js/dexie.js
bundle.
eg. in options.html
, I have this:
<script src="js/dexie.js"></script>
<script src="js/options.js"></script>
...but I do not want it to be used for popup.html
, which I want to keep as this:
<script src="js/popup.js"></script>
And since this is also a WebExtensions project, I definitely don't want my content scripts to need it!
The problem is, that when I open popup.js, I get the error: Uncaught ReferenceError: webpackJsonp is not defined
.
Is there any way -- without splitting this into more webpack modules -- so that the CommonsChunkPlugin
will play nice with the entry points so that only the ones I want are affected by it?
The only solution I can think of, is to make another CommonsChunkPlugin
that acts in the way that 'vendor' and 'common' is typically used. That is:
new webpack.optimize.CommonsChunkPlugin({
name: "dexie",
filename: "js/dexie.js",
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.includes("node_modules/dexie");
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: "manifest",
filename: "js/manifest.js",
minChunks: Infinity
}),
Unfortunately, this means I need to include js/manifest.js
in all my scripts, and since this is a WebExtension, then that means I have to inject it into each content page...IMHO this is a terrible solution.
Any ideas on how to improve this? Am I using CommonsChunkPlugin
incorrectly? Is there a better module I should be using? (I'm actually still coming to grips with webpack!)
I stumbled across this excellent answer by @prograhammer: https://stackoverflow.com/a/40416826/125525
In it he made reference to the Externals plugin, which I'd not heard of before, and it neatly solves my problems. This is the description from the webpack site:
For example, to include jQuery from a CDN instead of bundling it:
index.html
<script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous"> </script>
webpack.config.js
externals: { jquery: 'jQuery' }
This leaves any dependent modules unchanged, i.e. the code shown below will still work:
import $ from 'jquery'; $('.my-element').animate(...);