Say there is a module on npm called "awesomepackage". I can register it as a dependency of my application via package.json
like so:
npm i --save awesomepackage
Inspecting my node_modules
folder I see a folder named "awesomepackage" which looks like this:
- index.js
- package.json
- README.md
- lib/
- awesomepackage.min.js
and I can use the package inside my own application like so:
import {AwesomeThing} from 'awesomepackage';
My question:
When I build my application using webpack my final bundle.js
always contains the source code from node_modules/awesomepackage/index.js
- regardless of any environment variables I have setup (eg NODE_ENV=production
).
Is there any way to tell webpack to use the pre-built files (eg node_modules/awesomepackage/lib/awesomepackage.min.js
) if they are shipped as part of an NPM package, instead of re-building from the source?
I have seen solutions that use resolve.alias
and noParse
in the webpack config with hardcoded paths to minified source files, but doesn't that mostly defeat the purpose of using npm and webpack? I don't want to have to hard-code and maintain paths to every dependency's minified build files!
I got here because my bundle.js
jumped 2.5mb when I added moment.js
- which is 167kb minified, including all locales, but of which the source code includes 2mb of tests.
Edit
Clearly there is more to it than just minifying the final bundle.js
file at the end. For example: why would anybody want to include hundreds of unnecessary unit tests for dependencies in final production code? They don't. Which is why most libraries provide a dist
(or similar) folder as part of their npm module.
Why not just minify the entire webpack
bundle.js
? (source)Probably easier than trying to find some way to use the minified version of individual packages.
Let's consider your moment package.
You can always use
But it's not a good idea.
You shouldn't use minified files in webpack
If you use
it will build module from source. But if you have minification process in webpack config file it shouldn't be much bigger than shipped
.min.js
files. Often your own build can be even smaller than original.min.js
!Experiment for moment
I measure additional size of my
bundle.js
after addingmoment
and its 190 kB and originalmoment/min/moment-with-locales.min.js
size is 207 kB. Your 2.5 MB is probably that you add maps (in my configuration with mapsmoment
weights 2.7 MB) You can analyze that it is build with all locales - webpack can print this statistics (sizes are before minification):So why your custom build is smaller? You can use more aggressive minification. My build give me this information (probably it loose some weight at this point):
Reusing common modules
Moment
isn't the best module for highlight the most powerful feature of webpack - reusing common modules (sincemoment
doesn't use dependencies).Lest's consider that your application use 3 modules and each of them have some dependencies.
If you will only use
.min
version of this 3 modules you will add 50 kB + 25 kB + 45 kB = 120 kB to your application.On the other hand if you will build with source files, common modules will be added only once. Not like previously
moduleA
was included 3 times andmoduleC
2 times. This times to your app will be added:And finally with this approach you add 95 kB to your application.