为生产构建webpack - 缩小依赖关系 [英] Building webpack for production - minified dependencies

查看:83
本文介绍了为生产构建webpack - 缩小依赖关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设npm上有一个名为awesomepackage的模块。我可以通过 package.json 将其注册为我的应用程序的依赖项,如下所示:

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

检查我的 node_modules 文件夹我看到一个名为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';



我的问题:



当我建立我的应用程序使用webpack我的最终 bundle.js 总是包含来自 node_modules / awesomepackage / index.js 的源代码 - 无论如何我设置的任何环境变量(例如 NODE_ENV = production )。

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).

有没有办法告诉webpack使用预构建的文件(例如 node_modules / awesomepackage / lib / awesomepackage.min.js )如果它们作为NPM包的一部分提供,而不是从来源?

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?

我见过解决方案 使用 <$ cpack c> resolve.alias 和 noParse 在webpack配置中使用硬编码的路径来缩小源文件,但这并不能破坏pu使用npm和webpack?我不想硬编码和维护每个依赖项的缩小构建文件的路径!

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!

我来到这里是因为我的 bundle.js当我添加 moment.js 跳了2.5mb c $ c> - 缩小了167kb,包括所有语言环境,但源代码包含2mb的测试。

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.

显然,除了最后缩小最终的 bundle.js 文件之外,还有更多内容。例如:为什么有人想要在最终生产代码中包含数百个不必要的单元测试依赖项?他们没有。这就是为什么大多数库提供 dist (或类似)文件夹作为其npm模块的一部分。

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.

推荐答案

让我们考虑你的时刻套餐。

Let's consider your moment package.

你可以随时使用

import moment from 'node_modules/moment/min/moment-with-locales.min.js'

但这不是一个好主意。

如果您使用

import moment from 'moment';

它将从源代码构建模块。但是如果你在webpack配置文件中有缩小过程,它应该比装运 .min.js 文件大得多。通常你自己的版本可能比原版 .min.js 更小!

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!

我在添加<$ c $后测量我的 bundle.js 的额外大小c>时刻及其 190 kB 和原始时刻/分钟/时刻与locales.min.js 尺寸是 207 kB 。您的 2.5 MB 可能是您添加地图(在我的配置中使用地图时刻权重 2.7 MB )您可以分析它是使用所有语言环境构建的 - webpack可以打印此统计信息(大小在缩小之前) :

