webpack: Webpack 4 doesn't support sharing modules from entries
Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Webpack 4.5 cannot be configured to create JavaScript files that both: a) bundle shared modules and b) runs them.
If the current behavior is a bug, please provide the steps to reproduce.
The following markup shows the use case of a large app that has pages that assumes a babel-polyfilled environment and may depend on either React or jQuery or both. A page often has a corresponding Webpack entry that shouldn’t redundantly bundle babel-polyfill, React, jQuery, or the Webpack runtime.
<html>
<body>
<!-- Download and run babel-polyfill, fetch polyfill modules, and webpack runtime. -->
<script src="environment.js"></script>
<!-- An ES6 environment should polyfilled -->
<script>console.assert('Map exists.', typeof Map === 'function');</script>
<script>console.assert('Set exists.', typeof Set === 'function');</script>
<!-- Download react, react-dom -->
<script src="vendor-react.js"></script>
<!-- Download and run jquery, and a module that sets it on window -->
<script src="vendor-jquery.js"></script>
<script>console.assert('jQuery exists.', typeof jQuery === 'function');</script>
<!-- Download and run page-specific code that may import react or jquery
without bundling react or jquery in page-a.js -->
<script src="page-a.js"></script>
</body>
</html>
What is the expected behavior?
Webpack 3 and it’s CommonsChunkPlugin supported this feature.
Please mention other relevant information such as the browser version, Node.js version, webpack version, and Operating System.
Webpack 4.5, Node 8.2, OS X 10.12.6.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 19
- Comments: 39 (9 by maintainers)
Commits related to this issue
- Demonstrate Webpack 4 shared entry bug To see the problem: 1. Clone this git repository 2. Run `yarn` to install dependencies. 3. Run `yarn build` to build assets with Webpack. 4. View index.html in... — committed to deleteme/webpack-4-issue-6977-module-sharing-from-entries by deleteme 6 years ago
- Demonstrate Webpack 4 shared entry bug To see the problem: 1. Clone this git repository 2. Run `yarn` to install dependencies. 3. Run `yarn build` to build assets with Webpack. 4. View index.html in... — committed to deleteme/webpack-4-issue-6977-module-sharing-from-entries by deleteme 6 years ago
- Demonstrate Webpack 4 shared entry bug To see the problem: 1. Clone this git repository 2. Run `yarn` to install dependencies. 3. Run `yarn build` to build assets with Webpack. 4. View index.html in... — committed to deleteme/webpack-4-issue-6977-module-sharing-from-entries by deleteme 6 years ago
To expand on my last comment, by the way, there’s a slightly undocumented syntax for
optimization.runtimeChunk
: You can actually set it toto have Webpack inject the runtime into that chunk; this interoperates with
optimization.cacheGroups.***.name
, so if you have a shared chunk of dependencies that you swear every page of yours will load, you can use the above configuration to have Webpack inject the runtime there, to avoid the extra runtime-only chunk.If I understand your problem correctly, you are trying to load multiple entry points on a single page. This should work if you create one
runtimeChunk
for all entry points.This creates a “runtime.js”, which you need to load as first script on the page. After that, you can load multiple entry points on your page.
This is actually blocking update to webpack 4 for us. Some background: we have a pretty large app (4500+ modules, ~400 entry points). App is a mix of legacy and modern, webpack-built JS code. Every page could be a mix of legacy and modern widgets. For this cases, we create a separate webpack entry point for every modern-inside-legacy widget. Some global initialization is then put into another
init.js
entry point:This
init.js
is executed before widget entry points. Widgets expect'some-internal-library'
to be configured. This worked us for every webpack version since0.x
. On webpack 4 it broke, because it seems like every widget entry point now re-executessome-internal-module
on the first import andconfigure
call ininit.js
does not affect the rest.Is there something we can do to make it work?
@TheLarkInn When you say “available for other bundles not created from the same compilation?”
Does that apply to this line in the original description?
If so, do you think that this use case is unreasonable or unrealistic?
It seems to me that Webpack 4 assumes that it is responsible for the loading of all JavaScript on a site. While this may be true with code splits in a SPA, this is not always true for a site composed of html pages with script tags.
The hueristics system to determine what commons files to generate is a nice feature for SPA, but it is not practical for an html page app with script tags, where each script tag must be deliberately added.
I’m trying to avoid:
a~b~c.js
).I’m trying to preserve:
Is this something that Webpack 4 supports?
This is really a nightmare for me, I nearly spent around 30 hours to make it work somehow - and it’s still not working. I’m using rails webpacker and either the chunks are loaded multiple times or the JS code is not executing at all - even though I can see the “working” javascript include tags in the html. Until now webpack is absolutely killing my nerves & productivty 😦
Basically I would like to have 1 base js file (imports polyfill, jquery,…), and several other js entry files which are included if one of our subpages is opened (different react components, depending on which site is opened)).
This issue is more than a year old, and gets extremely frustrating for many devs trying to use a singleton-like module usage.
Webpack devs, is there not a solution in sight? As it is now, webpack 4 does not have an upgrade path for us.
You can set:
Which tells webpack to optimize dependencies from entries as well. By default
chunks
is set to async, so webpack won’t touch your entries.see https://webpack.js.org/plugins/split-chunks-plugin/#splitchunkschunks and https://webpack.js.org/guides/code-splitting
Any updates on this problem? This was something working smoothly in earlier version of webpack.
I have a vendor bundle, and my own commons module. With
libraryTarget: 'var'
I used to configure variables in my commons module (it has anoptions
variable within, which is exported for the modules importingcommon.js
).Before 4.0, using
CommonsChunkPlugin
I could import thecommon.js
module, then configure it from inlined code in my pages, and then use the options configured from the inline code in my modules. After 4.0, I can’t get it working. It seems as theoptions
within the samecommon.js
is two separate variables: one which is configured via thelibraryTarget
behavior from the inlined code, and another which is basically an the original state of the definedoptions
variable incommon.js
, imported by the underlying modules.Reading the new configuration docs so far with
SplitChunks
, I could not find ways as to how to keep the ‘one parent’-‘many children’ relation, so that my modules would see the same inline configuredcommon.js
option
variable everywhere.Am I missing something, or has this become completely unavailable with V4? Can someone enlighten me as to how I can achieve what was available with V3?
@sokra care to expand a bit on the different way?
It sounds like you are trying to synthetically make certain modules and things available for other bundles not created from the same compilation?
@paquette Using https://webpack.js.org/plugins/split-chunks-plugin
You are the true god of webpack!
@sokra can you please help us out here?
I’m also struggling with this. I have 3 entrypoints -
preload
,polyfill
, andapplication
.preload
is responsible for checking the browser supports promises, loading thepolyfill
entrypoint if not, and then loading theapplication
entrypoint. It loads these via regular old document.createElement(“script”) so that it’s not reliant on webpack’s promise-based chunk loader. I disable code splitting inpreload
&polyfill
for the same reason.This bit works fine, and webpack’s runtime chunk is successfully only inserted into preload.js. However any dependencies loaded in both preload & application get duplicated - once in the
preload
entrypoint, and once inapplication
’s split modules. How can I persuade webpack that any modules referenced in the runtimeChunk entrypoint don’t need to be duplicated?@sergei-startsev thanks I’ll look into those next if this doesn’t work, it seems that it might work though:
This is creating a base.js of node_modules, and later if I want to add other local shared resources I can modify
chunks
or maybecacheGroups
(not sure which)@deleteme Vendor files are not entry points… forget about the CommonsChunkPlugin in webpack 4.
This is also supported in webpack 4 but in a different way