一、5 大核心概念
1. entry(入口)
指示 Webpack 从哪个文件开始打包
2. output(输出)
指示 Webpack 打包完的文件输出到哪里去,如何命名等
3. loader(加载器)
webpack 本身只能处理 js、json 等资源,其他资源需要借助 loader,Webpack 才能解析
4. plugins(插件)
扩展 Webpack 的功能
5. mode(模式)
主要由两种模式:
开发模式:development
生产模式:production
Webpack基本配置
webpack.config.js
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
// path: 文件输出目录,必须是绝对路径
// path.resolve()方法返回一个绝对路径
// __dirname 当前文件的文件夹绝对路径
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "main.js",
},
// 加载器
module: {
rules: [
// loader的配置
],
},
// 插件
plugins: [
// plugin的配置
],
// 模式
mode: "development",
};
1. 处理样式资源
下载包
npm i css-loader style-loader -D
css-loader
:负责将 Css 文件编译成 Webpack 能识别的模块style-loader
:会动态创建一个 Style 标签,里面放置 Webpack 中 Css 模块内容
npm i less-loader -D
less-loader
:负责将 Less 文件编译成 Css 文件
npm i sass-loader sass -D
sass-loader
:负责将 Sass 文件编译成 css 文件sass
:sass-loader
依赖sass
进行编译
npm i stylus-loader -D
stylus-loader
:负责将 Styl 文件编译成 Css 文件
配置
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
// path: 文件输出目录,必须是绝对路径
// path.resolve()方法返回一个绝对路径
// __dirname 当前文件的文件夹绝对路径
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "main.js",
},
// 加载器
module: {
rules: [
// loader的配置
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左(从上到下)
use: [
"style-loader", // 将js中的css通过创建style标签添加到html文件中生效
"css-loader", // 将css资源编译成commonjs的模块到js中
],
},
{
test: /\.less$/,
use: [
// 使用多个loader
"style-loader",
"css-loader",
"less-loader", // 将less编译成css文件
],
},
{
test: /\.s[ac]ss$/,
use: [
"style-loader",
"css-loader",
"sass-loader", // 将less编译成css文件
],
},
{
test: /\.styl$/,
use: ["style-loader", "css-loader", "stylus-loader"],
},
],
},
// 插件
plugins: [
// plugin的配置
],
// 模式
mode: "development",
};
2. 处理图片资源
Webpack5 将file-loader
和 url-loader
功能内置到 Webpack 里,我们只需要简单配置即可处理图片资源
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "main.js",
},
// 加载器
module: {
rules: [
// loader的配置
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
// 小于10kb的图片会被base64处理
// 优点:减少请求数量 缺点:体积会更大
maxSize: 10 * 1024,
},
},
},
],
},
// 插件
plugins: [
// plugin的配置
],
// 模式
mode: "development",
};
3. 修改输出资源的名称和路径
(注意:需要将上次打包生成的文件清空,再重新打包才有效果)
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
},
// 加载器
module: {
rules: [
// loader的配置
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
// 小于10kb的图片会被base64处理
// 优点:减少请求数量 缺点:体积会更大
maxSize: 10 * 1024,
},
},
generator: {
// 将图片文件输出到 static/images 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: "static/images/[hash:8][ext][query]",
},
},
],
},
// 插件
plugins: [
// plugin的配置
],
// 模式
mode: "development",
};
4. 自动清空上次打包资源
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
// 自动清空上次打包的内容
// 原理:在打包前,将path整个目录内容清空,再进行打包
clean: true,
},
// 加载器
module: {
rules: [
// loader的配置
],
},
// 插件
plugins: [
// plugin的配置
],
// 模式
mode: "development",
};
5. 处理字体图标资源
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
// 小于10kb的图片会被base64处理
// 优点:减少请求数量 缺点:体积会更大
maxSize: 10 * 1024,
},
},
generator: {
filename: "static/images/[hash:8][ext][query]",
},
},
{
test: /\.(ttf|woff2?)$/,
type: "asset/resource", // 不会转basse64
generator: {
// 输出名称
filename: "static/media/[hash:8][ext][query]",
},
},
],
},
// 插件
plugins: [
// plugin的配置
],
// 模式
mode: "development",
};
6. 处理其他资源
就是在处理字体图标资源基础上增加其他文件类型,统一处理即可
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
{
test: /\.(ttf|woff2?|map4|map3|avi)$/,
type: "asset/resource", // 不会转basse64
generator: {
// 输出名称
filename: "static/media/[hash:8][ext][query]",
},
},
],
},
// 插件
plugins: [
// plugin的配置
],
// 模式
mode: "development",
};
7. 处理 js 资源
有人可能会问,js 资源 Webpack 不能已经处理了吗,为什么我们还要处理呢?
原因是 Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法
其次开发中,团队对代码格式是有严格要求的,我们不能由肉眼去检测代码格式,需要使用专业的工具来检测。
- 针对 js 兼容性处理,我们使用 Babel 来完成
- 针对代码格式,我们使用 Eslint 来完成
我们先完成 Eslint,检测代码格式无误后,在由 Babel 做代码兼容性处理
Eslint (plugin)
https://eslint.nodejs.cn/docs/latest
可组装的 JavaScript 和 JSX 检查工具。
这句话意思就是:它是用来检测 js 和 jsx 语法的工具,可以配置各项功能。
我们使用 Eslint,关键是写 Eslint 配置文件,里面写上各种 rules 规则,将来运行 Eslint 时就会以写的规则对代码进行检查。
1. 老版本配置
.eslintrc.js
旧配置,可以直接把 ESLint 降级回 8.x
npm install eslint@8 --save-dev
.eslintrc.js
module.exports = {
// 解析选项
parserOptions: {},
// 具体检查规则
rules: {},
// 继承其他规则
extends: [],
// ...
};
(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"],
},
};
示例:
.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 path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
clean: true, // 自动将上次打包目录资源清空
},
module: {
rules: [
// loader
]
},
plugins: [
new ESLintWebpackPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "src"),
}),
],
mode: "development",
};
忽略文件
.eslintignore
# 忽略dist目录下所有文件
dist
2. 在 Webpack 中使用新版本
npm i eslint-webpack-plugin eslint -D
- eslint.config.mjs
import js from "@eslint/js";
import globals from "globals";
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
languageOptions: {
ecmaVersion: 6, // es6
sourceType: "module", // es6 module
globals: {
...globals.node, // 启用node中全局变量
...globals.browser, // 启用浏览器中全局变量
},
},
plugins: {},
rules: {
...js.configs.recommended.rules, // 继承 Eslint 规则
"no-var": "error", // 不能使用 var 定义变量
},
},
globalIgnores(["dist/**"]), // 忽略文件
]);
或者直接用指令生成
npm init @eslint/config
Babel (loader)
JavaScript 编译器。
主要用于将 ES6 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中
babel.config.js
module.exports = {
// 预设
presets: [],
};
presets 预设
简单理解:就是一组 Babel 插件, 扩展 Babel 功能
@babel/preset-env
: 一个智能预设,允许您使用最新的 JavaScript。@babel/preset-react
:一个用来编译 React jsx 语法的预设@babel/preset-typescript
:一个用来编译 TypeScript 语法的预设
在 Webpack 中使用
npm i babel-loader @babel/core @babel/preset-env -D
babel.config.js
module.exports = {
// 能够编译ES6语法
presets: ["@babel/preset-env"],
};
- webpack.config.js
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
],
},
// 插件
plugins: [
// plugin的配置
],
// 模式
mode: "development",
};
8. 处理 Html 资源(plugin)
去掉引入的 js 文件,因为 HtmlWebpackPlugin 会自动引入
npm i html-webpack-plugin -D
- webpack.config.js
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
],
},
// 插件
plugins: [
// plugin的配置
new ESLintWebpackPlugin({
// 检测哪些文件
context: path.resolve(__dirname, "src"),
extensions: ["js"],
}),
new HtmlWebpackPlugin({
// 模板:以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "public/index.html"),
}),
],
// 模式
mode: "development",
};
9. 开发服务器&自动化
每次写完代码都需要手动输入指令才能编译代码,太麻烦了,我们希望一切自动化
npm i webpack-dev-server -D
- webpack.config.js
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
],
},
// 插件
plugins: [
// plugin的配置
],
// 开发服务器:不会输出资源,在内存中编译打包
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
},
// 模式
mode: "development",
};
运行指令
// 不再是npx webpack
npx webpack serve
10. 生产模式介绍
准备两个配置文件来放不同的配置
├── webpack-test (项目根目录)
├── config (Webpack配置文件目录)
│ ├── webpack.dev.js(开发模式配置文件)
│ └── webpack.prod.js(生产模式配置文件)
├── node_modules (下载包存放目录)
├── src (项目源码目录,除了html其他都在src里面)
│ └── 略
├── public (项目html文件)
│ └── index.html
├── eslint.config.js(Eslint配置文件)
├── babel.config.js(Babel配置文件)
└── package.json (包的依赖管理配置文件)
修改 webpack.dev.js
因为文件目录变了,所以所有绝对路径需要回退一层目录才能找到对应的文件
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
// 开发模式没有输出
path: undefined,
// filename: 输出文件名
filename: "static/js/main.js",
},
// 加载器
module: {
rules: [
// loader的配置
],
},
// 插件
plugins: [
// plugin的配置
new ESLintWebpackPlugin({
context: path.resolve(__dirname, "../src"),
extensions: ["js"],
}),
new HtmlWebpackPlugin({
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"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "../dist"),
// filename: 输出文件名
filename: "static/js/main.js",
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
],
},
// 插件
plugins: [
// plugin的配置
new ESLintWebpackPlugin({
context: path.resolve(__dirname, "../src"),
extensions: ["js"],
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
],
// 模式
mode: "production",
};
运行生产模式的指令:
npx webpack --config ./config/webpack.prod.js
配置运行指令
为了方便运行不同模式的指令,我们将指令定义在 package.json 中 scripts 里面
// package.json
{
// 其他省略
"scripts": {
"start": "npm run dev",
"dev": "npx webpack serve --config ./config/webpack.dev.js",
"build": "npx webpack --config ./config/webpack.prod.js"
}
}
以后启动指令:
- 开发模式:
npm start
或npm run dev
- 生产模式:
npm run build
11. Css 处理
(1) 提取 Css 成单独文件
Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式
这样对于网站来说,会出现闪屏现象,用户体验不好
我们应该是单独的 Css 文件,通过 link 标签加载性能才好
npm i mini-css-extract-plugin -D
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "../dist"),
// filename: 输出文件名
filename: "static/js/main.js",
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左(从上到下)
use: [
MiniCssExtractPlugin.loader, // 提取css成单独文件
"css-loader", // 将css资源编译成commonjs的模块到js中
],
},
{
test: /\.less$/,
use: [
// 使用多个loader
MiniCssExtractPlugin.loader,
"css-loader",
"less-loader", // 将less编译成css文件
],
},
{
test: /\.s[ac]ss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader", // 将less编译成css文件
],
},
{
test: /\.styl$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "stylus-loader"],
},
],
},
// 插件
plugins: [
// plugin的配置
// 提取css成单独文件
new MiniCssExtractPlugin({
// 定义输出文件名和目录
filename: "static/css/main.css",
}),
],
// 模式
mode: "production",
};
运行指令
npm run build
(2) Css 兼容性处理 (postcss)
npm i postcss-loader postcss postcss-preset-env -D
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 用来获取处理样式的 loader
function getStyleLoader(preProcessor) {
return [
MiniCssExtractPlugin.loader, // 提取css成单独文件
"css-loader", // 将css资源编译成commonjs的模块到js中
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
preProcessor,
].filter(Boolean);
}
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "../dist"),
// filename: 输出文件名
filename: "static/js/main.js",
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左(从上到下)
use: getStyleLoader(),
},
{
test: /\.less$/,
use: getStyleLoader("less-loader"),
},
{
test: /\.s[ac]ss$/,
use: getStyleLoader("sass-loader"),
},
{
test: /\.styl$/,
use: getStyleLoader("stylus-loader"),
},
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024,
},
},
generator: {
filename: "static/images/[hash:8][ext][query]",
},
},
{
test: /\.(ttf|woff2?|map4|map3|avi)$/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:8][ext][query]",
},
},
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
],
},
// 插件
plugins: [
// plugin的配置
],
// 模式
mode: "production",
};
package.json
{
// 其他省略
"browserslist": ["last 2 version", "> 1%", "not dead"]
}
(3)Css 压缩
npm i css-minimizer-webpack-plugin -D
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
path: path.resolve(__dirname, "../dist"),
// filename: 输出文件名
filename: "static/js/main.js",
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
],
},
// 插件
plugins: [
// plugin的配置
new ESLintWebpackPlugin({
context: path.resolve(__dirname, "../src"),
extensions: ["js"],
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
// 提取css成单独文件
new MiniCssExtractPlugin({
filename: "static/css/main.css",
}),
// css压缩
new CssMinimizerPlugin(),
],
// 模式
mode: "production",
};
12.html 压缩
默认生产模式已经开启了:html 压缩和 js 压缩
不需要额外进行配置
13. 总结
本章节我们学会了 Webpack 基本使用,掌握了以下功能:
1. 两种开发模式
- 开发模式:代码能编译自动化运行
- 生产模式:代码编译优化输出
2. Webpack 基本功能
- 开发模式:可以编译 ES Module 语法
- 生产模式:可以编译 ES Module 语法,压缩 js 代码
3. Webpack 配置文件
5 个核心概念
- entry
- output
- loader
- plugins
- mode
devServer 配置
4. Webpack 脚本指令用法
webpack
直接打包输出webpack serve
启动开发服务器,内存编译打包没有输出
附录:
webpack.config.js
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
// path: 所有文件输出目录,必须是绝对路径
// path.resolve()方法返回一个绝对路径
// __dirname 当前文件的文件夹绝对路径
path: path.resolve(__dirname, "dist"),
// filename: 输出文件名
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左(从上到下)
use: [
"style-loader", // 将js中的css通过创建style标签添加到html文件中生效
"css-loader", // 将css资源编译成commonjs的模块到js中
],
},
{
test: /\.less$/,
use: [
// 使用多个loader
"style-loader",
"css-loader",
"less-loader", // 将less编译成css文件
],
},
{
test: /\.s[ac]ss$/,
use: [
"style-loader",
"css-loader",
"sass-loader", // 将less编译成css文件
],
},
{
test: /\.styl$/,
use: ["style-loader", "css-loader", "stylus-loader"],
},
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
// 小于10kb的图片会被base64处理
// 优点:减少请求数量 缺点:体积会更大
maxSize: 10 * 1024,
},
},
generator: {
// 将图片文件输出到 static/images 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: "static/images/[hash:8][ext][query]",
},
},
{
test: /\.(ttf|woff2?|map4|map3|avi)$/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:8][ext][query]",
},
},
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
],
},
// 插件
plugins: [
// plugin的配置
new ESLintWebpackPlugin({
// 检测哪些文件
context: path.resolve(__dirname, "src"),
extensions: ["js"],
}),
new HtmlWebpackPlugin({
// 模板:以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "public/index.html"),
}),
],
// 开发服务器:不会输出资源,在内存中编译打包
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
},
// 模式
mode: "development",
};
webpack.prod.js
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
// 用来获取处理样式的 loader
function getStyleLoader(preProcessor) {
return [
MiniCssExtractPlugin.loader, // 提取css成单独文件
"css-loader", // 将css资源编译成commonjs的模块到js中
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
preProcessor,
].filter(Boolean);
}
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
// path: 所有文件输出目录
// __dirname nodejs的变量,代表当前文件的文件夹目录
path: path.resolve(__dirname, "../dist"),
// filename: 输出文件名
filename: "static/js/main.js",
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
// loader的配置
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左(从上到下)
use: getStyleLoader(),
},
{
test: /\.less$/,
use: getStyleLoader("less-loader"),
},
{
test: /\.s[ac]ss$/,
use: getStyleLoader("sass-loader"),
},
{
test: /\.styl$/,
use: getStyleLoader("stylus-loader"),
},
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
// 小于10kb的图片会被base64处理
// 优点:减少请求数量 缺点:体积会更大
maxSize: 10 * 1024,
},
},
generator: {
// 将图片文件输出到 static/images 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: "static/images/[hash:8][ext][query]",
},
},
{
test: /\.(ttf|woff2?|map4|map3|avi)$/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:8][ext][query]",
},
},
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
],
},
// 插件
plugins: [
// plugin的配置
new ESLintWebpackPlugin({
// 检测哪些文件
context: path.resolve(__dirname, "../src"),
extensions: ["js"],
}),
new HtmlWebpackPlugin({
// 模板:以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "../public/index.html"),
}),
// 提取css成单独文件
new MiniCssExtractPlugin({
// 定义输出文件名和目录
filename: "static/css/main.css",
}),
// css压缩
new CssMinimizerPlugin(),
],
// 模式
mode: "production",
};
webpack.dev.js
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口
entry: "./src/main.js", // 相对路径
// 输出
output: {
// path: 所有文件的输出目录
// 开发模式没有输出
path: undefined,
// filename: 输出文件名
filename: "static/js/main.js",
},
// 加载器
module: {
rules: [
// loader的配置
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左(从上到下)
use: [
"style-loader", // 将js中的css通过创建style标签添加到html文件中生效
"css-loader", // 将css资源编译成commonjs的模块到js中
],
},
{
test: /\.less$/,
use: [
// 使用多个loader
"style-loader",
"css-loader",
"less-loader", // 将less编译成css文件
],
},
{
test: /\.s[ac]ss$/,
use: [
"style-loader",
"css-loader",
"sass-loader", // 将less编译成css文件
],
},
{
test: /\.styl$/,
use: ["style-loader", "css-loader", "stylus-loader"],
},
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
// 小于10kb的图片会被base64处理
// 优点:减少请求数量 缺点:体积会更大
maxSize: 10 * 1024,
},
},
generator: {
// 将图片文件输出到 static/images 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: "static/images/[hash:8][ext][query]",
},
},
{
test: /\.(ttf|woff2?|map4|map3|avi)$/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:8][ext][query]",
},
},
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
],
},
// 插件
plugins: [
// plugin的配置
new ESLintWebpackPlugin({
// 检测哪些文件
context: path.resolve(__dirname, "../src"),
extensions: ["js"],
}),
new HtmlWebpackPlugin({
// 模板:以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "../public/index.html"),
}),
],
// 开发服务器:不会输出资源,在内存中编译打包
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
},
// 模式
mode: "development",
};