I measure additional size of my bundle.js after adding moment and its 190 kB and original moment/min/moment-with-locales.min.js size is 207 kB. Your 2.5 MB is probably that you add maps (in my configuration with maps moment weights 2.7 MB) You can analyze that it is build with all locales - webpack can print this statistics (sizes are before minification):

 [373] ./~/moment/moment.js 135 kB {0} [built]
 [374] ./~/moment/locale/af.js 2.62 kB {0} [optional] [built]
 [375] ./~/moment/locale/ar-ma.js 2.12 kB {0} [optional] [built]
 [376] ./~/moment/locale/ar-sa.js 3.16 kB {0} [optional] [built]
 [377] ./~/moment/locale/ar-tn.js 1.97 kB {0} [optional] [built]
 [378] ./~/moment/locale/ar.js 4.59 kB {0} [optional] [built]
 [379] ./~/moment/locale/az.js 3.35 kB {0} [optional] [built]
 [380] ./~/moment/locale/be.js 4.86 kB {0} [optional] [built]
 [381] ./~/moment/locale/bg.js 3.1 kB {0} [optional] [built]
 [382] ./~/moment/locale/bn.js 3.62 kB {0} [optional] [built]
 [383] ./~/moment/locale/bo.js 3.87 kB {0} [optional] [built]
 [384] ./~/moment/locale/br.js 3.44 kB {0} [optional] [built]
 [385] ./~/moment/locale/bs.js 4.7 kB {0} [optional] [built]
 [386] ./~/moment/locale/ca.js 2.97 kB {0} [optional] [built]
 [387] ./~/moment/locale/cs.js 6.4 kB {0} [optional] [built]
 [388] ./~/moment/locale/cv.js 2.33 kB {0} [optional] [built]
 [389] ./~/moment/locale/cy.js 2.92 kB {0} [optional] [built]
 [390] ./~/moment/locale/da.js 2.07 kB {0} [optional] [built]
 [391] ./~/moment/locale/de-at.js 3.03 kB {0} [optional] [built]
 [392] ./~/moment/locale/de.js 2.95 kB {0} [optional] [built]
 [393] ./~/moment/locale/dv.js 2.69 kB {0} [optional] [built]
 [394] ./~/moment/locale/el.js 3.73 kB {0} [optional] [built]
 [395] ./~/moment/locale/en-au.js 2.32 kB {0} [optional] [built]
 [396] ./~/moment/locale/en-ca.js 2.2 kB {0} [optional] [built]
 [397] ./~/moment/locale/en-gb.js 2.38 kB {0} [optional] [built]
 [398] ./~/moment/locale/en-ie.js 2.37 kB {0} [optional] [built]
 [399] ./~/moment/locale/en-nz.js 2.32 kB {0} [optional] [built]
 [400] ./~/moment/locale/eo.js 2.67 kB {0} [optional] [built]
 [401] ./~/moment/locale/es.js 2.97 kB {0} [optional] [built]
 [402] ./~/moment/locale/et.js 3.14 kB {0} [optional] [built]
 [403] ./~/moment/locale/eu.js 2.39 kB {0} [optional] [built]
 [404] ./~/moment/locale/fa.js 3.27 kB {0} [optional] [built]
 [405] ./~/moment/locale/fi.js 3.86 kB {0} [optional] [built]
 [406] ./~/moment/locale/fo.js 2.1 kB {0} [optional] [built]
 [407] ./~/moment/locale/fr-ca.js 2.09 kB {0} [optional] [built]
 [408] ./~/moment/locale/fr-ch.js 2.25 kB {0} [optional] [built]
 [409] ./~/moment/locale/fr.js 2.24 kB {0} [optional] [built]
 [410] ./~/moment/locale/fy.js 2.64 kB {0} [optional] [built]
 [411] ./~/moment/locale/gd.js 2.63 kB {0} [optional] [built]
 [412] ./~/moment/locale/gl.js 2.77 kB {0} [optional] [built]
 [413] ./~/moment/locale/he.js 3.41 kB {0} [optional] [built]
 [414] ./~/moment/locale/hi.js 3.88 kB {0} [optional] [built]
 [415] ./~/moment/locale/hr.js 4.83 kB {0} [optional] [built]
 [416] ./~/moment/locale/hu.js 4 kB {0} [optional] [built]
 [417] ./~/moment/locale/hy-am.js 3.22 kB {0} [optional] [built]
 [418] ./~/moment/locale/id.js 2.94 kB {0} [optional] [built]
 [419] ./~/moment/locale/is.js 4.43 kB {0} [optional] [built]
 [420] ./~/moment/locale/it.js 2.46 kB {0} [optional] [built]
 [421] ./~/moment/locale/ja.js 2.21 kB {0} [optional] [built]
 [422] ./~/moment/locale/jv.js 2.94 kB {0} [optional] [built]
 [423] ./~/moment/locale/ka.js 3.15 kB {0} [optional] [built]
 [424] ./~/moment/locale/kk.js 2.68 kB {0} [optional] [built]
 [425] ./~/moment/locale/km.js 2.02 kB {0} [optional] [built]
 [426] ./~/moment/locale/ko.js 2 kB {0} [optional] [built]
 [427] ./~/moment/locale/ky.js 2.69 kB {0} [optional] [built]
 [428] ./~/moment/locale/lb.js 4.92 kB {0} [optional] [built]
 [429] ./~/moment/locale/lo.js 2.32 kB {0} [optional] [built]
 [430] ./~/moment/locale/lt.js 4.37 kB {0} [optional] [built]
 [431] ./~/moment/locale/lv.js 3.9 kB {0} [optional] [built]
 [432] ./~/moment/locale/me.js 4.1 kB {0} [optional] [built]
 [433] ./~/moment/locale/mk.js 3.11 kB {0} [optional] [built]
 [434] ./~/moment/locale/ml.js 2.81 kB {0} [optional] [built]
 [435] ./~/moment/locale/mr.js 5.39 kB {0} [optional] [built]
 [436] ./~/moment/locale/ms-my.js 2.86 kB {0} [optional] [built]
 [437] ./~/moment/locale/ms.js 2.85 kB {0} [optional] [built]
 [438] ./~/moment/locale/my.js 2.73 kB {0} [optional] [built]
 [439] ./~/moment/locale/nb.js 2.23 kB {0} [optional] [built]
 [440] ./~/moment/locale/ne.js 3.81 kB {0} [optional] [built]
 [441] ./~/moment/locale/nl.js 2.63 kB {0} [optional] [built]
 [442] ./~/moment/locale/nn.js 2.09 kB {0} [optional] [built]
 [443] ./~/moment/locale/pa-in.js 4.01 kB {0} [optional] [built]
 [444] ./~/moment/locale/pl.js 3.94 kB {0} [optional] [built]
 [445] ./~/moment/locale/pt-br.js 2.23 kB {0} [optional] [built]
 [446] ./~/moment/locale/pt.js 2.34 kB {0} [optional] [built]
 [447] ./~/moment/locale/ro.js 2.61 kB {0} [optional] [built]
 [448] ./~/moment/locale/ru.js 7.08 kB {0} [optional] [built]
 [449] ./~/moment/locale/se.js 2.23 kB {0} [optional] [built]
 [450] ./~/moment/locale/si.js 2.43 kB {0} [optional] [built]
 [451] ./~/moment/locale/sk.js 5.49 kB {0} [optional] [built]
 [452] ./~/moment/locale/sl.js 6.16 kB {0} [optional] [built]
 [453] ./~/moment/locale/sq.js 2.45 kB {0} [optional] [built]
 [454] ./~/moment/locale/sr-cyrl.js 4.1 kB {0} [optional] [built]
 [455] ./~/moment/locale/sr.js 4.09 kB {0} [optional] [built]
 [456] ./~/moment/locale/ss.js 3.12 kB {0} [optional] [built]
 [457] ./~/moment/locale/sv.js 2.4 kB {0} [optional] [built]
 [458] ./~/moment/locale/sw.js 2.08 kB {0} [optional] [built]
 [459] ./~/moment/locale/ta.js 4.21 kB {0} [optional] [built]
 [460] ./~/moment/locale/te.js 3.09 kB {0} [optional] [built]
 [461] ./~/moment/locale/th.js 2.4 kB {0} [optional] [built]
 [462] ./~/moment/locale/tl-ph.js 2.14 kB {0} [optional] [built]
 [463] ./~/moment/locale/tlh.js 4.09 kB {0} [optional] [built]
 [464] ./~/moment/locale/tr.js 2.9 kB {0} [optional] [built]
 [465] ./~/moment/locale/tzl.js 3.59 kB {0} [optional] [built]
 [466] ./~/moment/locale/tzm-latn.js 2.11 kB {0} [optional] [built]
 [467] ./~/moment/locale/tzm.js 2.06 kB {0} [optional] [built]
 [468] ./~/moment/locale/uk.js 5.4 kB {0} [optional] [built]
 [469] ./~/moment/locale/uz.js 2.03 kB {0} [optional] [built]
 [470] ./~/moment/locale/vi.js 2.71 kB {0} [optional] [built]
 [471] ./~/moment/locale/x-pseudo.js 2.5 kB {0} [optional] [built]
 [472] ./~/moment/locale/zh-cn.js 4.35 kB {0} [optional] [built]
 [473] ./~/moment/locale/zh-tw.js 3.12 kB {0} [optional] [built]
 [474] ./~/moment/locale ^\.\/.*$ 2.41 kB {0} [optional] [built]

