一、代码分离
代码分离方法有三种:
- 入口起点:使用 entry 配置手动地分离代码。
- 防止重复:使用 SplitChunksPlugin 去重和分离 chunk。
- 动态导入:通过模块中的内联函数调用来分离代码。
二、动态导入(dynamic imports)
- import()
- require.ensure
三、预取/预加载模块(prefetch/preload module)
webpack v4.6.0+ 添加了预取和预加载的支持。
在声明 import 时,使用下面这些内置指令,可以让 webpack 输出 "resource hint(资源提示)",来告知浏览器:
- prefetch(预取):将来某些导航下可能需要的资源
- preload(预加载):当前导航下可能需要资源
四、shim预设依赖
(1)shim 预置全局变量
一些 third party(第三方库) 可能会引用一些全局依赖(例如 jQuery
中的 $
)
以下配置含义:如果你遇到了至少一处用到 _
变量的模块实例,那请你把lodash
package 引入进来,并将其提供给需要用到它的模块。
// import _ from 'lodash'; // 不需要了, 直接能用_
new webpack.ProvidePlugin({
_: 'lodash'
})
也可以只是引用某一个方法join, 通过配置一个“数组路径”(例如 [module, child, ...children?]
)实现此功能.
这样能更好的和tree shaking配合
new webpack.ProvidePlugin({
// _: 'lodash'
join: ['lodash', 'join']
})
(2)细粒度 shim
this=>window
https://v4.webpack.docschina....
(3) 全局 export
如何将没有导出的js代码,通过模块加载
五、渐进式应用网络程序
server-works
六、环境变量
如果设置 env
变量,却没有赋值,--env.production
默认表示将 --env.production
设置为 true
。
webpack CLI 文档。
webpack --env.NODE_ENV=local --env.production --progress
// 使用env
module.exports = env => {}
七、构建性能要点
(通用环境)==========》
1、webpack更新到最新版本
2、loader(include)
3、引导时间
每个额外的 loader/plugin 都有其启动时间。尽量少使用工具。
4、解析
- 减少
resolve.modules
,resolve.extensions
,resolve.mainFiles
,resolve.descriptionFiles
中 items 数量,因为他们会增加文件系统调用的次数。 - 如果你不使用 symlinks(例如
npm link
或者yarn link
),可以设置resolve.symlinks: false
。 - 如果你使用自定义 resolve plugin 规则,并且没有指定 context 上下文,可以设置
resolve.cacheWithContext: false
。
5、dll
使用 DllPlugin
为更改不频繁的代码生成单独编译结果。这可以提高应用程序的编译速度
6、小即是快(smaller = faster)
- 使用数量更少/体积更小的 library。
- 在多页面应用程序中使用
CommonsChunkPlugin
。 - 在多页面应用程序中使用
CommonsChunkPlugin
,并开启async
模式。 - 移除未引用代码。
- 只编译你当前正在开发的那些代码。
7、worker 池(worker pool)
thread-loader
可以将非常消耗资源的 loader 分流给一个 worker pool。
不要使用太多的 worker,因为 Node.js 的 runtime 和 loader 都有启动开销。最小化 worker 和 main process(主进程) 之间的模块传输。进程间通讯(IPC, inter process communication)是非常消耗资源的。
8、持久化缓存
使用 cache-loader
启用持久化缓存。使用 package.json
中的 "postinstall"
清除缓存目录。
9、自定义 plugin/loader
(开发环境)==========》先不说了
(生产环境)==========》
1、多个 compilation(编译时)
在进行多个 compilation 时,以下工具可以帮助到你:
parallel-webpack
:它允许在 worker 池中运行 compilation。cache-loader
:可以在多个 compilation 之间共享缓存。
2、 source map ===> false
(下列工具存在某些可能会降低构建性能的问题)==========》
1、 babel: 最小化项目中的 preset/plugins 数量。
2、 typescript
- 在单独的进程中使用
fork-ts-checker-webpack-plugin
进行类型检查。 - 配置 loader 跳过类型检查。
- 使用
ts-loader
时,设置happyPackMode: true
/transpileOnly: true
。
3、 sass
node-sass
中有个来自 Node.js 线程池的阻塞线程的 bug。 当使用thread-loader
时,需要设置workerParallelJobs: 2
。
配置项重点详解
(1)mode: "pruduction"
- 启用 minification(代码压缩) 和 tree shaking (usedExports:true)
- 自动指定DefinePlugin:process.env.NODE_ENV === 'production'
(2)devtool
- 生产环境:source-map
- 开发环境:inline-source-map
(3)optimization
splitChunks
splitChunks: {
chunks: 'all', // 提取公共模块 loadash
// 将第三方库(library)(例如 lodash 或 react)提取到单独的 vendor chunk 文件中,是比较推荐的做法
// 利用 client 的长效缓存机制,命中缓存来消除请求,并减少向 server 获取资源,同时还能保证 client 代码和 server 代码版本一致。
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
},
runtimeChunk
runtimeChunk: 'single' // 提取引导模板 将 runtime 代码拆分为一个单独的 chunk
(5)output
// filename: '[name].[contenthash].js', // content hash 内容变化才会变化
filename: 'webpack-numbers.js',
path: path.resolve(__dirname, 'dist'),
// 暴露 library 这是库名称 import from 'webpackNumbers'
library: 'webpackNumbers',
libraryTarget: 'umd'
(6)plugins
HashedModuleIdsPlugin
const { HashedModuleIdsPlugin } = require('webpack');
plugins: [
// 不会因模块增加和减少导致的模块内容变化,增加长缓存命中机制
new HashedModuleIdsPlugin()
],
BundleAnalyzerPlugin
分析打包代码
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
plugins: [
new BundleAnalyzerPlugin()
]
(7)externals
// 外部化 lodash
lodash: {
commonjs: 'lodash',
commonjs2: 'lodash',
amd: 'lodash',
root: '_'
}
// 对于想要实现从一个依赖中调用多个文件的那些 library:
externals: [
'library/one',
'library/two',
// 匹配以 "library/" 开始的所有依赖
/^library\/.+$/
]
(8)module.rules ( loader )
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
},
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。