webpack5 基础配置
Posted 奥特曼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack5 基础配置相关的知识,希望对你有一定的参考价值。
在开发中,我们会使用 vue、react、less、scss等语法进行开发项目,但是浏览器只能识别 js、css,或者说在js中使用了es6中的import 导入 这时候也需要打包工具去转换成浏览器可以识别的语句。
一、使用webpack
1.初始化package.json
npm init -y
注意生成的package.json 中的name不要叫插件名称 否则下载不了。
2.下载依赖
npm i webpack webpack-cli -D
3. 启用webpack
开发模式
npx webpack ./src/main.js --mode=development
生产模式
npx webpack ./src/main.js --mode=production
当然 你也需要新建一个 src/main.js的文件
npx webpack 是用来运行本地安装 Webpack
包的。
./src/main.js
: 指定 Webpack
从 main.js
文件开始打包,不但会打包 main.js
,还会将其依赖也一起打包进来。
--mode=xxx
:指定模式(环境)
4. 查看输出文件
默认输出到dist文件下。
二、基础配置
(1)5大核心概念
1. entry(入口):指示 Webpack 从哪个文件开始打包
2. output(输出):指示 Webpack 打包完的文件输出到哪里去,如何命名等
3. loader(加载器):webpack 本身只能处理 js、json 等资源,其他资源需要借助 loader,Webpack 才能解析
4. plugins(插件):扩展 Webpack 的功能
5. mode(模式)主要由两种模式:开发模式:development、生产模式:production
根目录新建 webpack.config.js
module.exports =
// 入口
entry: "",
// 输出
output: ,
// 加载器
module:
rules: [],
,
// 插件
plugins: [],
// 模式
mode: "",
;
修改配置文件
// Node.js的核心模块,专门用来处理文件路径
const path = require("path");
module.exports =
// 入口
// 相对路径和绝对路径都行
entry: "./src/main.js",
// 输出
output:
// path: 文件输出目录,必须是绝对路径
// path.resolve()方法返回一个绝对路径
// __dirname 当前文件的文件夹绝对路径
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "main.js",
,
// 加载器
module:
rules: [],
,
// 插件
plugins: [],
// 模式
mode: "development", // 开发模式 生产模式:production
;
有了入口和模式的配置 直接运行 即可
npx webpack
(2) 处理样式资源
1. 处理css资源
因为我们是将css引入到入口文件里面,一般情况下js是不能识别css 的所以我们要对css进行处理。
npm i css-loader style-loader -D
css-loader
:负责将 Css 文件编译成 Webpack 能识别的模块style-loader
:会动态创建一个 Style 标签,里面放置 Webpack 中 Css 模块内容
此时样式就会以 Style 标签的形式在页面上生效
webpack.config.js
module:
rules: [
// 用来匹配 .css 结尾的文件
test: /\\.css$/,
// use 数组里面 Loader 执行顺序是从右到左
use: ["style-loader", "css-loader"],
,
],
,
src/main.js
import './css/index.css'
src/css/index.css
.box
width: 200px;
height: 200px;
background: skyblue;
public/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script src="../dist/main.js"></script>
<body>
<div class="box"></div>
</body>
</html>
注意 html 引入的是打包后的文件
npx webpack
2.处理less资源
npm i less-loader -D
webpack.config.js
rules: [
...
test: /\\.less$/,
use: ["style-loader", "css-loader", "less-loader"],
,
],
src/main.js
import './css/index.css'
import './less/index.less'
当然像scss/sass、Stylus 也是相同的配置方法 具体可参考webpack官网
3. 处理图片资源
新增两张图片
src/images/2kb.png
src/images/avatar.png
使用进行打包,会默认在dist目录下 生成一个带有hash的图片名称,也并没有产生一个本地资源的目录,如果需要则需另外配置。
因为有一张图片是2kb的,每次访问都需要去进行请求资源,我们可以把小于 xx 之内的图片进行转换base64处理。
// 加载器
module:
rules: [
test: /\\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser:
dataUrlCondition:
maxSize: 10 * 1024, // 小于10kb的图片会被base64处理
,
,
,
],
这时候dist文件下 只会产生一个图片资源,另一个已被处理成base64资源。
4.修改输出资源的名称和路径
当然我们希望打包后的js在一个文件中,本地资源又在另一个文件中。
output:
path: path.resolve(__dirname, "dist"),
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
,
// 加载器
module:
rules: [
test: /\\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser:
dataUrlCondition:
maxSize: 10 * 1024, // 小于10kb的图片会被base64处理
,
,
generator:
// 将图片文件输出到 static/imgs 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: "static/imgs/[hash:8][ext][query]",
,
,,
,
],
打包结果:
5. 清空上次打包资源
若不做当前处理,如果有相同会默认替换,如有更新会自动新增不删除原来打包文件。
output:
path: path.resolve(__dirname, "dist"),
filename: "static/js/main.js",
+ clean: true, // 自动将上次打包目录资源清空
,
6. 处理字体图标
资源文件 可去iconfont-阿里巴巴矢量图标库进行下载
-
src/fonts/iconfont.ttf
-
src/fonts/iconfont.woff
-
src/fonts/iconfont.woff2
-
src/css/iconfont.css
import './css/index.css'
import './less/index.less'
+ import './css/iconfont.css'
module:
rules: [
test: /\\.(ttf|woff2?)$/,
type: "asset/resource",
generator:
filename: "static/media/[hash:8][ext][query]",
,
,
]
type: "asset/resource"
和type: "asset"
的区别:
type: "asset/resource"
相当于file-loader
, 将文件转化成 Webpack 能识别的资源,其他不做处理type: "asset"
相当于url-loader
, 将文件转化成 Webpack 能识别的资源,同时小于某个大小的资源会处理成 data URI 形式- 如果还有其他文件类型需要处理 可以在test正则中继续添加 |mp3|mp4|avi
7. eslint配置
eslint 就是检测我们各种语法规范的,让不规范的代码进行提示
根目录新建 .eslintrc.js
module.exports =
// 解析选项
parserOptions: ,
// 具体检查规则
rules: ,
// 继承其他规则
extends: [],
// ...
// 其他规则详见:https://eslint.bootcss.com/docs/user-guide/configuring
;
1. parserOptions 解析选项
parserOptions:
ecmaVersion: 6, // ES 语法版本
sourceType: "module", // ES 模块化
ecmaFeatures: // ES 其他特性
jsx: true // 如果是 React 项目,就需要开启 jsx 语法
2. rules 具体规则
"off"
或0
- 关闭规则"warn"
或1
- 开启规则,使用警告级别的错误:warn
(不会导致程序退出)"error"
或2
- 开启规则,使用错误级别的错误:error
(当被触发的时候,程序会退出)
rules:
semi: "error", // 禁止使用分号
'array-callback-return': 'warn', // 强制数组方法的回调函数中有 return 语句,否则警告
'default-case': [
'warn', // 要求 switch 语句中有 default 分支,否则警告
commentPattern: '^no default$' // 允许在最后注释 no default, 就不会有警告了
],
eqeqeq: [
'warn', // 强制使用 === 和 !==,否则警告
'smart' // https://eslint.bootcss.com/docs/rules/eqeqeq#smart 除了少数情况下不会有警告
],
3. extends 继承
开发中一点点写 rules 规则太费劲了,所以有更好的办法,继承现有的规则。
现有以下较为有名的规则:
// 例如在React项目中,我们可以这样写配置
module.exports =
extends: ["react-app"],
rules:
// 我们的规则会覆盖掉react-app的规则
// 所以想要修改规则直接改就是了
eqeqeq: ["warn", "smart"],
,
;
在webpack中使用
npm i eslint-webpack-plugin eslint -D
- .eslintrc.js
module.exports =
// 继承 Eslint 规则
extends: ["eslint:recommended"],
env:
node: true, // 启用node中全局变量
browser: true, // 启用浏览器中全局变量
,
parserOptions:
ecmaVersion: 6,
sourceType: "module",
,
rules:
"no-var": 2, // 不能使用 var 定义变量
,
;
webpack.config.js
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
module.exports =
plugins: [
new ESLintWebpackPlugin(
// 指定检查文件的根目录
context: path.resolve(__dirname, "src"),
),
],
这时候如果你在编辑器中安装了eslint插件 在src目录下写一个带有var声明变量的代码就会提示,如果没下载则打包编译时会有报错提示。
8. 忽略eslint文件检查
在上面我们值配置了src目录下,但是装在编译器的eslint插件并不知道,所以他也是全局进行检查,例如我们打包生成后的文件就会标红,所以过滤掉dist目录。
根目录新建.eslintignore
# 忽略dist目录下所有文件
dist
9.Babel
npm i babel-loader @babel/core @babel/preset-env -D
定义 Babel 配置文件
module:
test: /\\.js$/,
// 排斥哪些文件
exclude: /node_modules/,
loader: 'babel-loader',
options:
presets: ['@babel/preset-env']
],
,
当然如果配置项够多也可以提取options
babel.config.js
module.exports =
// 智能预设
presets: ['@babel/preset-env']
10.处理 Html 资源
html为什么需要打包呢,本身不就html吗 ?
这个html 是打包后的html 并且呢 他会引入打包后的js资源,内容也是和源文件一样的。
npm i html-webpack-plugin -D
webpack.config.js
plugins: [
new HtmlWebpackPlugin(
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "public/index.html"),
),
],
若new HtmlWebpackPlugin 中不写指定文件则只会引入js文件 不会生成相同的dom元素
11. 服务器自动化webpack-dev-server
每次都需要手动去刷新文件才去自动更新 webpack-dev-server就可以在本地服务器开启一个端口号,进行自动化更新
npm i webpack-dev-server -D
module.exports =
// 开发服务器
devServer:
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
npx webpack serve
当然也可以配置package.json使用npm run 运行
"scripts":
"dev": "webpack server",
"build": "webpack",
,
就可以使用
npm run dev
npm run build
12.Css 优化处理
提取 Css 成单独文件
Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式
这样对于网站来说,会出现闪屏现象,用户体验不好
我们应该是单独的 Css 文件,通过 link 标签加载性能才好
npm i mini-css-extract-plugin -D
webpack.config.js
将之前在module rules配置的 所有样式的"style-loader" 改成MiniCssExtractPlugin.loader
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports =
module:
rules: [
// 用来匹配 .css 结尾的文件
test: /\\.css$/,
// use 数组里面 Loader 执行顺序是从右到左
use: [MiniCssExtractPlugin.loader, "css-loader"],
,
test: /\\.less$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
,
]
13.css兼容性处理
例如在一些网站中使用-webkit- 等其他前缀对浏览器进行兼容。下面插件就是对css样式自动配置
npm i postcss-loader postcss postcss-preset-env -D
放到"css-loader"下面
loader: "postcss-loader",
options:
postcssOptions:
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
,
,
,
// 插件
plugins: [
// 提取css成单独文件
new MiniCssExtractPlugin(
// 定义输出文件名和目录
filename: "static/css/main.css",
),
],
当然 如果过多可以封装成函数进行return 返回出去,基本上在开发中也不会引入多个css样式处理语言。
我们可以在 package.json
文件中添加 browserslist
来控制样式的兼容性做到什么程度。
// 其他省略
"browserslist": ["ie >= 8"]
实际开发中我们一般不考虑旧版本浏览器了,所以我们可以这样设置:
// 其他省略
"browserslist": ["last 2 version", "> 1%", "not dead"]
14. 压缩css
npm install css-minimizer-webpack-plugin --save-dev
webpack.config.js
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports =
// 插件
plugins: [
// css压缩
new CssMinimizerPlugin(),
],
css 会从多行变成一行,对于js和html 不需要进行压缩,对于生产环境下会自动压缩成一行。
15.HotModuleReplacement
在修改某个文件进行打包时并不希望他是全部更新的,我修改了哪些就应该更新哪些文件
module.exports =
//...
devServer:
hot: true,
,
;
此时 css 样式经过 style-loader 处理,已经具备 HMR 功能了。 但是 js 还不行。
JS 配置需要在main.js 入口文件中
// 判断是否支持HMR功能
if (module.hot)
module.hot.accept("./js/one.js");
// 第二个参数额外执行的事件
module.hot.accept("./js/sum.js", function (sum)
const result2 = sum(1, 2, 3, 4);
console.log(result2);
);
在开发中各种框架的loader已经配置好了。
16.OneOf
打包时每个文件都会经过所有 loader 处理,虽然因为 test
正则原因实际没有处理上,但是都要过一遍。比较慢。如果匹配上一个就不需要再次匹配了。
在rules新增 oneOf:[ ]
module:
rules: [
//新增对象
oneOf:[,...一堆loader]
]
17.Cache
每次打包时 js 文件都要经过 Eslint 检查 和 Babel 编译,速度比较慢。我们可以缓存之前的 Eslint 检查 和 Babel 编译结果,这样第二次打包时速度就会更快了。
module:
rules: [
test: /\\.js$/,
// 排斥哪些文件
exclude: /node_modules/,
loader: 'babel-loader',
options:
presets: ['@babel/preset-env'],
+ cacheDirectory: true, // 开启babel编译缓存
+ cacheCompression: false, // 缓存文件不要压缩
]
plugins: [
new ESLintWebpackPlugin(
// 指定检查文件的根目录
context: path.resolve(__dirname, "src"),
exclude: "node_modules", // 默认值
+ cache: true, // 开启缓存
+ // 缓存目录
cacheLocation: path.resolve( __dirname,"./node_modules/.cache/.eslintcache" ),
)
]
18.图片压缩
npm i image-minimizer-webpack-plugin imagemin -D
无损压缩
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D
有损压缩
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo -D
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.export =
optimization:
minimizer: [
// 压缩图片
new ImageMinimizerPlugin(
minimizer:
implementation: ImageMinimizerPlugin.imageminGenerate,
options:
plugins: [
["gifsicle", interlaced: true ],
["jpegtran", progressive: true ],
["optipng", optimizationLevel: 5 ],
[
"svgo",
plugins: [
"preset-default",
"prefixIds",
name: "sortAttrs",
params:
xmlnsOrder: "alphabetical",
,
,
],
,
],
],
,
,
),
]
,
只有在生产模式下打包是生效的。当批量图片压缩是比较方便,也可以手动找网站进行压缩。
当然webpack配置还有很多 可自行参考webpack官网。
以上是关于webpack5 基础配置的主要内容,如果未能解决你的问题,请参考以下文章
微前端之 Webpack5 的 module federation