webpack5 学习记录

中文官网
英文官网

一、安装

安装命令

npm install webpack webpack-cli

基础打包命令

webpack 入口文件 --mode=development #开发模式
webpack 入口文件 --mode=production #生产模式

二、webpack 配置文件

在项目根目录新建 webpack.config.js
配置核心概念有 entry(入口),output(输出),loader(加载器),plugins(插件),mode(模式)
基础配置举例:

const path = require("path")
module.exports = {
	// 入口
	entry:"./src/main.js",//相对路径
	// 输出
	output:{
		// 文件的输出路径
		path:path.resolve(__dirname,"dist")//绝对路径
		// 文件名
		filename:"static/js/main.js"
	},
	// 加载器
	module:{
		rules:[
			// loader的配置
		]
	},
	// 插件
	plugins:[
		// 插件的配置
	],
	// 开发模式
	mode:"development"
}

配置完成后就可以直接使用webpack直接打包,无需再像上面那样麻烦

三、处理样式资源 + loader 的使用

webpack 默认只打包 js 资源,样式资源不会打包,如果引入了样式资源会报错,所以需要安装相应的 loader 进行配置后才会被打包
在上面官方文档中的 loader 里面可以看到很多 loader
官网loader示例
添加 css-loader 举例:

官方文档其实是有一些问题的,因为在这个地方需要添加两个 loader,style-loader 和 css-loader,但是安装时只给提示安装一个,这里应该两个都安装
另外有时会该使用 use 的地方给写成了 loader,这两个是有区别的,use 可以使用多个 loader,是一个列表形式,loader 只能使用一个 loader

安装
npm install --save-dev css-loader style-loader
在webpack.config.js中添加配置
module: {
	rules: [
		// 如果有其他的可以继续添加,rules是一个列表形式
		{
			test: /\.css$/, //只检测符合条件的文件
			use: [
				// 执行顺序:从左到右,从下到上
				'style-loader',
				'css-loader'
			]
		},
	]
}

然后在入口文件引入需要使用的 css 文件即可

四、处理图片资源

之前是使用 file-loader 和 url-loader,没有没太了解过,webpack5 是内置了的,不用配置会自行打包图片资源,但是有时图片资源比较小,为了优化减少请求次数可以将小图片资源打包时转为 base64,或者需要配置打包后生成的图片资源名,或者打包后的输出路径等等,可以进行配置
举例,也是写在 module 的 rules 里面,但是不用安装 loader 了,只需要配置开启:

module: {
    rules: [
		{
			test: /\.(png|jpe?g|gif|webp|svg)$/,
			type: "asset",
			parser: {
				dataUrlCondition: {
					// 小于15kb的图片转base64
					// 优点:减少请求数量
					// 缺点:体积会更大
					maxSize: 15 * 1024,
				},
			},
			generator: {
				 // 输出图片名称
				 // hash指根据图片内容生成的唯一值
				 // [hash:8]指hash值取前8位
				 // ext为扩展名
				 filename: "static/images/[hash:8][ext]",
			},
		},
	]
}

五、自动清空上次打包的内容

在每次打包时,之前打包的文件需要手动删除,很麻烦很乱,在 webpack4 的时候需要装一个插件才可以自动清除后打包,webpack5 给内置了,只需在 output 里面配置一个 clean 即可

output:{
	// 自动清空上次打包的内容
	// 原理:在打包前,将path整个目录内容清空,再进行打包
	clean:true
}

六、处理其他资源

与处理图片相同,不同的是音视频或字体等不需要处理成 base64,所以不用 parser 配置,修改 type,asset/resource 会原封不动的打包出来,generator 修改输出路径
举例:

{
	test: /\.(ttf|woff2|mp3|mp4|avi)$/,
	type: "asset/resource",
	generator: {
		filename: "static/media/[hash:8][ext]",
	},
},

七、使用 eslint

在 webpack4 的时候,eslint 在 webpack 使用是作为 loader 使用,在 webpack5 是作为插件来使用的
按照官网,需要安装 eslint-webpack-plugin 和 eslint
eslint

npm install eslint-webpack-plugin --save-dev
npm install eslint --save-dev

