Skip to content

webpack基本使用

一、webpack基本概念

webpack是为现代的JavaScript应用而生的静态的模块打包器

如图,webpack可以将各种资源打包成最基本的静态资源(js、css、html)

二、webpack的两种使用方式

2.1 node方式

jsx
const webpack = require('webpack')
// config 表示webpack的配置
webpack(config, (err, stats) => {})
json
{
	"scripts": {
		"build": "node ./build.js"
	}
}

2.2 命令行方式

bash
npm i webpack webpack-cli -D
json
{
	"scripts": {
		"build": "webpack"
	}
}

三、webpack配置文件

jsx
module.exports = {
		// 项目入口
		entry: '',
		output: {
			path: '',
			filename: ''
		},
}

四、webpack打包

4.1 webpack的打包流程

  1. 根据命令行或者配置文件找到入口文件
  2. 从入口开始,逐步形成依赖关系图依赖关系图包含JavaScript应用程序的所有模块(比如JavaScript文件,css文件、图片、字体等)
  3. 遍历依赖关系图,打包一个个模块(根据不同的文件使用不同的loader来解析)

4.2 loader的作用

webpack默认支持解析js文件以及json文件,因此我们可以直接导入js或者json文件,但是当我们直接导入除这两种格式以外的文件类型进行打包时,webpack会报以下错误:

module parse fail in ‘./src’,you need an appropriate loader to handle this file type.

这就是loader的作用,它可以加强webpack对其他文件的支持

4.3 配置loader

jsx
module.exports = {
		module: {
				rules: [
						{
								test: /\.css$/,
								loader: 'css-loader'
						}
				]
		}
}

4.4 常用的loader

  • 处理css的loader
    • style-loader(将css处理为页面style样式)
    • css-loader(解析css)
    • postcss-loader
      • autoprefixer(自动添加浏览器前缀)
      • postcss-preset-env(将现代化的css特性转为浏览器认识的,包括添加前缀)
  • 处理文件

webpack5可以直接使用资源模块类型来代替loader,只需要在module.rules 中添加对应的规则

jsx
module.exports = {
		module: {
				rules: [
						{
								test: /\.(png|jpe?g|webp|svg|gif)$/,
								type: 'asset'
						}
				]
		}
}
  • 处理.js文件
    • babel-loader
      • @babel/plugin-transform-arrow-functions
      • @babel/plugin-transform-block-scoping
      • @babel/preset-env
  • 处理.vue文件
    • vue-loader
      • VueLoaderPlugin(插件,必须使用)

4.5 resolve模块解析

  1. 确定文件还是文件夹
  • 如果是一个文件
    • 文件具有扩展名,则直接打包文件
    • 否则,使用resolve.extensions选项作为文件扩展名解析
  • 如果是一个文件夹
    • 会在文件夹中根据resolve.mainFiles配置选项中的文件顺序查找
      • resolve.mainFiles的默认值是['index']
      • 再根据resolve.extensions来解析扩展名

resolve.extensions 默认值['.wasm', '.js', '.mjs', '.json']

  1. alias配置别名
jsx
module.exports = {
	resolve: {
		alias: {
			utils: path.resolve(__dirname, './src/utils')		
		}
	}
}

4.6 plugin

loader与plugin的区别

  • loader用于特定模块类型的转换
  • plugin可以用于执行更广泛的任务,比如打包优化、资源管理、环境变量注入

4.7 常用的plugin

jsx
module.exports = {
	plugins: [
		// 打包前先清除掉所有打包文件
		new CleanWebpackPlugin(),
		// 自动生成模板html
		new HtmlWebpackPlugin({
			// 指定title
			title: 'webpack',
			// 指定模板
			template: '模板路径'
		}),
		new webpack.DefinePlugin({
			"BASE_URL": "'./'"
		})
	]
}
  • CleanWebpackPlugin
  • HtmlWebpackPlugin
  • DefinePlugin

4.8 mode配置

选项描述
development会将DefinePluginprocess.env.NODE_ENV的值设为development,为模块和chunk启用有效的名
production会将DefinePluginprocess.env.NODE_ENV的值设为production,为模块和chunk启用确定性的混淆名
none不使用任何默认优化选项

五、webpack开启本地服务器

  1. npm i webpack-dev-server -D
  2. package.json的scripts添加一行命令"serve:webpack serve"

六、HMR(模块热替换)

什么是HMR

  • 全程Hot Module Replace
  • 指在应用程序的运行过程中,替换添加删除模块,而无需重新刷新整个页面

开启HMR

devServer.hot设置为true,但是仍然会重新刷新整个页面,因为需要指定哪一个模块需要HMR

jsx
if (module.hot) {
	module.hot.accept("./utils/math.js")
}

devServer配置

jsx
module.exports = {
	devServer: {
		hot: true,
		port: 8888,
		host: "0.0.0.0",
		open: true,
		compress: true
	}
}

七、如何区分开发环境

  1. 创建代表不同环境的文件
    1. webpack.dev.js
    2. webpack.prod.js
  2. 根据不同配置文件编写不同的执行脚本
json
{
	scripts: {
		"dev": "webpack --config webpack.dev.js",
		"prod": "webpack --config webpack.prod.js"
	}
}
  1. 编写不同环境的配置
    1. 抽取公共配置webpack.base.js
      1. npm i webpack-merge -D
jsx
const { merge } = require('webpack-merge')
const baseConfig = require('./config.base')
const devConfig = require('./config.dev')

module.exports = merge(baseConfig, devConfig)