I encountered an issue while using code splitting and the CommonsChunkPlugin. My previous experience with require.js
involved files being automatically cached. Additionally, I have configured my webpack with libraryTarget: 'amd'
.
When looking at these two simple files, here is the resulting output:
// fileA.js
import $ from 'jquery'
// fileB.js
import $ from 'jquery'
Asset Size Chunks Chunk Names
fileB.js 271 kB 0 [emitted] [big] fileB
fileA.js 271 kB 1 [emitted] [big] fileA
Both files, fileA
and fileB
, contain jquery
. I am able to include these files in my html
like this:
require(['./dist/fileA.js', './dist/fileB.js'], function () {
})
The documentation suggests using the CommonsChunkPlugin
to extract jquery into its own file. So, my configuration now looks like this:
new webpack.optimize.CommonsChunkPlugin({
name: 'common'
}),
This results in the following output:
Asset Size Chunks Chunk Names
fileB.js 635 bytes 0 [emitted] fileB
fileA.js 617 bytes 1 [emitted] fileA
common.js 274 kB 2 [emitted] [big] common
However, now I am unable to use the above require
block because the common.js
also includes the webpack runtime. This leads to an error saying
Uncaught ReferenceError: webpackJsonp is not defined
.
To resolve this, I require the following setup:
- fileA.js (contains "fileA" code, requiring jquery)
- fileB.js (contains "fileB" code, requiring jquery)
- jquery.js (contains all jquery functionality)
- common.js (only contains webpack runtime)
I attempted something similar for fileA
and fileB
, but it resulted in the same output:
define(['jquery'], function ($) {
})
A vendor library should only be loaded if a script (like fileA
) is loaded and has it as a dependency (as required in requirejs).
Is there a way to achieve this? I've checked the webpack2 docs multiple times but couldn't find anything helpful...
Edit: With guidance from various GitHub issues, I was able to correct the asset generation with the following configuration:
module.exports = {
entry: {
jquery: ['jquery'],
vue: ['vue'],
fileA: ['./src/fileA.js'],
fileB: ['./src/fileB.js'],
fileC: ['./src/fileC.js']
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist',
filename: '[name].js',
libraryTarget: 'amd'
}
}
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.optimize.CommonsChunkPlugin({
name: ['vue', 'jquery']
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
chunks: ['vue', 'jquery'],
minChunks: Infinity
}),
new webpack.optimize.OccurrenceOrderPlugin()
])
I updated the source files to include:
// fileA.js
import $ from 'jquery'
import Vue from 'vue'
// fileB.js
import $ from 'jquery'
// fileC.js
import Vue from 'vue'
Here is the updated output:
vue.js 193 kB 0 [emitted] vue
fileC.js 447 bytes 1 [emitted] fileC
fileB.js 579 bytes 2 [emitted] fileB
fileA.js 666 bytes 3 [emitted] fileA
jquery.js 269 kB 4 [emitted] [big] jquery
common.js 5.78 kB 5 [emitted] common
Despite this, attempting to use it in an .html
file leads to the following error:
<body>
<script src="./dist/common.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.3/require.js"></script>
<script>
require(['./dist/fileA.js', './dist/fileB.js', './dist/fileC.js'], function (a, b, c) {
})
</script>
</body>
This error occurs both for fileA
and fileC
...
common.js:55 Uncaught TypeError: Cannot read property 'call' of undefined
at __webpack_require__ (common.js:55)
at Object.7 (fileA.js:16)
at __webpack_require__ (common.js:55)
at Object.6 (fileA.js:6)
at __webpack_require__ (common.js:55)
at webpackJsonpCallback (common.js:26)
at fileA.js:1
at Object.execCb (require.js:1696)
at Module.check (require.js:883)
at Module.enable (require.js:1176)
Edit:
I have created a repository on GitHub showcasing the issue I encountered. Following Rafael De Leon's suggestion, I now utilize System.import('<module>')
to asynchronously import other files. The error seems to occur when output.js
(the compiled main.ts
file) requires fileA.ts
using this syntax. I have also raised a concern in a GitHub issue as I suspect it may be a bug.