安装完成后需要引入,然后在 plugins 里面 new
举例:

const ESLintPlugin = require("eslint-webpack-plugin");
plugins: [
	new ESLintPlugin({
		// 检测src目录下的文件
		context: path.resolve(__dirname, "src"),
	}),
],

在根目录下新建.eslintrc.js 文件,配置内容可参考eslint 官网,举例

module.exports = {
	// 继承Eslint规则
	extends: ["eslint:recommended"],
	env: {
		node: true, // 启用node中全局变量
		browser: true, // 启用浏览器中全局变量
	},
	parserOptions: {
		ecmaVersion: 6, // es6
		sourceType: "module", // es module
	},
	rules: {
		"no-var": 2, // 不能使用var定义变量
	},
};

最后可以在根目录新建一个.eslintignore 文件,写入 dist,表示排出 dist 文件夹,因为打包后的文件就不要 eslint 检查了

八、使用 babel

webpack 在打包 js 的时候不会处理 es6 的语法,例如…运算或者箭头函数等,所以需要使用 babel 将 es6 语法编写的代码转换为兼容的语法,以便运行在当前或旧版本或其他环境当中
babel 是使用 loader 处理,在官网可以找到进行安装
babel-loader
配置

{
	test: /\.js$/,
	exclude: /node_modules/, // 排出node_modules中的js文件(这些文件不处理)
	use: {
		loader: 'babel-loader',
		options: {
			// 智能预设,能够编译es6语法
			presets: ['@babel/preset-env']
		}
	}
},

也可以在根目录新建 babel.config.js 配置文件,将配置单独提出来写在配置文件中,这样 options 就可以去除了,两种方式都可以,写在外面的好处是后面方便更改
babel.config.js文件

九、处理 html 资源

按上面的处理完成后生成的 js 文件需要手动引入到 html 里面,麻烦,可以借助 webpack 插件 HtmlWebpackPlugin 自动引入
安装

npm install --save-dev html-webpack-plugin

引入

const HtmlWebpackPlugin = require('html-webpack-plugin');

使用举例

plugins: [
	new HtmlWebpackPlugin({
		// 模板:以public/index.html文件创建新的html文件
		// 新的html文件特点:1.结构和原来一致 2.自动引入打包输出的资源
		template:path.relative(__dirname,"public/index.html")
	})
],

十、配置自动化

每次修改完 src 的文件后都需要手动输命令重新打包,麻烦,可以使用 webpack-dev-server 来配置自动化打包
安装

npm i webpack-dev-server -D

配置

module.exports = {
	// 开发服务器
	devServer: {
		host: "localhost", // 启动服务器域名
		port: "3000", // 启动服务器端口号
		open: true, // 是否自动打开浏览器
	},
}

配置完成后需要使用webpack server启动

十一、提取 css 成单独文件

css 文件前面都是在 js 里面引入的,会在 js 加载时创建 style 标签来生成样式,对于网站来说会出现闪屏现象,对用户体验不好,应该单独提取 css 文件,使用 link 引入
使用 webpack 的 MiniCssExtractPlugin 插件
MiniCssExtractPlugin插件
安装

npm install --save-dev mini-css-extract-plugin

引入

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

使用

plugins: [
	new MiniCssExtractPlugin({
		// 指定输出目录
		filename: "static/css/[hash:8].css",
	}),
],

在官网看到,前面使用了style-loader的地方需要替换为MiniCssExtractPlugin.loader
再打包时,就可以看到有 css 文件了,并且在打包后的 html 文件里面也是已经引入了的

十二、css 兼容性处理

有些样式有兼容性问题,例如 ie 或 Chrome 等等的浏览器样式有的带-ms-、-webkit-、-moz-这样,使用 postcss-loader、postcss、postcss-preset-env 处理
安装

npm install postcss-loader postcss postcss-preset-env -D

配置,写在 css-loader 的后面
css兼容性处理配置
如果配置了其他例如 less-loader、sass-loader,也是要写在 css-loader 的后面,例如
css兼容性处理配置

