自动清空上次打包的内容
配置如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/1a5eaf41a04941fdb883e56968fb7185.png)
处理其他资源
![在这里插入图片描述](https://img-blog.csdnimg.cn/356c1b657dbb42e4a3c8dc3cc11b7dc5.png)
处理js资源
原因: Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法,导致 js 不能在 IE 等浏览器运行,所以我们希望做一些兼容性处理。
其次开发中,团队对代码格式是有严格要求的,我们不能由肉眼去检测代码格式,需要使用专业的工具来检测。
- 针对 js 兼容性处理,我们使用 Babel 来完成
- 针对代码格式,我们使用 Eslint 来完成
我们先完成 Eslint,检测代码格式无误后,在由 Babel 做代码兼容性处理
Eslint
可组装的 JavaScript 和 JSX 检查工具。
这句话意思就是:它是用来检测 js 和 jsx 语法的工具,可以配置各项功能。
我们使用 Eslint,关键是写 Eslint 配置文件,里面写上各种 rules 规则,将来运行 Eslint 时就会以写的规则对代码进行检查
1. 配置文件
配置文件由很多种写法:
ESLint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
2 具体配置
我们以 .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 规则太费劲了,所以有更好的办法,继承现有的规则。
现有以下较为有名的规则:
ESLINT官方规则 : eslint:recommended
Vue Cli 官方规则 : plugin:vue/essential
React官方规则: react-app
// 例如在React项目中,我们可以这样写配置
module.exports = {
extends: ["react-app"],
rules: {
// 我们的规则会覆盖掉react-app的规则
// 所以想要修改规则直接改就是了
eqeqeq: ["warn", "smart"],
},
};
3.在webpack中使用
webpack官方文档
下载包
npm install eslint --save-dev
npm i eslint-webpack-plugin eslint -D
webpack.config.js配置
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
// ...
plugins: [new ESLintPlugin(options)],
// ...
};
![在这里插入图片描述](https://img-blog.csdnimg.cn/261997b548a146a5afdef49fe33183fe.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/4c38163695ad422e92a007983a88a3ad.png)
创建.eslintrc.js文件(注意前面有个点)
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 定义变量
},
};
记得安装eslint插件,这样开发的时候才有提示,不然只能等到编译的时候才报错
![在这里插入图片描述](https://img-blog.csdnimg.cn/070f1afd67404a46a9a7950748869438.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/ade5dd67f67f4cbbb53736be0544bce1.png)
4. Eslint插件
有时候,我们不想要eslint对某些文件进行语法检查,比如webpack打包生成的dist文件
解决方法:
创建.eslintignore文件(前面有个点)
![在这里插入图片描述](https://img-blog.csdnimg.cn/35413b6f37b0440d80059e0a67e6f699.png)
这样dist下的所有文件就不会报错了。
Babel
JavaScript 编译器。
主要用于将 ES6 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中
1.配置文件
配置文件由很多种写法:
Babel 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
2. 具体配置
我们以 babel.config.js 配置文件为例
module.exports = {
// 预设
presets: [],
};
presets 预设
简单理解:就是一组 Babel 插件, 扩展 Babel 功能
- @babel/preset-env: 一个智能预设,允许您使用最新的 JavaScript。
- @babel/preset-react:一个用来编译 React jsx 语法的预设
- @babel/preset-typescript:一个用来编译 TypeScript 语法的预设
3.在webpack中使用
1.下载
npm i babel-loader @babel/core @babel/preset-env -D
2.定义 Babel 配置文件
第一种
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/, // 不处理node_modules下的js文件
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
]
};
![在这里插入图片描述](https://img-blog.csdnimg.cn/62080790e8a246998b2f5e7cfc29f894.png)
第二种:
创建babel.config.js文件
![在这里插入图片描述](https://img-blog.csdnimg.cn/4070f59a84224ae683e7db6d56ac1382.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/83ced06eefe54a3a8ceb217164bd50b6.png)
处理html资源
之前存在一个问题,我们必须手动引入webpack打包后的js文件。比如:
![在这里插入图片描述](https://img-blog.csdnimg.cn/7fb58a96018b4821a20af8b7647e6e2c.png)
解决方法:
npm i html-webpack-plugin -D
配置webpacj.config.js文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: 'main.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js',
},
plugins: [ new HtmlWebpackPlugin({
// 模板:以public/index.html文件创建新的html文件
// 新的html文件特点:1、结构和原来一致 2、自动引入打包输出的资源
template: path.resolve(__dirname, "public/index.html"),
}),],
};
记得把原来手动引用的删除
![在这里插入图片描述](https://img-blog.csdnimg.cn/a1a11a7dd2c2497fb052ecdd23223c52.png)
打包结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/6e9f7dcc519543f8ae3b6f02488596ce.png)
开启自动化打包
每次更改代码后必须手动打包,不利于开发。
解决方法:
npm i webpack-dev-server -D
![在这里插入图片描述](https://img-blog.csdnimg.cn/bd6327919fa0486a866c3f25885fff4a.png)
const path = require("path");
const ESLintPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口,相对路径和绝对路径都可以
entry: "./src/main.js",
// 输出
output: {
path: path.resolve(__dirname, "./dist"),
// 入口文件打包输出文件名
filename: "static/js/main.js",
// 自动清空上次打包的内容
// 原理:在打包前,将path(上面那个)整个目录内容删除,然后再进行打包
clean: true,
},
// 记载器
module: {
rules: [
// loader的配置
{
test: /\.css/, // 只检测.css文件
use: [
// 执行顺序:从右到左
"style-loader", // 将js中的css通过创建style标签添加到html文件中生效
"css-loader", // 将css资源编译成commonjs模块到js中
],
},
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
"less-loader", // 将less编译成css文件
],
},
{
test: /\.(png|jpe?g|git|webp|svg)$/,
type: "asset",
parser: {
dataUrlCondition: {
// 这里配置小于20kb的图片就转为base64
// 优点:减少请求数量
// 缺点:体积会变大
maxSize: 20 * 1024,
},
},
generator: {
// 输出图片路径及名称
// [hash:10] hash值只取前10位
filename: "static/images/[hash:10][ext][query]",
},
},
{
// 处理字体、音频、视频等资源
test: /\.(tff|woff2?|map3|map4|avi)$/,
type: "asset/resource", // 不转换位base64
generator: {
filename: "static/media/[hash:10][ext][query]",
},
},
{
test: /\.js$/,
exclude: /node_modules/, // 不处理node_modules下的js文件
loader: "babel-loader",
// options: {
// presets: ["@babel/preset-env"],
// },
},
],
},
// 插件
plugins: [
new ESLintPlugin({
// 检测哪些文件
context: path.resolve(__dirname, "./src"),
}),
new HtmlWebpackPlugin({
// 模板:以public/index.html文件创建新的html文件
// 新的html文件特点:1、结构和原来一致 2、自动引入打包输出的资源
template: path.resolve(__dirname, "public/index.html"),
}),
],
// 开发服务器
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
},
// 模式
mode: "development",
};
开启命令:
npx webpack serve
![在这里插入图片描述](https://img-blog.csdnimg.cn/b7a3f0d53b56435da51aa418d385cb8d.png)
当你使用开发服务器时,所有代码都会在内存中编译打包,并不会输出到 dist 目录下。开发时我们只关心代码能运行,有效果即可,至于代码被编译成什么样子,我们并不需要知道。
生产模式介绍
生产模式是开发完成代码后,我们需要得到代码将来部署上线。这个模式下我们主要对代码进行优化,让其运行性能更好。
优化主要从两个角度出发:
生产模式准备
我们分别准备两个配置文件来放不同的配置
├── webpack-test (项目根目录)
├── config (Webpack配置文件目录)
│ ├── webpack.dev.js(开发模式配置文件)
│ └── webpack.prod.js(生产模式配置文件)
├── node_modules (下载包存放目录)
├── src (项目源码目录,除了html其他都在src里面)
│ └── 略
├── public (项目html文件)
│ └── index.html
├── .eslintrc.js(Eslint配置文件)
├── babel.config.js(Babel配置文件)
└── package.json (包的依赖管理配置文件)
![在这里插入图片描述](https://img-blog.csdnimg.cn/8dc36b99f1d94f19a5ca5947be3fd885.png)
开发模式 webpack.dev.js
const path = require("path");
const ESLintPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口,相对路径和绝对路径都可以
entry: "./src/main.js",
// 输出
output: {
// 开发模式没输出
path: undefined,
// 入口文件打包输出文件名
filename: "static/js/main.js",
// 自动清空上次打包的内容
// 原理:在打包前,将path(上面那个)整个目录内容删除,然后再进行打包
clean: true,
},
// 记载器
module: {
rules: [
// loader的配置
{
test: /\.css/, // 只检测.css文件
use: [
// 执行顺序:从右到左
"style-loader", // 将js中的css通过创建style标签添加到html文件中生效
"css-loader", // 将css资源编译成commonjs模块到js中
],
},
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
"less-loader", // 将less编译成css文件
],
},
{
test: /\.(png|jpe?g|git|webp|svg)$/,
type: "asset",
parser: {
dataUrlCondition: {
// 这里配置小于20kb的图片就转为base64
// 优点:减少请求数量
// 缺点:体积会变大
maxSize: 20 * 1024,
},
},
generator: {
// 输出图片路径及名称
// [hash:10] hash值只取前10位
filename: "static/images/[hash:10][ext][query]",
},
},
{
// 处理字体、音频、视频等资源
test: /\.(tff|woff2?|map3|map4|avi)$/,
type: "asset/resource", // 不转换位base64
generator: {
filename: "static/media/[hash:10][ext][query]",
},
},
{
test: /\.js$/,
exclude: /node_modules/, // 不处理node_modules下的js文件
loader: "babel-loader",
// options: {
// presets: ["@babel/preset-env"],
// },
},
],
},
// 插件
plugins: [
new ESLintPlugin({
// 检测哪些文件
context: path.resolve(__dirname, "../src"),
}),
new HtmlWebpackPlugin({
// 模板:以public/index.html文件创建新的html文件
// 新的html文件特点:1、结构和原来一致 2、自动引入打包输出的资源
template: path.resolve(__dirname, "../public/index.html"),
}),
],
// 开发服务器
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
},
// 模式
mode: "development",
};
启动命令:
npx webpack serve --config .\config\webpack.dev.js
生产模式webpack.prod.js
const path = require("path");
const ESLintPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口,相对路径和绝对路径都可以
entry: "./src/main.js",
// 输出
output: {
path: path.resolve(__dirname, "../dist"),
// 入口文件打包输出文件名
filename: "static/js/main.js",
// 自动清空上次打包的内容
// 原理:在打包前,将path(上面那个)整个目录内容删除,然后再进行打包
clean: true,
},
// 记载器
module: {
rules: [
// loader的配置
{
test: /\.css/, // 只检测.css文件
use: [
// 执行顺序:从右到左
"style-loader", // 将js中的css通过创建style标签添加到html文件中生效
"css-loader", // 将css资源编译成commonjs模块到js中
],
},
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
"less-loader", // 将less编译成css文件
],
},
{
test: /\.(png|jpe?g|git|webp|svg)$/,
type: "asset",
parser: {
dataUrlCondition: {
// 这里配置小于20kb的图片就转为base64
// 优点:减少请求数量
// 缺点:体积会变大
maxSize: 20 * 1024,
},
},
generator: {
// 输出图片路径及名称
// [hash:10] hash值只取前10位
filename: "static/images/[hash:10][ext][query]",
},
},
{
// 处理字体、音频、视频等资源
test: /\.(tff|woff2?|map3|map4|avi)$/,
type: "asset/resource", // 不转换位base64
generator: {
filename: "static/media/[hash:10][ext][query]",
},
},
{
test: /\.js$/,
exclude: /node_modules/, // 不处理node_modules下的js文件
loader: "babel-loader",
// options: {
// presets: ["@babel/preset-env"],
// },
},
],
},
// 插件
plugins: [
new ESLintPlugin({
// 检测哪些文件
context: path.resolve(__dirname, "../src"),
}),
new HtmlWebpackPlugin({
// 模板:以public/index.html文件创建新的html文件
// 新的html文件特点:1、结构和原来一致 2、自动引入打包输出的资源
template: path.resolve(__dirname, "../public/index.html"),
}),
],
// 生产模式不需要devServer
// 模式
mode: "production",
};
启动命令(跟开发模式不一样)
npx webpack --config .\config\webpack.prod.js
区别在是否生成了dist目录
![在这里插入图片描述](https://img-blog.csdnimg.cn/4c8fc40af8944a02ab37faefac18adff.png)
配置运行指令
为了方便运行不同模式的指令,我们将指令定义在 package.json 中 scripts 里面
修改package.json文件
// package.json
{
// 其他省略
"scripts": {
"start": "npm run dev",
"dev": "npx webpack serve --config ./config/webpack.dev.js",
"build": "npx webpack --config ./config/webpack.prod.js"
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/c738f1bf8f9c46d69ab33994abdf5e1b.png)
以后启动指令:
开发模式:npm start 或 npm run dev
生产模式:npm run build