# 基本使用场景
# 解析代码、资源
# 解析 CSS、Less、Sass
以 Sass 为例,按顺序使用 sass-loader、css-loader、style-loader 即可。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader', 'sass-loader' ]
}
]
}
}
# 解析图片、字体等二进制文件
可以使用 file-loader 或 url-loader 加载二进制文件,file-loader 更简单一些,我们以 file-loader 为例。
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|jpeg)$/,
use: 'file-loader'
}
]
}
}
以 PNG 图片为例,file-loader 会将图片移动到输出目录,并修改文件名为:xxx.png。在业务中,我们可以像下面这样引入图片,代码中 logo 变量的值就是 xxx.png。
import logo from './logo.png'
const img = document.createElement('img')
img.src = logo
document.body.appendChild(img)
# 解析 React JSX
# 解析 Vue
# 解析 TypeScript
# 打包基础库
打包库一般会使用 Rollup,因为更加简单、纯粹,但用 Webpack 也可以。
基本需求为:
- 支持打包压缩版、非压缩版本
- 支持 AMD/CMD/ESM 引入
- 单元测试
npm publish
发包,通过钩子配置发包前执行的命令
发包的流程是:
- 执行
npm publish
命令 - 自动执行钩子,例如
npm test
、npm build
这样的命令 - 然后就会根据 package.json 中 main 字段指定的入口发包
TODO: 详细代码待补充。
# 兼容性
# 自动添加 CSS 前缀
Autoprefixer (opens new window)
# 移动端 px 自动转 rem
# 工程、效率
# HtmlWebpackPlugin
可以自动生成一个 index.html,很方便,开发必备。最高级的地方在于可以在页面中自动插入一行 <script src="bundle.js">
。
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin()
]
}
# 自动清理 dist 目录
使用 clean-webpack-plugin。
# 优化 Webpack 命令行输出
使用 stats 选项可以配置输出哪些信息,隐藏哪些信息。
也可以用 friendly-errors-webpack-plugin (opens new window) 插件。
# 其它
# 打包多页应用
单页应用叫做 SPA,多页应用叫做 MPA,MPA 会有多个入口文件。
传统 MPA 的配置方法
const path = require('path')
const HtmlwebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
home: './src/home/index.js',
about: './src/about/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name]_[hash:8].js'
},
plugins: [
new CleanWebpackPlugin(),
new HtmlwebpackPlugin({
template: path.resolve(__dirname, './src/home/index.html'),
filename: 'home.html',
chunks: ['home']
}),
new HtmlwebpackPlugin({
template: path.resolve(__dirname, './src/about/index.html'),
filename: 'about.html',
chunks: ['about']
})
],
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
}
]
}
]
},
}
上面的配置方法不够灵活,如果增加了新的页面,我们还需要手动修改 Webpack 配置文件。考虑到 Webpack 配置文件本身就是 JavaScript 代码,我们可以借此实现更灵活的打包。
关键思路如下:
- 团队成员约定多页应用中,代码文件的组织规则
- 利用 glob (opens new window) 这个包,根据约定的规则动态获取 src 目录下的文件
利用 glob 灵活打包多页应用
const path = require('path')
const HtmlwebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const glob = require('glob')
function generateMPAConfig() {
const entryFiles = glob.sync('./src/*/index.js')
// entryFiles === [ './src/about/index.js', './src/home/index.js' ]
const htmlWebpackPlugins = []
const entry = {}
entryFiles.forEach((filePath) => {
const match = filePath.match(/src\/(.+)\/index\.(js|ts)$/)
const entryName = match && match[1]
entry[entryName] = filePath
htmlWebpackPlugins.push(new HtmlwebpackPlugin({
template: path.resolve(__dirname, `./src/${entryName}/index.html`),
filename: `${entryName}.html`,
chunks: [entryName]
}))
})
return {
entry,
htmlWebpackPlugins
}
}
const { entry, htmlWebpackPlugins } = generateMPAConfig()
module.exports = {
mode: 'development',
entry,
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name]_[hash:8].js'
},
plugins: [
new CleanWebpackPlugin(),
...htmlWebpackPlugins
],
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
}
]
}
]
},
}