一、webpack 认识
- 为什么需要构建工具,如下所示:
- 转换
ES6
语法 - 转换
JSX
CSS
前缀补全/预处理器- 压缩混淆
- 图片压缩
- 前端构建演变之路,
ant + YUI Tool -> grunt -> fis3、gulp -> rollup、webpack、parcel
。 - 为什么选择
webpack
,如下所示:
- 社区生态丰富
- 配置灵活和插件化扩展
- 官方更新迭代速度快
- 初识
webpack
,如下所示:
- 配置文件名称,
webpack
默认配置文件为 webpack.config.js
,可以通过 webpack --config
指定配置文件 webpack
配置组成,entry
是打包的入口文件,output
是打包的输出,mode
是环境,module
的 rules
是 Loader
配置,plugins
是插件配置。
- 零配置
webpack
包含哪些内容,如下所示:
- 指定默认的
entry
为 ./src/index.js
,指定默认的 output
为 ./dist/main.js
。
- 安装
webpack
可以通过 npm install webpack webpack-cli --save-dev
命令。 - 通过
npm script
运行 webpack
,通过 npm run build
进行构建,原理是模块局部安装会在 node_modules/.bin
目录创建软链接,配置如下所示:
"scripts": {
"build": "webpack"
}
二、webpack 基础用法的Entry、Output、Loaders、Plugins、Mode 和资源解析
- 核心概念之
Entry
,Entry
用来指定 webpack
的打包入口。 - 对于依赖图而言,依赖图的入口是
entry
,对于非代码比如图片、字体依赖也会不断加入到依赖图中。 Entry
的用法,如下所示:
module.exports ={
entry: './path/index.js'
}
module.exports ={
entry: {
app: './src/app.js',
adminApp: './src/adminApp.js'
}
}
- 核心概念之
Output
,Output
用来告诉 webpack
如何将编译后的文件输出到磁盘。 Output
的用法,如下所示:
module.exports ={
entry: './path/index.js',
output: {
filename: 'bundle.js',
path: _dirname + '/dist'
}
}
- 多入口配置,通过占位符确保文件名称的唯一,代码如下:
module.exports ={
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: _dirname + '/dist'
}
}
- 核心概念之
Loaders
,webpack
开销即用只支持 JS
和 JSON
两种文件类型,通过 Loaders
去支持其它文件类型并且把它们转化成有效的模块,并且可以添加到依赖图中。本身是一个函数,接收源文件作为参数,返回转换的结果。 - 常用的
Loaders
有哪些,如下所示:
babel-loader
,转换 ES6、ES7
等 JS
新特性语法css-loader
,支持 .css
文件的加载和解析less-loader
,将 less
文件转换成 css
ts-loader
,将 TS
转换成 JS
file-loader
,进行图片、字体等的打包raw-loader
,将文件以字符串的形式导入thread-loader
,多进程打包 JS
和 CSS
Loaders
的用法,test
指定匹配规则,use
指定使用的 loader
名称,代码如下所示:
module.exports ={
entry: './path/index.js',
output: {
filename: 'bundle.js',
path: _dirname + '/dist'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader'}
]
}
}
- 核心概念之
Plugins
,插件用于 bundle
文件的优化,资源管理和环境变量注入,作用于整个构建过程。 - 常见的
Plugins
有哪些,如下所示:
CommonsChunkPlugin
,将 chunks
相同的模块代码提取成公共的 js
CleanWebpackPlugin
,清理构建目录ExtractTextWebpackPlugin
,将 CSS
从 bundle
文件里提取成一个独立的 CSS
文件CopyWebpackPlugin
,将文件或者文件夹拷贝到构建的输出目录HtmlWebpackPlugin
,创建 html
文件去承载输出的 bundle
UglifyjsWebpackPlugin
,压缩 JS
ZipWebpackPlugin
,将打包出的资源生成一个 zip
包
Plugins
的用法,放到 plugins
数组里,代码如下:
module.exports ={
entry: './path/index.js',
output: {
filename: 'bundle.js',
path: _dirname + '/dist'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader'}
]
},
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
}
- 核心概念之
Mode
,Mode
用来指定当前的构建环境是 production、development
还是 none
,设置 mode
可以使用 webpack
内置的函数,默认值为 production
。 Mode
的内置函数功能,如下所示:
development
,设置 process.env.NODE_ENV
的值为 development
,开启 NamedChunksPlugin
和 NamedModulesPlugin
production
,设置 process.env.NODE_ENV
的值为 production
,开启 SideEffectsFlagPlugin
和 TerserPlugin
none
,不开启任何优化选项
- 资源解析,如下所示:
- 解析
ES6
,使用 babel-loader
,babel
的配置文件是 .babelrc
,代码如下:
module.exports ={
entry: './path/index.js',
output: {
filename: 'bundle.js',
path: _dirname + '/dist'
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader'
}
]
}
}
- 增加
ES6
的 babel preset
配置,代码如下:
{
"presets": [
"@babel/preset-env"
],
"plugins": [
"@babel/proposal-class-properties"
]
}
- 解析
React JSX
,增加 React
的 babel preset
,代码如下:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/proposal-class-properties"
]
}
- 解析
CSS
,css-loader
用于
加载 .css
文件,并且转换成 commonjs
对象,style-loader
将样式通过 <style>
标签插入到 head
中,代码如下:
const path = require('path');
module.exports ={
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(_dirname + 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
}
}
- 解析
Less
和 Sass
,less-loader
用于将 less
转换成 css
,代码如下:
const path = require('path');
module.exports ={
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(_dirname + 'dist')
},
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
}
- 解析图片,
file-loader
用于处理文件,代码如下:
const path = require('path');
module.exports ={
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(_dirname + 'dist')
},
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
}
}
- 解析字体,
file-loader
也可以用于处理字体,代码如下:
const path = require('path');
module.exports ={
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(_dirname + 'dist')
},
module: {
rules: [
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
}
}
- 使用
url-loader
,url-loader
也可以处理图片和字体,可以设置较小资源自动 base64
,代码如下:
const path = require('path');
module.exports ={
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(_dirname + 'dist')
},
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 10240
}
}]
}
]
}
}