这是我参与「第四届青训营 」笔记创作活动的第5天。
Webpack简介
webpack本质上是一种前端资源编译、打包工具,支持以下特性
- 多份资源文件打包成一个Bundle
- 支持Babel、Eslint、Ts、CoffeScript、Less、Sass
- 支持模块化处理css、图片等资源文件
- 支持HMR + 开发服务器
- 支持持续监听、持续构建
- 支持代码分离
- 支持Tree-shaking
- 支持Sourcemap
- ···
初始准备
安装
npm install webpack webpack-cli —save-dev
运行
npx webpack
自定义webpack配置 entry:入口文件 output:输出文件 mode:development/production 开发环境需求
- 模块热更新(开启本地服务,实时更新)
- sourcemap(方便打包调试)
- 接口代理(配置proxyTable解决开发环境跨域问题)
- eslint(代码规范检查) 生产环境需求
- 提取公共代码
- 压缩混淆
- 文件压缩/base64编码
- 去除无用代码
使用Webpack
关于webpack的使用方法,基本都围绕“配置”展开,大致可以分为两类
- 流程类:作用于流程中某个或多个环节,直接影响打包效果的配置项
- 工具类:主流程之外,提供更多工程化能力的配置项
配置总览
使用频率
- entry/output
- module/plugins
- mode
- watch/devServer/devtool
Loader
什么是loader webpack自身只支持js和json这两种格式的文件,对于其他文件需要通过loader将其转换为commonJS规范的文件后,webpack才能解析到,常见loader如下
加载CSS
{
test: /\.css/,
use: ['css-loader', 'style-loader']
}
抽离和压缩CSS
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
mode: 'production',
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
mode: 'production',
plugins: [
new MiniCssExtractPlugin({ filename: 'styles/[contenthash].css' })
],
module: {
rules: [
{
test: /\.(css|less)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
},
]
},
optimization: {
minimizer: [new CssMinimizerPlugin()]
}
加载images图像
{
test: /\.(jpg|png)$/,
use: {
loader: "url-loader",
options: {
limit: 25000, //25KB以上图像会调用file-loader
},
},
},
{
test: /\.(jpg|png)$/,
use: {
loader: "file-loader",
options: {
name: "[path][name].[hash].[ext]",
},
},
},
加载数据
{
test: /\.(csv|tsv)$/,
use: 'csv-loader'
},
{
test: /\.xml$/
use: 'xml-loader'
}
自定义JSON模块parser
{
test: /\.tmol$/,
type: 'json',
parser: {
parser: toml.parse
}
},
{
test: /\.yaml$/,
type: 'json',
parser: {
parser: yaml.parse
}
},
{
test: /\.json5$/,
type: 'json',
parser: {
parser: json5.parse
}
Babel-loader
对不支持es6的浏览器使用babel-loader打包将es6转化为es5
{
test: /\.js/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
preset: ['@babel/preset-env']
}
}
}
插件
Plugin 是一个扩展器,它丰富了 webpack 本身,针对是 loader 结束后,webpack 打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听 webpack 打包过程中的某些节点,执行广泛的任务。
插件的特点
- 是一个独立的模块
- 模块对外暴露一个 js 函数
- 函数的原型
(prototype)上定义了一个注入compiler对象的apply方法apply函数中需要有通过compiler对象挂载的webpack事件钩子,钩子的回调中能拿到当前编译的compilation对象,如果是异步编译插件的话可以拿到回调callback - 完成自定义子编译流程并处理
complition对象的内部数据 - 如果异步编译插件的话,数据处理完成后执行
callback回调。
热更新插件
模块热更新插件。Hot-Module-Replacement 的热更新是依赖于 webpack-dev-server,后者是在打包文件改变时更新打包文件或者 reload 刷新整个页面,HRM 是只更新修改的部分。
const webpack = require('webpack')
plugins: [
new webpack.HotModuleReplacementPlugin(), // 热更新插件
]
html-webpack-plugin
生成 html 文件。将 webpack 中entry配置的相关入口 chunk 和 extract-text-webpack-plugin抽取的 css 样式 插入到该插件提供的template或者templateContent配置项指定的内容基础上生成一个 html 文件,具体插入方式是将样式link插入到head元素中,script插入到head或者body中。
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.join(__dirname, '/index.html'),
minify: {
// 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换行符
minifyCSS: true, // 压缩内联css
},
inject: true,
}),
]
clean-webpack-plugin
clean-webpack-plugin 用于在打包前清理上一次项目生成的 bundle 文件,它会根据 output.path 自动清理文件夹;这个插件在生产环境用的频率非常高,因为生产环境经常会通过 hash 生成很多 bundle 文件,如果不进行清理的话每次都会生成新的,导致文件夹非常庞大。
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, '/index.html'),
}),
new CleanWebpackPlugin(), // 所要清理的文件夹名称
]
开发环境配置
- 使用source map devtool: 'inline-source-map‘ 在浏览器中可以定位到具体的错误位置
- 使用watch mode npx webpack -watch 如果文件被更新,代码将被重新编译,不必手动运行整个构建
- 使用webpack-dev-server 提供了一个基本的web server,并且具有live reloading功能