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的打包流程
- 根据命令行或者配置文件找到入口文件
- 从入口开始,逐步形成依赖关系图,依赖关系图包含JavaScript应用程序的所有模块(比如JavaScript文件,css文件、图片、字体等)
- 遍历依赖关系图,打包一个个模块(根据不同的文件使用不同的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
- babel-loader
- 处理.vue文件
- vue-loader
- VueLoaderPlugin(插件,必须使用)
- vue-loader
4.5 resolve模块解析
- 确定文件还是文件夹
- 如果是一个文件
- 文件具有扩展名,则直接打包文件
- 否则,使用
resolve.extensions
选项作为文件扩展名解析
- 如果是一个文件夹
- 会在文件夹中根据
resolve.mainFiles
配置选项中的文件顺序查找resolve.mainFiles
的默认值是['index']
- 再根据
resolve.extensions
来解析扩展名
- 会在文件夹中根据
resolve.extensions
默认值['.wasm', '.js', '.mjs', '.json']
- 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
- 可使用
output.clean
代替
- 可使用
HtmlWebpackPlugin
DefinePlugin
4.8 mode配置
选项 | 描述 |
---|---|
development | 会将DefinePlugin 中process.env.NODE_ENV 的值设为development,为模块和chunk启用有效的名 |
production | 会将DefinePlugin 中process.env.NODE_ENV 的值设为production,为模块和chunk启用确定性的混淆名 |
none | 不使用任何默认优化选项 |
五、webpack开启本地服务器
npm i webpack-dev-server -D
- 在
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
}
}
七、如何区分开发环境
- 创建代表不同环境的文件
webpack.dev.js
webpack.prod.js
- 根据不同配置文件编写不同的执行脚本
json
{
scripts: {
"dev": "webpack --config webpack.dev.js",
"prod": "webpack --config webpack.prod.js"
}
}
- 编写不同环境的配置
- 抽取公共配置
webpack.base.js
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)