Entry
:入口,Webpack 执行构建的第一步将从 Entry 开始。Module
:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出全部依赖的模块。Chunk
:代码块,一个chunk由多个模块组合而成,用于代码合并与分割。Loader
:模块转换器,用于将模块的原内容按照需求转换成新内容。Plugin
:插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件能够监听这些事件的发生,在特定时机作对应的事情。初始化参数
——> 开始编译
——> 肯定入口
——> 编译模块
——> 完成模块编译
——> 输出资源
——> 输出完成
javascript
Compiler
对象,加载全部配置的插件Plugin
,经过执行对象的run方法开始执行编译entry
找出全部的入口文件Loader
对模块进行编译,再找出该模块依赖的模块,再递归本步骤直到全部入口依赖的文件都通过处理chunk
,再将每一个chunk转换成一个单独的文件加入输出列表中,这是能够修改输出内容的最后机会写入文件系统中
(fs)总结一下,Webpack的构建流程能够分为如下三大阶段
:java
bundle.js
实际上是一个当即执行函数,bundle.js
能直接运行在浏览器中的缘由在于输出的文件中经过__webpack_require__
函数定义了一个能够在浏览器中执行的加载函数来模拟Node.js中的require语句。 并且Webpack 作了缓存优化,执行加载过的模块不会再执行第二次,执行结果会缓存在内存中,当某个模块第二次被访问时会直接去内存中读取被缓存的返回值。node
(function(modules){
//模拟require语句
function __webpack_require__(){}
//执行存放全部模块数组中的第0个模块(main.js)
__webpack_require_[0]
})([/*存放全部模块的数组*/])
复制代码
优化Loader
:优化 Loader 的文件搜索范围(exclude掉node_modules)、将Babel编译过的文件缓存起来(loader: 'babel-loader?cacheDirectory=true')。 对于 Loader 来讲,影响打包效率首当其冲必属 Babel 了。由于 Babel 会将代码转为字符串生成 AST,而后对 AST 继续进行转变最后再生成新的代码
,项目越大,转换代码越多,效率就越低。HappyPack
: 能够将Loader的同步执行转换为并行的。module: {
loaders: [
{
test: /\.js$/,
include: [resolve('src')],
exclude: /node_modules/,
// id 后面的内容对应下面
loader: 'happypack/loader?id=happybabel'
}
]
},
plugins: [
new HappyPack({
id: 'happybabel',
loaders: ['babel-loader?cacheDirectory'],
// 开启 4 个线程
threads: 4
})
]
复制代码
DllPlugin
: 能够将特定的类库提早打包而后引入。极大的减小打包类库的次数,只有当类库更新版本才有须要从新打包。// 单独配置在一个文件中
// webpack.dll.conf.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
// 想统一打包的类库
vendor: ['react']
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].dll.js',
library: '[name]-[hash]'
},
plugins: [
new webpack.DllPlugin({
// name 必须和 output.library 一致
name: '[name]-[hash]',
// 该属性须要与 DllReferencePlugin 中一致
context: __dirname,
path: path.join(__dirname, 'dist', '[name]-manifest.json')
})
]
}
// 使用 DllReferencePlugin 将依赖文件引入项目中
// webpack.conf.js
module.exports = {
// ...省略其余配置
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
// manifest 就是以前打包出来的 json 文件
manifest: require('./dist/vendor-manifest.json'),
})
]
}
复制代码
代码压缩
:webpack3中使用 webpack-parallel-uglify-plugin
来并行运行 UglifyJS
(单线程),webpack4中将mode
设置为production
则默认开启压缩。按需加载
:每一个路由页面单独打包为一个文件、loadash
这种大型类库一样能够使用这个功能。Scope Hoisting
: 会分析出模块之间的依赖关系,尽量的把打包出来的模块合并到一个函数中去。Webpack4 中开启这个功能,只须要启用 optimization.concatenateModules
。// test.js
export const a = 1
// index.js
import { a } from './test.js'
复制代码
打包上面两个文件后,生成代码相似这样:react
[
/* 0 */
function (module, exports, require) {
//...
},
/* 1 */
function (module, exports, require) {
//...
}
]
复制代码
若是使用Scope Hositing,会生成这样的相似代码:webpack
[
/* 0 */
function (module, exports, require) {
//...
}
]
复制代码
Tree Shaking
:能够实现删除项目中未被引用的代码。Webpack4的生产环境默认开启这个功能。// test.js
export const a = 1
export const b = 2
// index.js
import { a } from './test.js'
复制代码
test 文件中的变量 b 若是没有在项目中使用到的话,就不会被打包到文件中。web