那么为什么你的自定义版本更小?您可以使用更积极的缩小。我的构建给了我这个信息(可能它在这一点上减轻了一些重量):

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):

Condition always true [./~/moment/moment.js:8,0]
Condition always true [./~/moment/locale/af.js:6,0]
Condition always true [./~/moment/locale/ar-ma.js:7,0]
Condition always true [./~/moment/locale/ar-sa.js:6,0]
Condition always true [./~/moment/locale/ar-tn.js:5,0]
Condition always true [./~/moment/locale/ar.js:8,0]
Condition always true [./~/moment/locale/az.js:6,0]
Condition always true [./~/moment/locale/be.js:8,0]
Condition always true [./~/moment/locale/bg.js:6,0]
Condition always true [./~/moment/locale/bn.js:6,0]
Condition always true [./~/moment/locale/bo.js:6,0]
Condition always true [./~/moment/locale/br.js:6,0]
Condition always true [./~/moment/locale/bs.js:7,0]
Condition always true [./~/moment/locale/ca.js:6,0]
Condition always true [./~/moment/locale/cs.js:6,0]
Dropping unreachable code [./~/moment/locale/cs.js:31,0]
Dropping unreachable code [./~/moment/locale/cs.js:40,0]
Dropping unreachable code [./~/moment/locale/cs.js:49,0]
Dropping unreachable code [./~/moment/locale/cs.js:58,0]
Dropping unreachable code [./~/moment/locale/cs.js:67,0]
Condition always true [./~/moment/locale/cv.js:6,0]
Condition always true [./~/moment/locale/cy.js:6,0]
Condition always true [./~/moment/locale/da.js:6,0]
Condition always true [./~/moment/locale/de-at.js:9,0]
Condition always true [./~/moment/locale/de.js:8,0]
Condition always true [./~/moment/locale/dv.js:6,0]
Condition always true [./~/moment/locale/el.js:6,0]
Condition always true [./~/moment/locale/en-au.js:5,0]
Condition always true [./~/moment/locale/en-ca.js:6,0]
Condition always true [./~/moment/locale/en-gb.js:6,0]
Condition always true [./~/moment/locale/en-ie.js:6,0]
Condition always true [./~/moment/locale/en-nz.js:5,0]
Condition always true [./~/moment/locale/eo.js:8,0]
Condition always true [./~/moment/locale/es.js:6,0]
Condition always true [./~/moment/locale/et.js:7,0]
Condition always true [./~/moment/locale/eu.js:6,0]
Condition always true [./~/moment/locale/fa.js:6,0]
Condition always true [./~/moment/locale/fi.js:6,0]
Condition always true [./~/moment/locale/fo.js:6,0]
Condition always true [./~/moment/locale/fr-ca.js:6,0]
Condition always true [./~/moment/locale/fr-ch.js:6,0]
Condition always true [./~/moment/locale/fr.js:6,0]
Condition always true [./~/moment/locale/fy.js:6,0]
Condition always true [./~/moment/locale/gd.js:6,0]
Condition always true [./~/moment/locale/gl.js:6,0]
Condition always true [./~/moment/locale/he.js:8,0]
Condition always true [./~/moment/locale/hi.js:6,0]
Condition always true [./~/moment/locale/hr.js:6,0]
Condition always true [./~/moment/locale/hu.js:6,0]
Dropping unused variable suffix [./~/moment/locale/hu.js:16,0]
Condition always true [./~/moment/locale/hy-am.js:6,0]
Condition always true [./~/moment/locale/id.js:7,0]
Condition always true [./~/moment/locale/is.js:6,0]
Condition always true [./~/moment/locale/it.js:7,0]
Condition always true [./~/moment/locale/ja.js:6,0]
Condition always true [./~/moment/locale/jv.js:7,0]
Condition always true [./~/moment/locale/ka.js:6,0]
Condition always true [./~/moment/locale/kk.js:6,0]
Condition always true [./~/moment/locale/km.js:6,0]
Condition always true [./~/moment/locale/ko.js:10,0]
Condition always true [./~/moment/locale/ky.js:6,0]
Condition always true [./~/moment/locale/lb.js:6,0]
Condition always true [./~/moment/locale/lo.js:6,0]
Condition always true [./~/moment/locale/lt.js:6,0]
Condition always true [./~/moment/locale/lv.js:7,0]
Condition always true [./~/moment/locale/me.js:6,0]
Condition always true [./~/moment/locale/mk.js:6,0]
Condition always true [./~/moment/locale/ml.js:6,0]
Condition always true [./~/moment/locale/mr.js:7,0]
Condition always true [./~/moment/locale/ms-my.js:6,0]
Condition always true [./~/moment/locale/ms.js:6,0]
Condition always true [./~/moment/locale/my.js:6,0]
Condition always true [./~/moment/locale/nb.js:7,0]
Condition always true [./~/moment/locale/ne.js:6,0]
Condition always true [./~/moment/locale/nl.js:6,0]
Condition always true [./~/moment/locale/nn.js:6,0]
Condition always true [./~/moment/locale/pa-in.js:6,0]
Condition always true [./~/moment/locale/pl.js:6,0]
Condition always true [./~/moment/locale/pt-br.js:6,0]
Condition always true [./~/moment/locale/pt.js:6,0]
Condition always true [./~/moment/locale/ro.js:7,0]
Condition always true [./~/moment/locale/ru.js:8,0]
Condition always true [./~/moment/locale/se.js:6,0]
Condition always true [./~/moment/locale/si.js:6,0]
Condition always true [./~/moment/locale/sk.js:7,0]
Dropping unreachable code [./~/moment/locale/sk.js:32,0]
Dropping unreachable code [./~/moment/locale/sk.js:41,0]
Dropping unreachable code [./~/moment/locale/sk.js:50,0]
Dropping unreachable code [./~/moment/locale/sk.js:59,0]
Dropping unreachable code [./~/moment/locale/sk.js:68,0]
Condition always true [./~/moment/locale/sl.js:6,0]
Condition always true [./~/moment/locale/sq.js:8,0]
Condition always true [./~/moment/locale/sr-cyrl.js:6,0]
Condition always true [./~/moment/locale/sr.js:6,0]
Condition always true [./~/moment/locale/ss.js:6,0]
Condition always true [./~/moment/locale/sv.js:6,0]
Condition always true [./~/moment/locale/sw.js:6,0]
Condition always true [./~/moment/locale/ta.js:6,0]
Condition always true [./~/moment/locale/te.js:6,0]
Condition always true [./~/moment/locale/th.js:6,0]
Condition always true [./~/moment/locale/tl-ph.js:6,0]
Condition always true [./~/moment/locale/tlh.js:6,0]
Condition always true [./~/moment/locale/tr.js:7,0]
Condition always true [./~/moment/locale/tzl.js:6,0]
Condition always true [./~/moment/locale/tzm-latn.js:6,0]
Condition always true [./~/moment/locale/tzm.js:6,0]
Condition always true [./~/moment/locale/uk.js:7,0]
Condition always true [./~/moment/locale/uz.js:6,0]
Condition always true [./~/moment/locale/vi.js:6,0]
Condition always true [./~/moment/locale/x-pseudo.js:6,0]
Condition always true [./~/moment/locale/zh-cn.js:7,0]
Condition always true [./~/moment/locale/zh-tw.js:6,0]