{
	loader: "postcss-loader",
	options: {
		postcssOptions: {
			plugins: [
				"postcss-preset-env", // 能解决大多数样式兼容性问题
			],
		},
	},
},

在 package.json 中新增浏览器兼容程度,解释:1.所有浏览器最后两个版本;2 覆盖 99%的浏览器;3.不要已经死亡的浏览器;
浏览器兼容程度

"browserslist": [
	"last 2 version",
	"> 1%",
	"not dead"
]

十三、封装样式 loader 函数

在使用时可能要配置很多关于样式的 loader,例如 css,less,sass,scss,styl 等
在写 loader 的时候大部分都是相同的,为了方便维护,使代码更美观,因此可以封装 loader 函数

// 用来获取处理样式的loader
function getStyleLoader(pre) {
  return [
    //执行顺序,从右到左,从下到上
    MiniCssExtractPlugin.loader, //将js中的css通过创建style标签添加html文件中生效
    "css-loader", // 将css资源变异成CommonJS的模块到js中
    {
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          plugins: [
            "postcss-preset-env", // 能解决大多数样式兼容性问题
          ],
        },
      },
    },
    pre,
  ].filter(Boolean);
}

在使用时可以直接传入需要使用的 loader
使用loader函数示例

十四、CSS 压缩

将打包的 css 代码压缩到一行,使用 CssMinimizerWebpackPlugin 插件,html 和 js 文件如果开启生产模式默认压缩
安装

npm install css-minimizer-webpack-plugin --save-dev

引入

const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

使用

new CssMinimizerPlugin()

压缩前
压缩前
压缩后
压缩后

十五、使用 SourceMap(源代码映射)提升开发体验

一般来说程序写好后,打包完成执行出错,查看错误时提示的行数或错误点都是已经打包后的,如果是大型项目找这些错误很麻烦,因此用这个技术生成源代码与构建后的代码映射关系文件(.map 文件),在出错时浏览器会自动识别源代码出错的位置
在官网的配置---devtool可以找到
实际开发时只需要使用
在开发模式下使用cheap-module-source-map,打包编译速度快,只包含行映射,不包含列映射
在生产模式下使用source-map,打包编译速度慢,包含列和行映射
使用时只需增加一条配置即可
devtool配置示例

十六、提升打包构建速度

在打包时 webpack 默认是重新打包所有的代码,即使只改了一处,所以在大型项目会比较费时,因此使用模块热替换(hot module replacement)
这个在 webpack5 中是默认开启的,不可用于生产环境,在开发环境的开发服务器中配置 hot 即可
配置模块热替换
但是这个只开启 css 模块热替换,js 资源不会开启模块热替换,因此需要在入口文件进行判断使用

xxx.js为引入的其他js资源,这样写在修改xxx.js时就会开启模块热替换功能
后面可以跟一个函数,如果文件被更改了就会调用后面的函数
if (module.hot) {
  // 判断是否支持热模块替换功能
  module.hot.accept("xxx1.js"[,函数]);
  module.hot.accept("xxx2.js");
}

十七、oneOf 优化

在配置文件中会配置很个 loader 进行资源处理,但是这个运行的模式是会从上到下依次查看 loader 是否能处理资源,即使已经配置了正则表达式过滤,即使上面的 loader 已经可以处理,还是会往下找,因此使用 OneOf 处理

在配置的 loader 外使用 oneOf 包裹起来即可,例如之前使用

module:{
	rules:[
		{
			test: /\.css$/, //只检测.css文件
			use: [
				//执行顺序,从右到左,从下到上
				"style-loader", //将js中的css通过创建style标签添加html文件中生效
				"css-loader", // 将css资源变异成CommonJS的模块到js中
			],
		},
		{
			test: /\.less$/, //只检测.css文件
			use: [
				//执行顺序,从右到左,从下到上
				"style-loader", //将js中的css通过创建style标签添加html文件中生效
				"css-loader", // 将css资源变异成CommonJS的模块到js中
				"less-loader",
			],
		},
	]
}

使用 oneOf

