引言
一直在听说 webpack,但一直也只是听说,前段时间刚好没事便学习了一下,今天离学习 webpack 有一小段时间了,刚好整理整理一些知识点,就当对之前学习的巩固与之后查阅更为方便
Webpack 入门篇包括了对使用 Webpack 的前置准备、Webpack 的基本介绍和 Webpack 基础配置的讲解
前置准备
依赖环境
在学习 Webpack 之前,需要将其需要的环境准备好,即 node
初始化项目
在安装完 node 之后,就可以初始化项目了。用自己喜欢的软件工具(IDEA 或者 VSCode)创建一个空文件夹,然后打开软件内的终端,初始化项目。以下命令二选一:
# 一步一步初始化
npm init
# 直接使用默认配置一次性初始化
npm init -y
为什么需要 Webpack
项目初始化完成了,便可以正式开始 Webpack 配置的学习了。但是为了能让后面的知识便于理解,所以这里也对 Webpack 做一些简单的介绍:
- 首先附上官网链接
- 其次Webpack 是用来处理 JavaScript 资源的
好了,到这,可能会有一些疑惑,JavaScript 资源还需要处理?
是的,JavaScript 是需要进行一定的加工处理,但这不是必须的,如果你的 js 代码很简单,就一个文件,完全不会存在这样的问题的。但是,当你的代码逻辑变得复杂,文件之间需要互相依赖,在这种需求下写出的代码,咱们的浏览器还能读的懂吗?还可以给你正常运行吗?答案是不行。还有便是 ES6 的一些语法糖,我们用起来是方便了,可是直接抛给浏览器它就傻了呀,不认识呀。所以,我们写的 js 代码在特定的情况下是需要被处理的,因此便诞生了 Webpack
到这,我们知道 Webpack 可以处理 JavaScript,也知道 JavaScript 需要被处理。那其他的资源呢?Webpack 可以处理吗?
答案是 Webpack 并不能直接处理其他的资源文件,它只能用来处理 JavaScript 资源,但是直接的不行,咱们可以配置呀,因此处理其它资源我们需要安装对应的处理器和插件
可能又会有疑问了,那为什么 Webpack 不把所有这些资源的处理都弄好?
额,这个我也不是很清楚,但是细想一下,每一个工具都有它的主要职责,js 资源使用量大,所以就以它为核心了吧,而对于其他的资源那就需要处理哪个就自己配置吧。让自己的项目能更轻便、灵活吧
基础配置
最开始我们已经初始化了一个空项目,现在因为要使用 Webpack,所以需要安装一下它的依赖
npm i -D webpack webpack-cli webpack-dev-server
安装好依赖之后就可以开始了, Webpack 配置是写在 webpack.config 配置文件的,位置可以随意,名字对了就行,使用时找到对应位置使用即可
# 打包,文件路径是配置的 output 输出文件的路径
npx webpack --config {webpack.config.js 路径}
# 运行
npx webpack serve --config {webpack.config.js 路径}
对于 Webpack 基础配置,只要掌握 5 大核心概念:entry、output、loader、plugins、mode 即可
entry
入口文件的配置,可以配置多个入口文件。下面是配置了 2 个入口文件的例子:
entry: {
app: "./src/app.js",
admin: "./src/admin.js",
}
output
这是与入口文件对应的输出文件的配置,一个入口文件只能对应一个输出文件。对于单入口文件,直接写明输出文件的输出位置即可:
output: {
path: path.resolve(__dirname, "dist"),
filename: "static/js/main.js",
}
对于多入口文件,则使用[name],它在输出文件名中是一个占位符,表示入口的名称
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
}
path.resolve,path 是 NodeJS 中的一个模块,专门用来处理路径的,resolve 是 path 模块下一个用来拼接路径的方法
loader
处理器的配置会与前面的入口文件和输出文件配置不同,因为它需要下载对应的处理器了。可以用处理器来处理样式资源、图片资源、字体图标资源、音视频资源
首先,应该知道 loader 配置的写法:
module: {
rules: [
{
test: /\.xxx$/,
use: 'xxx-loader'
}
],
}
样式资源
处理的样式资源有多种,包括:css、less、sass、scss、stylus。
下面直接列出处理各个样式资源的规则:
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.less$/i,
use: ["style-loader", "css-loader", "less-loader"],
},
{
test: /\.s[ac]ss$/i,
use: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.styl$/,
use: ["style-loader", "css-loader", "stylus-loader"],
},
当然,也是需要安装相应依赖的:
# css
npm i -D style-loader css-loader
# less、sass、stylus
npm i -D less-loader sass-loader stylus-loader
图片资源、字体图标资源、音视频资源
过去在 Webpack4 时,我们处理图片资源通过 file-loader 和 url-loader 进行处理,但是 Webpack5 已经将两个 Loader 功能内置到 Webpack 里,因此不需要再下载 loader了,只需要简单配置即可处理图片资源
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
}
上面只是对图片的简单处理,还可以对图片资源进行一些优化,比如下于多少 KB 转为 base64 码。可能还会有提到图片压缩,这个会在后面的高级配置提到
{
test: /.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 // 小于10kb的图片会被 base64 处理
}
}
}
字体图标和音视频也是文件资源,因此处理方法和图片资源处理类似:
{
test: /\.(ttf|woff2?|map4|map3|avi)$/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:8][ext][query]",
},
}
plugins
loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量
plugin 可以用来处理 js 和 html 的资源
问题来了,js 资源不是 Webpack 已经处理好了?咋又需要处理了?
问的好,前面也提到过工具开发都是有一个主要目的,但随着技术的发展,在开发 Webpack 时也不能料到之后的 js 语法会发展成哪样,因此它能做的只是兼容它那是的 js,但后面的它就管不到了,只能自己配置处理了
所以 Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法,导致 js 不能在 IE 等浏览器运行,因此我们希望做一些兼容性处理
这里主要介绍两个处理 js 的插件:Babel 和 Eslint
- 针对 js 兼容性处理,我们使用 Babel 来完成
- 针对代码格式,我们使用 Eslint 来完成
在开发时,可以按照先完成 Eslint 检测,代码格式无误后,在由 Babel 做代码兼容性处理。当然,个人开发可以跳过 Eslint 检测,因为有时候很烦人
处理 js 资源
Eslint
首先,在 Webpack 配置文件引入 Eslint 插件,然后使用插件:
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
plugins: [
new ESLintWebpackPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "src"),
}),
]
完成了上面的操作,就需要去写 Eslint 的配置了,它也有自己的配置文件,还有很多种写法:
.eslintrc.*:新建文件,位于项目根目录.eslintrc.eslintrc.js.eslintrc.json- 区别在于配置格式不一样
package.json中eslintConfig:不需要创建文件,在原有文件基础上写
ESLint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
基础的 ESLint 配置文件:
module.exports = {
// 继承 Eslint 规则
extends: ["eslint:recommended"],
env: {
node: true,
browser: true,
},
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
},
rules: {
"no-var": 2,
},
};
这里 extends 继承的直接是 Eslint 的规则,这里还可以继承 React -- react-app 、Vue -- plugin:vue/vue3-essential 规则
.eslintignore文件可以添加需要忽略检查的文件目录
同样,需要安装使用的依赖:
npm i -D eslint eslint-webpack-plugin
Babel
Babel 的使用和 Eslint 有些不太一样了,它是通过处理器实现的:
{
test: /.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
}
完成了上面的操作,就需要去写 Babel 的配置了,它也有自己的配置文件,还有很多种写法:
babel.config.*:新建文件,位于项目根目录babel.config.jsbabel.config.json
.babelrc.*:新建文件,位于项目根目录.babelrc.babelrc.js.babelrc.json
package.json中babel:不需要创建文件,在原有文件基础上写
Babel 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
基础的 Babel 配置文件:
module.exports = {
presets: ['@babel/preset-env']
}
同样,需要安装使用的依赖:
npm i -D babel-loader @babel/core @babel/preset-env
处理 html 资源
对打包生成的 html 的处理配置,使用此插件可以指定模板,即打包后的 html 与模板的格式一致
const HtmlWebpackPlugin = require("html-webpack-plugin");
plugins: [
new HtmlWebpackPlugin({
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "public/index.html"),
}),
],
同样,需要安装使用的依赖:
npm i -D html-webpack-plugin
mode
development, production 两个环境二选一
mode: "development"
结语
这是一篇关于入门 Webpack 的基本配置的讲解。可以用于配置 Webpack 时用来查阅,因为它包括了基础配置代码
如果想了解一些关于 Webpack 的高级配置,可以转到 Webpack 进阶篇
最后附上 Webpack 配置文件的结构,配置内容直接往里面套即可:
module.exports = {
entry: "",
output: {
path: "",
filename: "",
},
module: {
rules: [
{
test: /\.xxx$/i,
use: [],
},
],
},
plugins: [],
mode: "",
};