一、常见需求
1、简单配置入口和出口,实现build打包功能。
入口配置(建议在配置入口文件时使用绝对路径)
出口配置(在配置出口时只能使用绝对路径)
[chunkhash] 生成hash字符串的方式:每次打包,webpack根据当前chunk进行计算,如果发现有代码变化,就生成新的hash名;如果当前chunk没有代码变化,生成的hash名和上一次一样。
filename: 'js/[name].[chunkhash].js', // 格式化字符串
2、配置本地服务,以便开发环境
webpack-dev-server 它是基于express、sockjs的一个node服务器。全局、本地都安装。
本地服务只对development环境起作用
3、自动清除dist目录,添加文件hash值,开启编译进度条、开启代码压缩
自动清除dist目录
v5:output出口配置中添加 clean:true
如果是v4,用 clean-webpack-plugin
添加文件hash值
filename: 'js/[name].[chunkhash].js', // 格式化字符串
开启编译进度条
plugins中设置 new webpack.ProgressPlugin()
开启代码压缩
optimization:{ minimize:true, minimizer:[new TerserPlugin()] }
4、区分开发环境和生产环境。
const common = require('./common')
const build = require('./build')
const serve = require('./serve')
const { merge } =require('webpack-merge')
module.exports = env => merge(common, env.development?serve:build)
mode区分
5、在当前环境支持图片的模块化
v4的写法
{ test: /\.(png|jpg|jpeg|gif|webp|svg)$/, use: ['url-loader'] },
{ test: /\.(png|jpg|jpeg|gif|webp|svg)$/, use: ['file-loader'] },
v5的写法
{ test: /\.(png|svg|jpg|jpeg|gif)$/, type: 'asset/resource' },
6、在当前环境中支持样式的模块化
css-loader、style-loader、css抽离
处理样式模块(v4和v5的写法是一样的)
{ test: /\.(css|scss|sass)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'] },
注意1:当同一个项目中使用sass、less、postcss、stylus等多种css预处理器时,我们要分别编写多条样式模块的解析规则。如果只有一种css预处理器,我们通常把处理.css的loader和处理当前这种css预处理器的loader写在一起。
[chunkhash] 生成hash字符串的方式:每次打包,webpack根据当前chunk进行计算,如果发现有代码变化,就生成新的hash名;如果当前chunk没有代码变化,生成的hash名和上一次一样。
注意2:当同一条规则需要多个loader协同完成任务时,要注意loaders的顺序,数组中后面的loader先工作
注意3:一般我们很少使用style-loader,而应该使用。。。。把css代码抽离成样式的文件。
sass-loader用于加载.scss/.sass文件的,要交给sass编译器进行编译。(要特别注意node版本、webpack版本和sass-loader版本之间的兼容性)
node v12+ sass-loader v12+ webpack v5
node v12- sass-loader v10- webpack v4
7、把src中的js代码编译成浏览器能够普通兼容的ES5代码
1、第一条规则:当webpack运行时,如果遇到以.js为后缀的文件时,webpack就使用babel-loader来加载.js文件,然后交给Babel编译器(@babel/core、@babel/preset-env)进行编译转换,最终得到ES5代码。
2、babel-loader 专门用于加载javascript文件,然后交给Babel编译器进行编译。
装了一系列的Babel预设和插件,添加babel.config.js对各种Babel包进行配置
@babel/core Babel编译器核心包
@babel/preset-env 用于编译ES6+代码
@babel/preset-react 用于编译jsx代码
@babel/preset-typesript 用于编译ts代码
3、配置预设
就是一些比较大的javascript语法版本。预设不一定能够编译所有的小语法
presets: [
['@babel/preset-env', {}]
],
@babel/core 是Babel编译器的核心代码,最新版本 v7
@babel/preset-env 是一个Babel预设,用于编译ES6+语法
@babel/preset-react 是一个Babel预设,用于编译jsx语法
@babel/preset-typescript 是一个Babel预设,用于编译ts语法
4、配置插件
用于弥补预设不能编译的小语法问题
plugins: [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", {}]
]
8、在当前环境中集成ESLint检测(集成React开发环境的代码检测)
1、v4 eslint-loader
exclude 忽略对某种目录或文件的检测
enforce:'pre' 这条规则是一条前置规则,发生一般规则之前。只有当这条规则验证通过了,后面的一般规则才会运行。
eslint-loader 专门用于加载javascript文件,然后交给eslint系列的检测工具进行检测。所以,我们还要安装很多合适的eslint检测工具,并在项目中添加eslint的相关配置文件。
2、v4 eslint-webpack-plugin 参见.eslintrc.js这个配置。
3、在v5中,使用eslint-webpack-plugin来配置ESLint,语法是CommonJS语法
意义:协同开发保证代码规范和一致性。(每个公司的ESlint规范不一样)
ESLint只是一个javascript代码检测工具,所以根据不同的项目我们需要安装不同的ESLint检测器(代码规范的标准)
ESLint的配置文件有六种,当前这种是优先级最高的。(.eslint.js文件)
4、如何解决ESLint报错或警告的问题呢?
1、老老实实地找到报错或警告的地方,把它修复好。(开发环境不便于写代码)
2、找到这条ESLint规则的名称,在ESLint配置文件中修改它的检测级别
3、使用ESlint注释包裹代码,忽略这段代码的检测。
// eslint-disable-line
/* eslint-disable */ /* eslint-enable */
/* eslint-disable no-var */ /* eslint-enable no-var */
4、找到webpack配置文件,把eslint规则注释掉。(慎用)
5、在项目的根目录添加 .eslintigore 这个文件。(选择性地忽略某些目录或文件)
经验:如果项目老是频繁报eslint错误,建议直接在项目根目录添加一个.eslintigore文件,选择性忽略某些代码的检测。当提交代码前,一定要移除.eslintigore文件,重启项目,修复所有的eslint问题。(协同开发时,切忌把有eslint问题的代码提交到远程)
5、定制React开发环境的代码检测:
eslint-loader 在webpack v4中集成ESLint
eslint-webpack-plugin 在webpack v5中集成ESlint
eslint 这是ESLint官方提供的基础检测工具,只要使用ESLint必须安装它
eslint-plugin-react 这是一个用于检测React语法的ESlint插件
eslint-plugin-react-hooks 这是一个用于检测React Hooks语法的ESLint插件
eslint-plugin-jsx-a11y 这是一个用于检测React JSX元素属性语法的ESLint插件
eslint-plugin-import 这是一个用于检测ES6+模块化语法的ESLint插件
eslint-config-airbnb 由爱彼迎公司开源的一个ESLint套件
@babel/eslint-parser 它是Babel-ESlint的前身,可兼容ESLint的默认解析器,用于对比较新的js语法进行检测。
6、改变eslint规则的检测级别(三种检测级别)
off (0) -关闭规则
warn (1) -违反规则给警告
error (2) -违反规则给报错
9、在当前环境下支持jsx语法
安装 @babel/preset-react 参见babel.config.js这个配置。
二、webpack拓展
loader
1、常用loader有哪些?罗列七八个。
style-loader 将css添加到DOM的内联样式标签style里
css-loader 允许将css文件通过require的方式引入,并返回css代码
less-loader 处理less
sass-loader 处理sass
file-loader 分发文件到output目录并返回相对路径
url-loader 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url
html-minify-loader 压缩HTML
babel-loader 用babel来转换ES6文件到ES5
2、自定义loader
每个loader都是一个function函数,它接收一种文件(对象或字符串),最终返回另外一种文件(对象、字符串或JS代码),什么是必须返回JS代码呢?如果当前封装的loader用于webpack规则中最后的一个loader,那么必须返回js代码。
自定义loader的基本语法:
module.exports = function(source) {
// 使用任何第三方js模块do something
const result = 'some string or object'
// return `module.exports = ${JSON.stringify(result)}`
return `export default ${JSON.stringify(result)}` }
如果一个loader不用于webpack规则的最后一个loader,不要抛出js代码。
plugin
1、常用plugins有哪些?罗列七八个。
Html-Webpack-Plugin 在打包结束后,动生成个 html 文件,并把打包生成的js 模块引到该 html 中
clean-webpack-plugin 删除(清理)构建目录
MiniCssExtractPlugin 抽离css文件
ESLintPlugin 代码检测工具
2、自定义plugin
每个plugin本质上都是一个class类(这个类必须有一个叫apply实例方法,在这个apply用于向webpack的hooks钩子上添加一个事件)。
自定义封装plugin最重要的是理解什么webpack的hooks钩子。
举例:clean-webpack-plugin
优化
Wepack开发环境优化(start)优化标准:运行速度尽量快
1、devtool: 'inline-source-map'(负)
2、watch代码依赖图的变化,在v5中hot:true实现热更新(正)
3、在开发环境中开启memory缓存(生产环境下默认是关闭的)(正)
4、在编写各种loaders规则或者plugin时,使用exclude、include减少node文件系统的工作。(正)
5、巧用resolve对各种路径进行优化,缩小搜索范围。(正)
6、使用thread-loader(注意硬件配置)开启多线程构建。(正)
7、使用cache-loader对“指定文件模块”进行缓存。(正)
8、使用 speed-measure-webpack-plugin 对所有的plugins进行加速。(正)
Webpack生产打包优化(build)优化标准:代码质量优化
1、devtool: 'source-map'(正)
2、chunks拆分:
① 在前端代码中使用“动态导入()=>import()”自动实现代码分离(正)(推荐)安装 @babel/plugin-syntax-dynamic-import 支持动态导入语法
② 使用optimization.splitChunks 或 split-chunks-plugin手动实现分离分离(正)(很少用)
3、vendor抽离:在entry入口中对多个chunk中重复的代码进行抽离(正)
4、bundle分析技术:使用webpack-bundle-analyzer对“代码依赖图”进行人工分析
5、使用 tree-shaking 技术把src中的“死代码”移除掉,以节省打包后代码的体积。具体做法是在package.json中添加"sideEffects":false,该功能只对mode:production起作用。
6、抽离CSS并压缩:
① 使用 mini-css-extract-plugin 把css代码抽离出来
② 使用 css-minimizer-webpack-plugin 把css代码进行压缩
7、terser压缩:使用 terser-webpack-plugin 集成terser高性能压缩