module:{
	rules:[
		{
			oneOf:[
				{
					test: /\.css$/, //只检测.css文件
					use: [
						//执行顺序,从右到左,从下到上
						"style-loader", //将js中的css通过创建style标签添加html文件中生效
						"css-loader", // 将css资源变异成CommonJS的模块到js中
					],
				},
				{
					test: /\.less$/, //只检测.css文件
					use: [
						//执行顺序,从右到左,从下到上
						"style-loader", //将js中的css通过创建style标签添加html文件中生效
						"css-loader", // 将css资源变异成CommonJS的模块到js中
						"less-loader",
					],
				},
			]
		}
	]
}

十八、exclude 和 include 优化

在第八个使用 babel-loader 处理 js 资源时使用过 exclude,排出 node_modules 文件夹里的东西,因为里面是下载的第三方依赖包可以直接使用,另外有 include,为包含,例如写 src 目录就是只处理 src 目录的文件,不处理其他文件

十九、cache 缓存优化

每次打包时,都要经过 eslint 检查和 babel 编译,速度比较慢,可以缓存之前 eslint 检查和 babel 编译的结果,仅检查和编译修改的文件,这样二次打包就会变快了
处理 js 资源 babel-loader 配置,增加 options 配置项

{
	test: /\.js$/,
	include: path.resolve(__dirname, "../src"), // 只处理src下的文件,其他文件不处理
	use:[
		loader: "babel-loader",
		options: {
			cacheDirectory: true, // 开启babel缓存
			cacheCompression: false, // 关闭缓存文件压缩
		},
	]
},

插件 eslint 配置 cache,增加 cache 和 cacheLocation(缓存路径)配置项

new ESLintPlugin({
	// 检测哪些文件
	context: "src",
	exclude: "node_modules",
	cache: true,
	cacheLocation: path.resolve(__dirname, "../node_modules/.cache/eslintcache"),
}),

二十、多线程打包

为了加快打包速度,可以开启多线程打包,使用 thread-loader
安装

npm i thread-loader -D

一般打包慢的是 js,所以针对 js 资源做处理

// 前面使用nodejs的os获取cpu核数
const os = require("os");
const threads = os.cpus().length; // CPU核数

// 下面修改js的loader配置,配置thread-loader
{
	test: /\.js$/,
	include: path.resolve(__dirname, "../src"), // 只处理src下的文件,其他文件不处理
	use: [
		{
			loader: "thread-loader", // 开启多线程
			options: {
				works: threads, // 线程数量
			},
		},
		{
			loader: "babel-loader",
			options: {
				cacheDirectory: true, // 开启babel缓存
				cacheCompression: false, // 关闭缓存文件压缩
			},
		},
	],
},

同样 eslint 也可以做多线程处理,只需要增加threads即可

new ESLintPlugin({
	// 检测哪些文件
	context: "src",
	exclude: "node_modules",
	cache: true,
	cacheLocation: path.resolve(__dirname, "../node_modules/.cache/eslintcache"),
	threads, // 开启多线程和线程数量
}),

多线程压缩 js,引入 terser-webpack-plugin 插件

const TerserWebpackPlugin = require("terser-webpack-plugin");

使用

new TerserWebpackPlugin({
	parallel: threads,
}),

在 webpack5 中,官方推荐将压缩的插件单独抽出来写

plugins:[],
optimization: {
	minimizer: [
		// 压缩css
		new CssMinimizerPlugin(),
		// 压缩js
		new TerserWebpackPlugin({
			parallel: threads,
		}),
	],
},

二十一、使用@babel/plugin-transform-runtime 插件配置 babel-loader 减少代码体积

安装

npm i @babel/plugin-transform-runtime -D

使用,在 babel-loader 的 options 配置里增加 plugibs 配置即可

{
	test: /\.js$/,
	include: path.resolve(__dirname, "../src"), // 只处理src下的文件,其他文件不处理
	use: [
		{
			loader: "babel-loader",
			options: {
				cacheDirectory: true, // 开启babel缓存
				cacheCompression: false, // 关闭缓存文件压缩
				plugins: ["@babel/plugin-transform-runtime"],
			},
		},
	],
},

二十二、压缩本地静态图片体积

使用ImageMinimizerWebpackPlugin插件
下载一直报错,先不说了。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值