You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
其实不然,mode 只可以定义成 development 或 production ,而在项目中,我们不仅仅只有开发或生产环境,很多情况下需要配置不同的环境(例如测试环境),此时我们就需要手动配置其它环境变量(例如测试环境,就需要定义 process.env.NODE_ENV 为 'test' ),你可以采取以下方式:
module.exports={plugins: [// 优化 requirenewwebpack.ContextReplacementPlugin(/moment[\/\\]locale$/,/en|zh/),// 用于提升构建速度createHappyPlugin('happy-babel',[{loader: 'babel-loader',options: {presets: ['@babel/preset-env',"@babel/preset-react"],plugins: [['@babel/plugin-proposal-class-properties',{loose: true}]],// babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启cacheDirectory: true,// Save disk space when time isn't as importantcacheCompression: true,compact: true,}}])]}
常用 plugins:
html-webpack-plugin:生成 html 文件,并将包添加到 html 中
webpack-parallel-uglify-plugin:压缩 js(多进程并行处理压缩)
happypack:多线程loader,用于提升构建速度
hard-source-webpack-plugin:为模块提供中间缓存步骤,显著提高打包速度
webpack-merge:合并 webpack 配置
mini-css-extract-plugin:抽离 css
optimize-css-assets-webpack-plugin:压缩 css
add-asset-html-webpack-plugin:将 JavaScript 或 CSS 资产添加到 html-webpack-plugin 生成的 HTML 中
前言
对于入门选手来讲,webpack 配置项很多很重,如何快速配置一个可用于线上环境的 webpack 就是一件值得思考的事情。其实熟悉 webpack 之后会发现很简单,基础的配置可以分为以下几个方面:
entry
、output
、mode
、resolve
、module
、optimization
、plugin
、source map
、performance
等,本文就来重点分析下这些部分。一、配置入口 entry
1、单入口和多入口
将源文件加入到 webpack 构建流程,可以是单入口:
构建包名称
[name]
为main
;或多入口:
key:value
键值对的形式:[name]
,在这里为index
入口决定 webapck 从哪个模块开始生成依赖关系图(构建包),每一个入口文件都对应着一个依赖关系图。
2. 动态配置入口文件
动态打包所有子项目
当构建项目包含多个子项目时,每次增加一个子系统都需要将入口文件写入 webpack 配置文件中,其实我们让webpack 动态获取入口文件,例如:
则会将所有匹配
./project/**/index.js
的文件作为入口文件进行打包,如果你想要增加一个子项目,仅仅需要在project
创建一个子项目目录,并创建一个index.js
作为入口文件即可。这种方式比较适合入口文件不集中且较多的场景。
动态打包某一子项目
在构建多系统应用或组件库时,我们每次打包可能仅仅需要打包某一模块,此时,可以通过命令行的形式请求打印某一模块,例如:
在打包的时候解析命令行参数:
然后配置入口:
相当于:
当然,你可以传入其它参数,也可以应用于多个地方,例如
resolve.alias
中。二、配置出口 output
用于告知 webpack 如何构建编译后的文件,可以自定义输出文件的位置和名称:
在 webpack4 开发模式下,会默认启动
output.pathinfo
,它会输出一些额外的注释信息,对项目调试非常有用,尤其是使用 eval devtool 时。filename
:[name]
为 entry 配置的key
,除此之外,还可以是[id]
(内部块 id )、[hash]
、[contenthash]
等。1. 浏览器缓存与 hash 值
对于我们开发的每一个应用,浏览器都会对静态资源进行缓存,如果我们更新了静态资源,而没有更新静态资源名称(或路径),浏览器就可能因为缓存的问题获取不到更新的资源。在我们使用 webpack 进行打包的时候,webpack 提供了 hash 的概念,所以我们可以使用 hash 来打包。
在定义包名称(例如
chunkFilename
、filename
),我们一般会用到哈希值,不同的哈希值使用的场景不同:hash
build-specific, 哈希值对应每一次构建(
Compilation
),即每次编译都不同,即使文件内容都没有改变,并且所有的资源都共享这一个哈希值,此时,浏览器缓存就没有用了,可以用在开发环境,生产环境不适用。chunkhash
chunk-specific, 哈希值对应于 webpack 每个入口点,每个入口都有自己的哈希值。如果在某一入口文件创建的关系依赖图上存在文件内容发生了变化,那么相应入口文件的
chunkhash
才会发生变化,适用于生产环境contenthash
content-specific,根据包内容计算出的哈希值,只要包内容不变,
contenthash
就不变,适用于生产环境但我们会发现,有时内容没有变更,打包时
[contenthash]
反而变更了的问题,webpack 也允许哈希的切片。如果你写
[hash:8]
,那么它会获取哈希值的前 8 位。注意:
filename
影响,受chunkFilename
影响hash/chunkhash/contenthash
一般会配合html-webpack-plugin
(创建 html ,并捆绑相应的打包文件) 、clean-webpack-plugin
(清除原有打包文件) 一起使用。2. 打包成库
当使用 webapck 构建一个可以被其它模块引用的库时:
三、配置模式 mode(webpack4)
设置
mode
,可以让 webpack 自动调起相应的内置优化。或在命令行里配置:
在设置了
mode
之后,webpack4 会同步配置process.env.NODE_ENV
为development
或production
。webpack4 最引人注目的主要是:
减小编译时间
打包时间减小了超过 60%
零配置
我们可以在没有任何配置文件的情况下将 webpack 用于各种项目
webpack4 支持零配置使用,这里的零配置就是指,
mode
以及entry
(默认为src/index.js
)都可以通过入口文件指定,并且 webpack4 针对对不同的mode
内置相应的优化策略。1. production
配置:
相当于默认内置了:
2. development
配置:
相当于默认内置了:
3. none
不进行任何默认优化选项。
配置:
相当于默认内置了:
4. production、 development、none 总结
production 模式下给你更好的用户体验:
development 模式会给予你最好的开发体验:
尽管 webpack4 在尽力让零配置做到更多,但仍然是有限度的,大多数情况下还是需要一个配置文件。我们可以在项目的初期使用零配置,在后期业务复杂的时候再配置。
5. 环境变量 process.env.NODE_ENV
第三方框架或库,以及我们的业务代码,都会针对不同的环境配置,执行不同的逻辑代码,例如:
我们可以通过以下方式定义环境变量:
方法一:webpack4 中 mode: 'production' 已经默认配置了 process.env.NODE_ENV = 'production' ,所以 webapck4 可以不定义
尽管 webpack4 中定义
mode
会自动配置process.env.NODE_ENV
,那么我们就不需要手动配置环境变量了吗?其实不然,
mode
只可以定义成development
或production
,而在项目中,我们不仅仅只有开发或生产环境,很多情况下需要配置不同的环境(例如测试环境),此时我们就需要手动配置其它环境变量(例如测试环境,就需要定义process.env.NODE_ENV
为'test'
),你可以采取以下方式:方法二:webpack.DefinePlugin
config/prod.env.js
:方法三:webpack 命令时, NODE_ENV=development
在 window 中配置
NODE_ENV=production
可能会卡住,所以使用 cross-env:方法四:使用
new webpack.EnvironmentPlugin(['NODE_ENV'])
EnvironmentPlugin
是一个通过webpack.DefinePlugin
来设置process.env
环境变量的快捷方式。注意:上面其实是给
NODE_ENV
设置一个默认值'production'
,如果其它地方有定义process.env.NODE_ENV
,则该默认值无效。四、配置解析策略 resolve
自定义寻找依赖模块时的策略(例如
import _ from 'lodash'
):五、配置解析和转换文件的策略 module
决定如何处理项目中不同类型的模块,通常是配置 module.rules 里的 Loader:
1. noParse
指明 webpack 不去解析某些内容,该方式有助于提升 webpack 的构建性能。
2. rules
常见的 loader 有:
babel-loader
:解析.js
和.jsx
文件tsx-loader
:处理 ts 文件less-loader
:处理 less 文件,并将其编译为 csssass-loader
:处理 sass、scss 文件,并将其编译为 csspostcss-loader
:css-loader
:处理 css 文件style-loader
:将 css 注入到 DOMfile-loader
:将文件上的import
/require
解析为url
,并将该文件输出到输出目录中url-loader
:用于将文件转换成 base64 uri 的 webpack 加载程序html-loader
:将 HTML 导出为字符串, 当编译器要求时,将 HTML 最小化更多 loaders 可查看 LOADERS 。
六、配置优化 optimization(webpack4)
webapck4 会根据你所选择的
mode
进行优化,你可以手动配置,它将会覆盖自动优化,详细配置请见 Optimization 。主要涉及两方面的优化:
1. 最小化包
optimization.removeAvailableModules
删除已可用模块optimization.removeEmptyChunks
删除空模块optimization.occurrenceOrder
标记模块的加载顺序,使初始包更小optimization.providedExports
、optimization.usedExports
、concatenateModules
、optimization.sideEffects
删除死代码optimization.splitChunks
提取公共包optimization.minimizer
||TerserPlugin
来最小化包2. 拆包
当包过大时,如果我们更新一小部分的包内容,那么整个包都需要重新加载,如果我们把这个包拆分,那么我们仅仅需要重新加载发生内容变更的包,而不是所有包,有效的利用了缓存。
拆分 node_modules
很多情况下,我们不需要手动拆分包,可以使用
optimization.splitChunks
:我们不必制定拆包策略,
chunks: all
会自动将node_modules
中的所有内容放入一个名为vendors〜main.js
的文件中。拆分业务代码
采用多入口的方式,当有业务代码更新时,更新相应的包即可
拆分第三方库
当第三方包更新时,仅更新相应的包即可。
注意,当包太多时,浏览器会发起更多的请求,并且当文件过小时,对代码压缩也有影响。
动态加载
现在我们已经对包拆分的很彻底了,但以上的拆分仅仅是对浏览器缓存方面的优化,减小首屏加载时间,实际上我们也可以使用按需加载的方式来进一步拆分,减小首屏加载时间:
七、配置 plugin
配置 Plugin 去处理及优化其它的需求,
常用 plugins:
html-webpack-plugin
:生成 html 文件,并将包添加到 html 中webpack-parallel-uglify-plugin
:压缩 js(多进程并行处理压缩)happypack
:多线程loader,用于提升构建速度hard-source-webpack-plugin
:为模块提供中间缓存步骤,显著提高打包速度webpack-merge
:合并 webpack 配置mini-css-extract-plugin
:抽离 cssoptimize-css-assets-webpack-plugin
:压缩 cssadd-asset-html-webpack-plugin
:将 JavaScript 或 CSS 资产添加到 html-webpack-plugin 生成的 HTML 中更多插件可见:plugins
八、配置devtool:source map
配置 webpack 如何生成 Source Map,用来增强调试过程。不同的值会明显影响到构建(build)和重新构建(rebuild)的速度:
生产环境:默认为
null
,一般不设置(none
)或nosources-source-map
开发环境:默认为
eval
,一般设置为eval
、cheap-eval-source-map
、cheap-module-eval-source-map
策略为:
如果默认的 webpack
minimizer
已经被重定义(例如terser-webpack-plugin
),你必须提供sourceMap:true
选项来启用 source map 支持。更多可查看:devtool
###九、配置性能 performance
当打包是出现超过特定文件限制的资产和入口点,
performance
控制 webpack 如何通知:十、配置其它
1. watch 与 watchOptions
watch
监视文件更新,并在文件更新时重新编译:
在
webpack-dev-server
和webpack-dev-middleware
中,默认启用了监视模式。或者我们可以在命令行里启动监听(
--watch
):watchOptions
2. externals
排除打包时的依赖项,不纳入打包范围内,例如你项目中使用了
jquery
,并且你在 html 中引入了它,那么在打包时就不需要再把它打包进去:配置:
3.target
构建目标,用于为 webpack 指定一个环境:
4. cache
缓存生成的 webpack 模块和块以提高构建速度。在开发模式中,缓存设置为
type: 'memory'
,在生产模式中禁用。cache: true
是cache: {type: 'memory'}
的别名。要禁用缓存传递false
:在内存中,缓存仅在监视模式下有用,并且我们假设你在开发中使用监视模式。 在不进行缓存的情况下,内存占用空间较小。
5. name
配置的名称,用于加载多个配置:
十一、总结
本文仅仅是列出一些常用的配置项,所有的配置文件架构可见:WebpackOptions.json,你也可以进入 webpack 官网了解更多。
参考:
webpack
The 100% correct way to split your chunks with Webpack
webpack 4: mode and optimization
The text was updated successfully, but these errors were encountered: