I have a simple node project where I use webpack-stream (via Gulp) to bundle multiple JS files into one output file. The webpack must concatenate the files in such a way that it looks as if you wrote all the code in one file.
For example, the runtime of the output file expects a startTest()
function to be declared globally.
For this reason I have disabled certain optimizations that would encapsulate or otherwise minify the output code.
Consider the following simplified code of my project:
main.js:
import VoiceGender from "./models/VoiceGender";
console.log(VoiceGender.MALE);
function startTest() {
console.log(VoiceGender.MALE);
}
VoiceGender.js:
const VoiceGender = {
MALE: 'M',
FEMALE: 'F'
}
export default VoiceGender;
The webpack configuration:
{
"mode":"production",
"output":{
"iife":false,
"filename":"bundle.js"
},
"optimization":{
"minimize":false,
"usedExports":false,
"mangleExports":false
},
"cache":{
"type":"filesystem"
}
}
bundle.js (webpack output):
/******/ "use strict";
/******/ // The require scope
/******/ var __webpack_require__ = {};
/******/
/************************************************************************/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
;// CONCATENATED MODULE: ./src/models/VoiceGender.js
const VoiceGender_VoiceGender = {
MALE: "M",
FEMALE: "F"
};
/* harmony default export */ const models_VoiceGender = (VoiceGender_VoiceGender);
;// CONCATENATED MODULE: ./src/main.js
console.log(models_VoiceGender.MALE);
function startTest() {
console.log(VoiceGender.MALE);
}
Notice that the console.log(..)
above the startTest()
function uses the generated name by Webpack (which is fine), but inside the startTest()
function it does not use that reference. This is the wrong reference because Webpack declared the module under models_VoiceGender
and VoiceGender_VoiceGender
instead of VoiceGender
.
I have no idea what could be causing this. Maybe a bug? I tried playing around with certain properties but I don't see any change.
webpack-stream version: ^7.0.0
gulp version: ^4.0.2
webpack version (via webpack-stream): ^5.21.2
UPDATE:
When adding export
to the startTest()
function, the reference is fixed. Alternatively, calling startTest()
inside that script would also fix the reference. I have configured webpack to not exclude "unused" code, but it seems it does not properly bundle the unused code.
I've let this sit for a little bit to see if more people could weigh in on this, but I'm thinking that this is really more of a bug or a side effect of webpack and I should report it there.
Basically, webpack is configured to keep unused code. Even though the runtime will call the startTest()
function, webpack doesn't know that so for webpack this is unused code.
For some reason, webpack doesn't do the "effort" to use the correct module names in "unused" code. I assume this is a bug.
A workaround is to make the code appear used by:
export
to the functionSo in the end, the workarounds are fine and perhaps they are semantically correct.