重用通用模块



Moment 不是突出webpack最强大功能的最佳模块 - 重用通用模块(因为时刻不使用依赖项)。


Reusing common modules

Moment isn't the best module for highlight the most powerful feature of webpack - reusing common modules (since moment doesn't use dependencies).

要考虑您的应用程序使用3个模块,并且每个模块都有一些依赖项。

Lest's consider that your application use 3 modules and each of them have some dependencies.

                   size

module1            20 kB 
  dependencies
    - moduleA      10 kB 
    - moduleB      15 kB
    - moduleC      5  kB
module1.min        50 kB

module2            10 kB 
  dependencies
    - moduleA      10 kB 
    - moduleD      5  kB
module2.min        25 kB

module3            30 kB 
  dependencies
    - moduleA      10 kB 
    - moduleC      5  kB
module3.min        45 kB

如果你只使用 .min 这3个模块的版本你将为你的应用程序添加50 kB + 25 kB + 45 kB = 120 kB

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.

                   size

module1            20 kB 
  dependencies
    - moduleA      10 kB  
    - moduleB      15 kB 
    - moduleC      5  kB 
module1.min        50 kB  <-- this

module2            10 kB  
  dependencies
    - moduleA      10 kB 
    - moduleD      5  kB 
module2.min        25 kB  <-- this

module3            30 kB  
  dependencies
    - moduleA      10 kB 
    - moduleC      5  kB
module3.min        45 kB  <-- this

另一方面,如果您将使用源文件构建,则通用模块将仅添加一次。不像之前的 moduleA 包括3次而 moduleC 2次。
这个时间到你的应用程序将被添加:

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 and moduleC 2 times. This times to your app will be added:

                   size

module1            20 kB  <-- this
  dependencies
    - moduleA      10 kB  <-- this
    - moduleB      15 kB  <-- this
    - moduleC      5  kB  <-- this
module1.min        50 kB

module2            10 kB  <-- this
  dependencies
    - moduleA      10 kB 
    - moduleD      5  kB  <-- this
module2.min        25 kB

module3            30 kB  <-- this
  dependencies
    - moduleA      10 kB 
    - moduleC      5  kB
module3.min        45 kB

最后通过这种方法,您可以添加 95 kB 你的申请。

And finally with this approach you add 95 kB to your application.

这篇关于为生产构建webpack - 缩小依赖关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