前言-为什么要使用webpack
- 转换ES6
- 转换jsx(vue、ts等 )
- css前缀补全/预处理器(sass、less等)
- 图片压缩
- 压缩混淆
配置⽂文件名称
webpack 默认配置⽂文件:webpack.config.js
,可通过webpack --config
来指定配置文件。
在webpack.config.js
中,除了我们常用的导出对象的方式,还有多种配置类型。
- 导出为一个函数
module.exports = function(env, argv) {
return {
mode: env.production ? 'production' : 'development',
devtool: env.production ? 'source-maps' : 'eval',
...
};
};
该函数会传入两个参数。一个是环境对象(environment),另一个是map
对象。
- 导出一个 Promise
这种方法便于需要异步地加载所需的配置变量。
module.exports = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
entry: './app.js',
/* ... */
})
}, 5000)
})
}
- 导出多个配置对象
module.exports = [{
output: {
filename: './dist-amd.js',
libraryTarget: 'amd'
},
entry: './app.js',
mode: 'production',
}, {
output: {
filename: './dist-commonjs.js',
libraryTarget: 'commonjs'
},
entry: './app.js',
mode: 'production',
}]
下面我们介绍一些配置文件中的核心配置概念。
核心概念--Entry
我们可以在entry
中设置一个或多个入口文件,默认值为 ./src
。
- 设置单个入口
用法:entry: string|Array
// webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js'
};
即当使用Array<string>
时,仍会仅生产一个bundle
文件(下同,会生成对应的一个chunk
文件)。
- 设置多个入口
用法:entry: {[entryChunkName: string]: string|Array}
// webpack.config.js
module.exports = {
app: './src/app.js',
vendors: './src/vendors.js'
};
上面的单个入口同下面的配置:
// webpack.config.js
module.exports = {
main: './path/to/my/entry/file.js'
};
常见场景
- 多页面应用程序
const config = {
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
};
每个HTML页面单独引入一个index.js
,需要3个分离的依赖图。
这里可以使用CommonsChunkPlugin
来抽取公共逻辑代码,减少。
当然,这种写法在每次新增或删除⻚页⾯,都需要改webpack配置。这里我们可以使用glob.sync
来动态设置。
entry: glob.sync(path.join(__dirname, './src/*/index.js'))
- 用于实现组件库的压缩版本和非压缩版本
const config = {
entry: {
"index": "./src/index.js",
"index.min": "./src/index.js"
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\.min\.js$/,
}),
],
}
};
这里我们使用TerserPlugin
来实现代码压缩(后面介绍),并且仅压缩*.min.js
文件。
当然,在使用的该组件库的时候,我们可以设置package.json
的main
为index.js
,在该文件中动态引入压缩版本和非压缩版本。
// index.js
if (process.env.NODE_ENV === "production") {
module.exports = require("./dist/index.min.js");
} else {
module.exports = require("./dist/index.js");
}
核心概念--Output
output
属性的最低要求为必须是一个对象,且具有以下两个属性(更多的属性说明见这里):
- filename,用于输出文件的名称
- path,用于输出文件所在目录的绝对路径
- 单入口配置
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
filename: 'bundle.js’,
path: __dirname + '/dist'
},
};
- 多入口配置
module.exports = {
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
},
};
由于多个入口,会生成多个bundle
文件,所以这里使用占位符来进行区分。
核心概念-Loaders
webpack
开箱即用只支持JS和JSON两种文件类型,需要loader
将其他类型的文件转为webpack
能够处理的文件类型,并添加到依赖图中完成打包。
loader
支持链式传递。
loader
类似于其他构建工具中“任务(task)”,本身是一个函数。传递链中的第一个loader
将返回值传递给下一个loader
。在最后一个 loader,返回 webpack 所预期的 JavaScript。
loader
可以是同步的,也可以是异步的。loader
接收查询参数,用于对loader
传递配置;也能够使用options
对象进行配置。
常见的loader
名称 | 描述 | babel-loader | 转换ES6等JS新语法特性 | ts-loader | 将TS转为JS | css-loader | 支持.css文件的加载和解析 | less-loader | 将less文件转为.css文件 | file-loader | 处理图片文件 | raw-loader | 将文件以字符串的形式导入,比如.txt文件 | less-loader | 将less文件转为.css文件 | thread-loader | 多进程打包css和js文件 |
---|
更多loader
可以参考这里。
使用loader
我们一般在配置文件中通过module.rules
来设置loader
使用方式。
注:还有内联方式(每个import
语句中显式指定loader
)和CLI方式,但是不推荐。
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};
其中,test
用于匹配待处理的文件;use
表示使用的loader
,当需要使用多个loader
时,use
的值可以为数组,其loader
的执行顺序为从右到左。
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
]
}
如上所示,处理.css
文件时,会先执行css-loader
,再执行style-loader
。
核心概念-Plugins
插件是webpack
的支柱功能,用于bundle
文件的优化,资源管理理和环境变量量注⼊入,即解决loader
无法处理的事情,会作用于整个构建过程。
插件就是一个含有apply
方法的类,在apply
方法中会传入compiler
(即webpack实例)。我们可以通过调用compiler
中暴露的钩子函数,完成在webpack构造过程的相关功能。
class MyExampleWebpackPlugin {
apply(compiler) {
compiler.hooks.emit.tapAsync(
'MyExampleWebpackPlugin',
(compilation, callback) => {
...
callback();
}
);
}
}
这里调用的钩子函数的tapAsync
方法(异步调用),取决于不同的钩子类型,也可以在某些钩子上访问tap
(同步调用)和tapPromise
。
更多插件相关内容可参考这里。
常用插件
名称 | 说明 | CommonsChunkPlugin | 提取块之间共享的通用模块 | CopyWebpackPlugin | 将单个文件或整个目录复制到构建目录 | CleanWebpackPlugin | 清理构建目录 | MiniCssExtractPlugin | 将CSS单独提取为一个文件 | HotModuleReplacementPlugin | 启用热模块更换(HMR) | HtmlWebpackPlugin | 轻松创建HTML文件来服务您的捆绑软件 | TerserPlugin | 使用Terser缩小项目中的JS |
---|
更多插件内容可以参考这里。
Webpack构建流程
Webpack
的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:
- 初始化参数
从配置文件和CLI
配置语句中读取与合并参数,得出最终的参数。
- 开始编译
用上一步得到的参数初始化Compiler
对象,加载所有配置的插件,执行对象的run
方法开始执行编译。
- 确定入口
根据配置中的entry
找出所有的入口文件
- 编译模块
从入口文件出发,调用所有配置的loader
对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理。
- 完成模块编译
- 输出资源
根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk
文件,再把每个chunk
文件转换成一个单独的bundle
文件加入到输出列表。
- 输出完成
在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
总结
Webpack
配置文件中,通过entry
设置编译入口文件,在output
设置编译后的文件目录,通过loader
引入其他类型文件,通过plugin
来实现一些loader
无法达到的功能。
参考
- 玩转webpack --极客时间
- 「吐血整理」再来一打Webpack面试题
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!