I'm trying to figure out why an app (Vuejs3, webpack 5, Babel 7) behaves differently in production than in development mode. For some reason, in production mode, the imports and exports are working differently (i.e. files aren't imported at all, i.e. their code isn't run during import).
This is the structure which works in development mode:
+- foo/
| +-- index.js
|
| export {default as Component} from './comp';
| export {default as SomethingElse} from './comp2';
|
| +-- comp.vue
|
| alert('hey there!');
| export default {...component here...}
|
+- main.js
import './foo';
This works all fine in development mode, but not at all in production. I seems as if the code in comp.vue is never being executed and thus the component isn't imported/registered. I tried to use re-exporting/aggregation in index.js instead, but that didn't change anything.
If I change main.js to import {Component} from './foo' then everything works fine. However the import 'file' pattern is used so often that I would struggle to change it (and it works in development mode).
Another way to make this work is to set the source map to eval-cheap-source-map (instead of source-map) in production which is the same source map method used as in development. Conversely, if I change source map to source-map in development mode, the component is successfully loaded.
Which leads me to the conclusion that webpack is somehow handling export/import different in production that in develop (the source-map observation is just an observation, but worth noting). I'm a bit puzzled as to why this happens, so would like to appreciate any experience that you can share.
Note
This may be an issue with some of the production mode optimisation steps. Is there any way to disable them (all of them to see whether this is the general issue and then disable/re-enable parts of them to find the "culprit"?)
After many unsuccessful attempts to fix this in the webpack configuration, I arrived at this configuration:
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin({
terserOptions: {
compress: {
unused: false
}
}
})
]
},
unused(default: true) -- drop unreferenced functions and variables (simple direct variable assignments do not count as references unless set to "keep_assign")
This seems to avoid side effect code from being culled when using re-exports. I'm yet to find out why the code was deemed side effect free though (which is not the default as far as I can tell).