webpack: Library Modules undefined when using splitChunks

Bug report

What is the current behavior?

Without splitChunks enabled entries have module objects in library as expected, but when splitChunks is enabled all keys in the library object are undefined.

If the current behavior is a bug, please provide the steps to reproduce.

Attached repository has both the broken state (master branch) and the working state (working branch). The only difference between the two branches is the addition of the optimization object in webpack.common.js.

https://github.com/rpg-verodin/splitchunks_issue_demo

To set up the repo:

The application I work on at my job has a multi-page architecture. Most Webpack entries have a variety of vendor bundles (including React, lodash, moment, etc), and they are all repeated over and over across the product.

In our product I had a branch from about 6 months ago where splitChunks was working as configured, but it never made it into our mainline codebase. When I tried to pull it in recently I came across this issue.

Both the working and broken builds include the following identical chunk of code that includes the simplification of a JSX component that should be available at components.tester.Tester, but in the broken build components.tester is undefined:

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Tester\", function() { return Tester; });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n\nvar Tester = function Tester() {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h1\", null, \"This is a test\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"p\", null, \"This is only a test.\"));\n};\n\n//# sourceURL=webpack://components.%5Bname%5D/./components/Tester.js?");

What is the expected behavior?

When splitChunks is enabled the modules in the library object should not be undefined, but should contain exports the same as when splitChunks is not enabled.

Other relevant information: webpack version: 4.43.0 Node.js version: v14.1.0 (same issue occurs with 10.17.0 in our production environment) Operating System: Mac OS 10.15.5 and Centos 7 Additional tools: Not sure what this is asking for, but the repo has a package.json, .bashrc and webpack config with all the info about the conditions that result in this.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 16 (8 by maintainers)

Most upvoted comments

@evilebottnawi and anyone else –

Mine might be a separate issue or a different manner of oversight, but I thought I’d ask anyway:

In my case, I’m using webpack to create a library module and wanted to chunk out the vendor portion of it. I’m not using <script/> includes – my webpack output is being consumed via ES import.

It works fine as a single bundle, but as soon as I introduce the splitChunks: { chunks: "all" } optimization, my module import comes back as undefined.

Any immediate thoughts as to why that might be? If not, I’ll consider creating a separate issue…

This is probably a bit of a hack, but I think I’ve more or less managed to accomplish what I wanted by including the vendor bundle as an entry and excluding it from bundling by defining it in externals. Feels dirty, but it seems to work as intended:

entry: {
	"guid-generator": [
		"dist/vendor/index.js",
		"../lib/guid-generator/src/index.ts"
	]
},
externals: {
	"dist/vendor/index.js": "dist/vendor/index.js"
}

Don’t split library, you will potentially lose tree shaking and many other optimizations

Yeah, I realize that doing it this way isn’t ideal. But, I’m working in a legacy application with sprawling front-end code that just isn’t in a state where I could easily begin bundling the site code directly.

My goal at the moment is to avoid pulling in the entirety of vendor scripts (what I’m doing currently), and instead author libraries that consume vendor scripts and expose a vendor-agnostic interface for the application to use. When bundled with webpack, tree shaking should strip away the parts of the vendor scripts that aren’t used by the library, correct?

In the guid-generator project, for example – the vendor chunk generated by webpack includes v4 from the uuid node module, since it is used by the library, but excludes v1, v2, v3, etc.

To your point, though, this method leaves me with no way of excluding (tree shaking) the parts of my library that aren’t used by the app. I’m fine with that compromise, for now, given the limitations of the legacy code I’m working in, and the fact that the libraries will already be tailored for use in my product and shouldn’t contain much code that isn’t used by my applications, anyway.

Sorry for delay, look at this tomorrow

@cymptom Can you create reproducible test repo, I think we fixed it in master, want to check

I’ll do that and get back to you. Thanks 😃

@evilebottnawi That would certainly do it. Sorry for my stupid mistake. Thanks a lot for the help; I appreciate it.