一、处理图标资源
1.1 下载字体图标文件
-
选择想要的图标添加到购物车,统一下载到本地。
1.2 添加字体图标资源
👉 src/fonts/iconfont.ttf
👉 src/fonts/iconfont.woff
👉 src/fonts/iconfont.woff2
👉 src/css/iconfont.css
👉 src/main.js
javascript
import { add } from "./math";
import count from "./js/count";
import sum from "./js/sum";
// 引入资源,Webpack才会对其打包
import "./css/iconfont.css";
import "./css/index.css";
import "./less/index.less";
import "./sass/index.sass";
import "./sass/index.scss";
import "./styl/index.styl";
console.log(count(2, 1));
console.log(sum(1, 2, 3, 4));
👉 public/index.html
html
<!DOCTYPE html>
<html lang="en">
<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>webpack5</title>
</head>
<body>
<h1>Hello Webpack5</h1>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
<div class="box5"></div>
<!-- 使用字体图标 -->
<i class="iconfont icon-arrow-down"></i>
<i class="iconfont icon-ashbin"></i>
<i class="iconfont icon-browse"></i>
<script src="../dist/static/js/main.js"></script>
</body>
</html>
1.3 配置
javascript
const path = require("path");
module.exports = {
// 入口【相对路径】
entry: './src/main.js',
// 输出
output: {
// 文件的输出路径【绝对路径】
// __dirname 当前文件的文件夹的绝对路径
path: path.resolve(__dirname, 'dist'),
// 入口文件打包输出的文件名称
filename: 'static/js/main.js',
// 自动清空上次打包结果
// 原理:在打包前,将上述配置的path整个目录内容清空,再进行打包
clean: true,
},
// 加载器
module: {
rules: [
// loader 的配置
// css样式
{
test: /\.css$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
]
},
// less样式
{
test: /\.less$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
'less-loader',// 将less文件编译成css文件
]
},
// sass样式
{
test: /\.s[ac]ss$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
'sass-loader',// 将sass文件编译成css文件
]
},
// stylus样式
{
test: /\.styl$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
'stylus-loader',// 将Styl文件编译成css文件
]
},
// 图片
{
test: /\.(png|jpe?g|gif|webp|svg)$/,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于10kb的图片会转成base64
// 优点:减少请求数量;缺点:体积会变大
maxSize: 10 * 1024
}
},
generator: {
// 输出图片的名称
/*
static/images/: 指定了输出文件的基础目录为 static/images/
[hash:10]: hash值取10位
[ext]: 保留原文件的扩展名
[query]: 保留原文件的查询字符串部分
*/
filename: "static/iamges/[hash:10][ext][query]"
}
},
// 字体图标
{
test: /\.(ttf|woff2?)$/,
type: "asset/resource",
generator: {
// 输出名称
filename: "static/media/[hash:10][ext][query]"
}
}
]
},
// 插件
plugins: [
// plugin的配置
],
/*
模式:
开发模式:development
生产模式:production
*/
mode: "development"
}
type: "asset/resource"
和type: "asset"
的区别:
type: "asset/resource"
相当于file-loader
, 将文件转化成 Webpack 能识别的资源,其他不做处理。
type: "asset"
相当于url-loader
, 将文件转化成 Webpack 能识别的资源,同时小于某个大小的资源会处理成 data URI 形式。
1.4 运行指令
运行以下命令,执行完后,打开index.html页面查看效果。
javascript
npx webpack
二、处理其他资源
2.1 配置
注意:就是在处理字体图标资源基础上增加其他文件类型,统一处理即可。
javascript
const path = require("path");
module.exports = {
// 入口【相对路径】
entry: './src/main.js',
// 输出
output: {
// 文件的输出路径【绝对路径】
// __dirname 当前文件的文件夹的绝对路径
path: path.resolve(__dirname, 'dist'),
// 入口文件打包输出的文件名称
filename: 'static/js/main.js',
// 自动清空上次打包结果
// 原理:在打包前,将上述配置的path整个目录内容清空,再进行打包
clean: true,
},
// 加载器
module: {
rules: [
// loader 的配置
// css样式
{
test: /\.css$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
]
},
// less样式
{
test: /\.less$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
'less-loader',// 将less文件编译成css文件
]
},
// sass样式
{
test: /\.s[ac]ss$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
'sass-loader',// 将sass文件编译成css文件
]
},
// stylus样式
{
test: /\.styl$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
'stylus-loader',// 将Styl文件编译成css文件
]
},
// 图片
{
test: /\.(png|jpe?g|gif|webp|svg)$/,
type: 'asset',//会转换为base64
parser: {
dataUrlCondition: {
// 小于10kb的图片会转成base64
// 优点:减少请求数量;缺点:体积会变大
maxSize: 10 * 1024
}
},
generator: {
// 输出图片的名称
/*
static/images/: 指定了输出文件的基础目录为 static/images/
[hash:10]: hash值取10位
[ext]: 保留原文件的扩展名
[query]: 保留原文件的查询字符串部分
*/
filename: "static/iamges/[hash:10][ext][query]"
}
},
// 字体图标或其他文件
{
test: /\.(ttf|woff2?|mp3|,p4|avi)$/,
type: "asset/resource",//不会转base64
generator: {
// 输出名称
filename: "static/media/[hash:10][ext][query]"
}
}
]
},
// 插件
plugins: [
// plugin的配置
],
/*
模式:
开发模式:development
生产模式:production
*/
mode: "development"
}
2.2 运行指令
运行以下指令,执行完毕后,打开index.html页面查看效果。
javascript
npx webpack
三、处理js资源
js 资源 Webpack 不能已经处理了吗,为什么我们还要处理呢?
原因是 Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法,导致 js 不能在 IE 等浏览器运行,所以我们希望做一些兼容性处理。
其次开发中,团队对代码格式是有严格要求的,我们不能由肉眼去检测代码格式,需要使用专业的工具来检测。
-
针对 js 兼容性处理,我们使用 Babel 来完成。
-
针对代码格式,我们使用 Eslint 来完成。
我们先完成 Eslint,检测代码格式无误后,在由 Babel 做代码兼容性处理。
3.1 Eslint
官网:配置 ESLint - ESLint - 插件化的 JavaScript 代码检查工具https://zh-hans.eslint.org/docs/latest/use/configure/
Eslint:可组装的 JavaScript 和 JSX检查工具。
这句话意思就是:它是用来检测 js 和 jsx 语法的工具,可以配置各项功能。
我们使用 Eslint,关键是写 Eslint 配置文件,里面写上各种 rules 规则,将来运行 Eslint 时就会以写的规则对代码进行检查。
3.1.1 配置文件
配置文件有很多种写法:
- .eslintrc.*:新建文件,位于项目根目录,以下文件的区别在于配置格式不一样。
- .eslintrc
- .eslintrc.js
- .eslintrv.json
- package.json 中 eslintConfig:不需要创建文件,在原有文件基础上写。
Eslint会自动查找和读取它们,所以以上配置文件只需要存在一个即可。
3.1.2 具体配置
以.eslintrc.js为例
javascript
module.exports = {
// 解析选项
parserOptions: {},
// 具体检查规则
rules: {},
// 继承其他规则
extends: [],
// ...
// 其他规则详见:https://zh-hans.eslint.org/docs/latest/use/configure/
};
👉 parserOptions解析选项
javascript
parserOptions: {
ecmaVersion: 6, // ES 语法版本
sourceType: "module", // ES 模块化
ecmaFeatures: { // ES 其他特性
jsx: true // 如果是 React 项目,就需要开启 jsx 语法
}
}
👉 rules具体规则【最重要】
-
"off"
或0
- 关闭规则 -
"warn"
或1
- 开启规则,使用警告级别的错误:warn
(不会导致程序退出) -
"error"
或2
- 开启规则,使用错误级别的错误:error
(当被触发的时候,程序会退出)
javascript
rules: {
semi: "error", // 禁止使用分号
// 强制数组方法的回调函数中有 return 语句,否则警告
'array-callback-return': 'warn',
'default-case': [
// 要求 switch 语句中有 default 分支,否则警告
'warn',
// 允许在最后注释 no default, 就不会有警告了
{ commentPattern: '^no default$' }
],
eqeqeq: [
// 强制使用 === 和 !==,否则警告
'warn',
// https://eslint.bootcss.com/docs/rules/eqeqeq#smart 除了少数情况下不会有警告
'smart'
],
}
更多规则详见:规则参考 - ESLint 中文网 (nodejs.cn)https://eslint.nodejs.cn/docs/latest/rules/ 👉 extends继承
开发中一点点写 rules 规则太费劲了,所以有更好的办法,继承现有的规则。
现有以下较为有名的规则:
-
Eslint官网的规则:
eslint:recommended
-
Vue Cli官方的规则:
plugin:vue/essential
-
React Cli 官方的规则:
react-app
javascript
// 例如在React项目中,我们可以这样写配置
module.exports = {
extends: ["react-app"],
rules: {
// 我们的规则会覆盖掉react-app的规则
// 所以想要修改规则直接改就是了
eqeqeq: ["warn", "smart"],
},
};
3.1.3 在webpack中使用
-
下载包:
javascriptyarn add eslint-webpack-plugin eslint -D
-
定义Eslint配置文件
javascript// .eslintrc.js module.exports = { // 继承 Eslint 规则 extends: ["eslint:recommended"], env: { node: true, // 启用node中全局变量 browser: true, // 启用浏览器中全局变量 }, parserOptions: { ecmaVersion: 6, sourceType: "module", }, rules: { "no-var": 2, // 不能使用 var 定义变量 }, };
-
修改main.js文件代码
javascript// 主文件(入口文件) import count from "./js/count"; import sum from "./js/sum"; import './css/iconfont.css' import './css/index.css' import './less/index.less' import './sass/index.sass' import './sass/index.scss' import './stylus/index.styl' // eslint校验会说此处有问题,不让使用var定义变量 var result = count(2, 1) console.log(result); console.log(sum(1, 2, 3, 4));
-
配置webpack.config.js
javascriptconst ESLintPlugin = require("eslint-webpack-plugin"); const path = require("path"); module.exports = { // 入口【相对路径】 entry: './src/main.js', // 输出 output: { // 文件的输出路径【绝对路径】 // __dirname 当前文件的文件夹的绝对路径 path: path.resolve(__dirname, 'dist'), // 入口文件打包输出的文件名称 filename: 'static/js/main.js', // 自动清空上次打包结果 // 原理:在打包前,将上述配置的path整个目录内容清空,再进行打包 clean: true, }, // 加载器 module: { rules: [ // loader 的配置 // css样式 { test: /\.css$/i,// 只检测.css文件 use: [// 执行顺序:从右到左,从下到上 'style-loader',// 将js中css通过创建style标签添加到html文件中生效 'css-loader',// 将css资源编译成commonjs的模块到js中 ] }, // less样式 { test: /\.less$/i,// 只检测.css文件 use: [// 执行顺序:从右到左,从下到上 'style-loader',// 将js中css通过创建style标签添加到html文件中生效 'css-loader',// 将css资源编译成commonjs的模块到js中 'less-loader',// 将less文件编译成css文件 ] }, // sass样式 { test: /\.s[ac]ss$/i,// 只检测.css文件 use: [// 执行顺序:从右到左,从下到上 'style-loader',// 将js中css通过创建style标签添加到html文件中生效 'css-loader',// 将css资源编译成commonjs的模块到js中 'sass-loader',// 将sass文件编译成css文件 ] }, // stylus样式 { test: /\.styl$/i,// 只检测.css文件 use: [// 执行顺序:从右到左,从下到上 'style-loader',// 将js中css通过创建style标签添加到html文件中生效 'css-loader',// 将css资源编译成commonjs的模块到js中 'stylus-loader',// 将Styl文件编译成css文件 ] }, // 图片 { test: /\.(png|jpe?g|gif|webp|svg)$/, type: 'asset',//会转换为base64 parser: { dataUrlCondition: { // 小于10kb的图片会转成base64 // 优点:减少请求数量;缺点:体积会变大 maxSize: 10 * 1024 } }, generator: { // 输出图片的名称 /* static/images/: 指定了输出文件的基础目录为 static/images/ [hash:10]: hash值取10位 [ext]: 保留原文件的扩展名 [query]: 保留原文件的查询字符串部分 */ filename: "static/iamges/[hash:10][ext][query]" } }, // 字体图标或其他文件 { test: /\.(ttf|woff2?|mp3|,p4|avi)$/, type: "asset/resource",//不会转base64 generator: { // 输出名称 filename: "static/media/[hash:10][ext][query]" } } ] }, // 插件 plugins: [ // plugin的配置 new ESLintPlugin({ // 哪些文件需要检查:检测src文件夹下的文件 context: path.resolve(__dirname, 'src') }) ], /* 模式: 开发模式:development 生产模式:production */ mode: "development" }
-
运行命令
javascriptnpx webpack
运行以上命令,并在控制台查看Eslint检查结果
3.1.4 VSCode Eslint插件
打开 VSCode,下载Eslint插件,即可不用编译就能看到错误,可以提前解决。但是此时就会对项目所有文件默认进行Eslint检查了,我们dist目录下的打包文件就会报错。但是我们只需要检查src下面的文件,不需要检查dist目录下的文件。
所以可以使用Eslint忽略文件来解决,在项目根目录新建下面文件:
.eslintignore
javascript
# 忽略dist目录下所有文件
dist
3.2 Babel
babel是一个JavaScript编译器
主要用于将ES6语法编写的代码转换为向后兼容的JavaScript语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
3.2.1 配置文件有很多种写法
-
babel.config.*:新建文件,位于项目根目录
-
babel.config.js
-
babel.config.json
-
-
.babelrc.*:新建文件,位于项目根目录
-
.babelrc
-
.babelrc.js
-
.babelrc.json
-
-
package.json
中babel
:不需要创建文件,在原有文件基础上写
Babel 会查找和自动读取它们,所以以上配置文件只需要存在一个即可。
3.2.2 具体配置
以 babel.config.js
配置文件为例:
javascript
module.exports = {
// 预设
presets: [],
};
presets 预设
简单理解:就是一组 Babel 插件, 扩展 Babel 功能
-
@babel/preset-env
: 一个智能预设,允许您使用最新的 JavaScript。 -
@babel/preset-react
:一个用来编译 React jsx 语法的预设 -
@babel/preset-typescript
:一个用来编译 TypeScript 语法的预设
3.2.3 在webpack中使用
-
下载包:
javascriptyarn add -D babel-loader @babel/core @babel/preset-env
-
定义Babel配置文件:babel.config.js
javascriptmodule.exports = { presets: ["@babel/preset-env"], };
-
修改main.js文件代码
javascriptimport count from "./js/count"; import sum from "./js/sum"; // 引入资源,Webpack才会对其打包 import "./css/iconfont.css"; import "./css/index.css"; import "./less/index.less"; import "./sass/index.sass"; import "./sass/index.scss"; import "./styl/index.styl"; const result1 = count(2, 1); console.log(result1); const result2 = sum(1, 2, 3, 4); console.log(result2);
-
配置:webpack.config.js
javascriptconst ESLintPlugin = require("eslint-webpack-plugin"); const path = require("path"); module.exports = { // 入口【相对路径】 entry: './src/main.js', // 输出 output: { // 文件的输出路径【绝对路径】 // __dirname 当前文件的文件夹的绝对路径 path: path.resolve(__dirname, 'dist'), // 入口文件打包输出的文件名称 filename: 'static/js/main.js', // 自动清空上次打包结果 // 原理:在打包前,将上述配置的path整个目录内容清空,再进行打包 clean: true, }, // 加载器 module: { rules: [ // loader 的配置 // css样式 { test: /\.css$/i,// 只检测.css文件 use: [// 执行顺序:从右到左,从下到上 'style-loader',// 将js中css通过创建style标签添加到html文件中生效 'css-loader',// 将css资源编译成commonjs的模块到js中 ] }, // less样式 { test: /\.less$/i,// 只检测.css文件 use: [// 执行顺序:从右到左,从下到上 'style-loader',// 将js中css通过创建style标签添加到html文件中生效 'css-loader',// 将css资源编译成commonjs的模块到js中 'less-loader',// 将less文件编译成css文件 ] }, // sass样式 { test: /\.s[ac]ss$/i,// 只检测.css文件 use: [// 执行顺序:从右到左,从下到上 'style-loader',// 将js中css通过创建style标签添加到html文件中生效 'css-loader',// 将css资源编译成commonjs的模块到js中 'sass-loader',// 将sass文件编译成css文件 ] }, // stylus样式 { test: /\.styl$/i,// 只检测.css文件 use: [// 执行顺序:从右到左,从下到上 'style-loader',// 将js中css通过创建style标签添加到html文件中生效 'css-loader',// 将css资源编译成commonjs的模块到js中 'stylus-loader',// 将Styl文件编译成css文件 ] }, // 图片 { test: /\.(png|jpe?g|gif|webp|svg)$/, type: 'asset',//会转换为base64 parser: { dataUrlCondition: { // 小于10kb的图片会转成base64 // 优点:减少请求数量;缺点:体积会变大 maxSize: 10 * 1024 } }, generator: { // 输出图片的名称 /* static/images/: 指定了输出文件的基础目录为 static/images/ [hash:10]: hash值取10位 [ext]: 保留原文件的扩展名 [query]: 保留原文件的查询字符串部分 */ filename: "static/iamges/[hash:10][ext][query]" } }, // 字体图标或其他文件 { test: /\.(ttf|woff2?|mp3|,p4|avi)$/, type: "asset/resource",//不会转base64 generator: { // 输出名称 filename: "static/media/[hash:10][ext][query]" } }, // babel { test: /\.js$/, exclude: /(node_modules)/,// 排除node_modules下的js文件不进行处理 use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], }, }, }, ] }, // 插件 plugins: [ // plugin的配置 new ESLintPlugin({ // 哪些文件需要检查:检测src文件夹下的文件 context: path.resolve(__dirname, 'src') }) ], /* 模式: 开发模式:development 生产模式:production */ mode: "development" }
-
运行指令
javascriptnpx webpack
四、处理html资源
4.1 下载包
javascript
yarn add html-webpack-plugin -D
4.2 配置 --- webpack.config.js
javascript
const ESLintPlugin = require("eslint-webpack-plugin");
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 入口【相对路径】
entry: './src/main.js',
// 输出
output: {
// 文件的输出路径【绝对路径】
// __dirname 当前文件的文件夹的绝对路径
path: path.resolve(__dirname, 'dist'),
// 入口文件打包输出的文件名称
filename: 'static/js/main.js',
// 自动清空上次打包结果
// 原理:在打包前,将上述配置的path整个目录内容清空,再进行打包
clean: true,
},
// 加载器
module: {
rules: [
// loader 的配置
// css样式
{
test: /\.css$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
]
},
// less样式
{
test: /\.less$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
'less-loader',// 将less文件编译成css文件
]
},
// sass样式
{
test: /\.s[ac]ss$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
'sass-loader',// 将sass文件编译成css文件
]
},
// stylus样式
{
test: /\.styl$/i,// 只检测.css文件
use: [// 执行顺序:从右到左,从下到上
'style-loader',// 将js中css通过创建style标签添加到html文件中生效
'css-loader',// 将css资源编译成commonjs的模块到js中
'stylus-loader',// 将Styl文件编译成css文件
]
},
// 图片
{
test: /\.(png|jpe?g|gif|webp|svg)$/,
type: 'asset',//会转换为base64
parser: {
dataUrlCondition: {
// 小于10kb的图片会转成base64
// 优点:减少请求数量;缺点:体积会变大
maxSize: 10 * 1024
}
},
generator: {
// 输出图片的名称
/*
static/images/: 指定了输出文件的基础目录为 static/images/
[hash:10]: hash值取10位
[ext]: 保留原文件的扩展名
[query]: 保留原文件的查询字符串部分
*/
filename: "static/iamges/[hash:10][ext][query]"
}
},
// 字体图标或其他文件
{
test: /\.(ttf|woff2?|mp3|,p4|avi)$/,
type: "asset/resource",//不会转base64
generator: {
// 输出名称
filename: "static/media/[hash:10][ext][query]"
}
},
// babel
{
test: /\.js$/,
exclude: /(node_modules)/,// 排除node_modules下的js文件不进行处理
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
]
},
// 插件
plugins: [
// plugin的配置
new ESLintPlugin({
// 哪些文件需要检查:检测src文件夹下的文件
context: path.resolve(__dirname, 'src')
}),
// 该插件将为你生成一个 HTML5 文件, 在 body 中使用 script 标签引入你所有 webpack 生成的 bundle。
new HtmlWebpackPlugin({
// 模板:以public/index.html文件为模板来生成新的html文件
/*
新的html文件有两个特点:
1.结构和原来一致【模板代码结构】
2.自动引入打包的资源
*/
template: path.resolve(__dirname, 'public/index.html')
})
],
/*
模式:
开发模式:development
生产模式:production
*/
mode: "development"
}
4.3 修改index.html
去掉引入的 js 文件,因为 HtmlWebpackPlugin 会自动引入。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" >
<title>Document</title>
</head>
<body>
<h1>hello webpack</h1>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
<div class="box5"></div>
<i class="iconfont icon-browse"></i>
<!-- 手动引入的js不需要了,通过插件自动引入 -->
<!-- <script src="../dist/static/js/main.js"></script> -->
</body>
</html>
4.4 运行指令
运行以下指令,此时dist目录就会输出一个index.html文件
html
npx webpack