摘自官网的一段话:webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。
官网链接:https://webpack.docschina.org/concepts/
在日常的开发中,我们会使用框架(React、Vue),ES6 模块化语法,Less/Sass 等 css 预处理器等语法进行开发。这样的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、Css 等语法,才能运行,所以我们需要打包工具帮我们做完这些事。除此之外,打包工具还能压缩代码、做兼容性处理、提升代码性能等。
在这里我将webpack为了几个要点,也是webpack核心的几个点
新建文件,创建一个新的项目
npm init -y
下载我们的依赖
npm i webpack webpack-cli -D
构建项目目录文件
webpack_document # 项目根目录(所有指令必须在这个目录运行)└── src # 项目源码目录├── js # js文件目录│ ├── count.js│ └── sum.js├── css # css文件目录└── index.js # 项目主文件
创建我们的配置文件webpack.config.js
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),// clean清楚上一次的打包结果clean: true,// 输出的文件名字filename: 'index.js'},// 解析器module: {},plugins: [],mode: 'production'
}
运行指令
npx webpack
观察生成的dist的文件,就是我们打包后的文件了
Webpack 将来都通过 webpack.config.js 文件进行配置,来增强 Webpack 的功能
开发模式顾名思义就是我们开发代码时使用的模式。
这个模式下我们主要做两件事:
由于webpack只能处理js、json文件,并不能处理css文件,所以我们需要借助相应loader解析器来增强我们的功能,在webpack的官网中,为我们提供了常用的loader,如果不能满足我们的日常需要,也可以到社区中去寻找想要的loader [webpack官网loader]
下载
// 下载css-loader style-loader
npm i css-loader style-loader -D
说明
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: 'index.js'},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},]},plugins: [],mode: 'production'
}
使用
在src目录下创建我们的css文件,并在index.js中进行引入,然后进行打包,观察我们的dist文件里面的输出结果
为了方便我们观察效果,我们创建我们静态页面,并引入我们打包后dist文件下面的js文件,文件目录结构如下
页面效果如下:
下载
// 这里我们前面下载过style-loader 和 css-loader 了,这里就不需要下载
npm i less-loader -D
说明
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: 'index.js'},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader,再写less-loaderuse: ["style-loader", "css-loader", "less-loader"],}]},plugins: [],mode: 'production'
}
使用
在src目录下,创建我们的less文件夹,并生成index.less文件,写入样式,在index.js,引入我们的less文件,然后在pubilc的index.html文件中,创建对应的box文件,执行npx webpack,观察打包后的结果
页面效果如下:
下载
npm i sass-loader sass -D
说明
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: 'index.js'},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: ["style-loader", "css-loader", "sass-loader"],},]},plugins: [],mode: 'production'
}
使用
在src目录下,创建我们的sass文件夹,并生成index.sass 和 index.scss 文件,写入样式,在index.js,引入我们的sass、scss文件,然后在pubilc的index.html文件中,创建对应的box文件,执行npx webpack,观察打包后的结果
页面效果如下:
npm i stylus-loader -D
说明
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: 'index.js'},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.styl$/,use: ["style-loader", "css-loader", "stylus-loader"],},]},plugins: [],mode: 'production'
}
使用
在src目录下,创建我们的styl文件夹,并生成index.styl 和 index.styl 文件,写入样式,在index.js,引入我们的styl文件,然后在pubilc的index.html文件中,创建对应的box文件,执行npx webpack,观察打包后的结果
页面效果如下:
以下摘自官网的一段话
资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。
在 webpack 5 之前,通常使用:
raw-loader 将文件导入为字符串
url-loader 将文件作为 data URI 内联到 bundle 中
file-loader 将文件发送到输出目录
资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:
asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现。
asset/source 导出资源的源代码。之前通过使用 raw-loader 实现。
asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现。
当在 webpack 5 中使用旧的 assets loader(如 file-loader/url-loader/raw-loader 等)和 asset 模块时,你可能想停止当前 asset 模块的处理,并再次启动处理,这可能会导致 asset 重复,你可以通过将 asset 模块的类型设置为 ‘javascript/auto’ 来解决。
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: 'index.js'},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.styl$/,use: ["style-loader", "css-loader", "stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",},]},plugins: [],mode: 'production'
}
使用
在src目录下,创建我们的images文件夹,添加图片文件,笔者这里添加了jpe,png,gif三种格式的图片,分别在不同的样式中进行引入,执行npx webpack,观察打包后的结果
此时如果查看 dist 目录的话,会发现多了三张图片资源
因为 Webpack 会将所有打包好的资源输出到 dist 目录下
为什么样式资源没有呢?
因为经过 style-loader 的处理,样式资源打包到 main.js 里面去了,所以没有额外输出出来
页面效果
将小于某个大小的图片转化成 data URI 形式(Base64 格式)
优点:减少请求数量
缺点:体积变得更大,但是10kb以下的图片,转换为base64格式的情形下,只有增加1-2kb(所以我们出来10kb以下的)
配置
{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}}},
我们发现打包完成后,图片直接输出到dist的根目录下了,没有规范起来,我们希望输出到dist的static/images目录下,同时js文件输出到dist的static/js目录下,这样就比较规范了
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.styl$/,use: ["style-loader", "css-loader", "stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。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]",},},]},plugins: [],mode: 'production'
}
使用
通过以上配置后,dist文件输出的文件被规范起来了,这个时候需要修改一下我们index.html的引入路径,打开页面也是同样的效果
当我们在项目中使用字体图标的时候,我们也希望打包的时候,将这一部分内容进行打包输出
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.styl$/,use: ["style-loader", "css-loader", "stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},]},plugins: [],mode: 'production'
}
使用
在src目录下,创建我们的fonts文件夹,在阿里巴巴适量库中下载字体图标(笔者这里为了演示,使用的是font-class的形式),然后引入到fonts文件夹中,在index.js,然后在pubilc的index.html文件中,创建对应的span标签,添加class类名,执行npx webpack,观察打包后的结果
页面效果
开发中可能还存在一些其他资源,如音视频等,我们也一起处理了
就是在处理字体图标资源基础上增加其他文件类型,统一处理即可
配置
{// 如果有其他资源,在这里的正则里面添加即可test: /\.(ttf|woff2?|map4|map3|avi)$/,type: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},
这里有同学可能会问,js 资源 Webpack 不能已经处理了吗,为什么我们还要处理呢?
原因是 Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法,导致 js 不能在 IE 等浏览器运行,所以我们希望做一些兼容性处理。
其次开发中,团队对代码格式是有严格要求的,我们不能由肉眼去检测代码格式,需要使用专业的工具来检测。
针对 js 兼容性处理,我们使用 Babel 来完成
针对代码格式,我们使用 Eslint 来完成
我们先完成 Eslint,检测代码格式无误后,在由 Babel 做代码兼容性处理
介绍
简介:可组装的 JavaScript 和 JSX 检查工具。
这句话意思就是:它是用来检测 js 和 jsx 语法的工具,可以配置各项功能
我们使用 Eslint,关键是写 Eslint 配置文件,里面写上各种 rules 规则,将来运行 Eslint 时就会以写的规则对代码进行检查
配置文件
配置文件由很多种写法:
.eslintrc.*:新建文件,位于项目根目录
.eslintrc
.eslintrc.js
.eslintrc.json
区别在于配置格式不一样
package.json 中 eslintConfig:不需要创建文件,在原有文件基础上写
ESLint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
具体配置
我们以.eslintrc.js为例子进行配置
具体eslint的配置参考官网和规则文档,这里给出相关链接
ESlint规则
ESlint官网
// .eslintrc.js
module.exports = {// 继承 Eslint 规则extends: ["eslint:recommended"],env: {node: true, // 启用node中全局变量browser: true, // 启用浏览器中全局变量},parserOptions: {ecmaVersion: 6,sourceType: "module",},rules: {"no-var": 2, // 不能使用 var 定义变量},
};
下载
npm i eslint-webpack-plugin eslint -D
在webpack中使用
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
const ESLintWebpackPlugin = require("eslint-webpack-plugin");module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.styl$/,use: ["style-loader", "css-loader", "stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "src"),})],mode: 'production'
}
vsocde安装eslint插件
安装eslint插件后,配置需要忽略检查的文件
// .eslintignore
# 忽略dist目录下所有文件
dist
介绍
JavaScript 编译器。
主要用于将 ES6 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中
配置文件
配置文件由很多种写法:
babel.config.*:新建文件,位于项目根目录
babel.config.js
babel.config.json
.babelrc.*:新建文件,位于项目根目录
.babelrc
.babelrc.js
.babelrc.json
package.json 中 babel:不需要创建文件,在原有文件基础上写
Babel 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
具体配置
我们以babel.config.js为例子
// babel.config.js
module.exports = {// 预设presets: [],
};
presets 预设
简单理解:就是一组 Babel 插件, 扩展 Babel 功能
@babel/preset-env: 一个智能预设,允许您使用最新的 JavaScript。
@babel/preset-react:一个用来编译 React jsx 语法的预设
@babel/preset-typescript:一个用来编译 TypeScript 语法的预设
下载
npm i babel-loader @babel/core @babel/preset-env -D
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
const ESLintWebpackPlugin = require("eslint-webpack-plugin");module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.styl$/,use: ["style-loader", "css-loader", "stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},{test: /\.js$/,exclude: /node_modules/, // 排除node_modules代码不编译loader: "babel-loader",},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "src"),})],mode: 'production'
}
在实际的开发工作中,我们希望使用一个html模块,然后将我们打包后的js文件自动引入到html模版中,这样我们开发的时候就不用手动引入或者修改打包后的文件了
下载
npm i html-webpack-plugin -D
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.styl$/,use: ["style-loader", "css-loader", "stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},{test: /\.js$/,exclude: /node_modules/, // 排除node_modules代码不编译loader: "babel-loader",},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "public/index.html"),})],mode: 'production'
}
Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式
这样对于网站来说,会出现闪屏现象,用户体验不好
我们应该是单独的 Css 文件,通过 link 标签加载性能才好
下载插件
npm i mini-css-extract-plugin -D
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: [MiniCssExtractPlugin.loader, "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],},{test: /\.styl$/,use: [MiniCssExtractPlugin.loader, "css-loader", "stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},{test: /\.js$/,exclude: /node_modules/, // 排除node_modules代码不编译loader: "babel-loader",},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "public/index.html"),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "static/css/index.css",}),],mode: 'production'
}
下载
npm i postcss-loader postcss postcss-preset-env -D
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: [MiniCssExtractPlugin.loader, "css-loader", {loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},}],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: [MiniCssExtractPlugin.loader, "css-loader", {loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},"less-loader"],},{test: /\.s[ac]ss$/,use: [MiniCssExtractPlugin.loader, "css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},"sass-loader"],},{test: /\.styl$/,use: [MiniCssExtractPlugin.loader, "css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},"stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},{test: /\.js$/,exclude: /node_modules/, // 排除node_modules代码不编译loader: "babel-loader",},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "public/index.html"),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "static/css/index.css",}),],mode: 'production'
}
配置需要兼容的浏览器列表
// package.json"browserslist": ["last 2 version","> 1%","not dead"]
}
下载
npm i css-minimizer-webpack-plugin -D
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
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: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: [MiniCssExtractPlugin.loader, "css-loader", {loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},}],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: [MiniCssExtractPlugin.loader, "css-loader", {loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},"less-loader"],},{test: /\.s[ac]ss$/,use: [MiniCssExtractPlugin.loader, "css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},"sass-loader"],},{test: /\.styl$/,use: [MiniCssExtractPlugin.loader, "css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},"stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},{test: /\.js$/,exclude: /node_modules/, // 排除node_modules代码不编译loader: "babel-loader",},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "public/index.html"),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "static/css/index.css",}),new CssMinimizerPlugin()],mode: 'production'
}
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
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");// 获取处理样式的Loaders
const getStyleLoaders = (preProcessor) => {return [MiniCssExtractPlugin.loader,"css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean);
};module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: getStyleLoaders(),},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: getStyleLoaders("less-loader"),},{test: /\.s[ac]ss$/,use: getStyleLoaders("sass-loader"),},{test: /\.styl$/,use: getStyleLoaders("stylus-loader"),},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},{test: /\.js$/,exclude: /node_modules/, // 排除node_modules代码不编译loader: "babel-loader",},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "public/index.html"),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "static/css/index.css",}),new CssMinimizerPlugin()],mode: 'production'
}
在我们的日常开发中我们希望我改了代码后,会自动更新我们更改后的内容,而不用每次打包后才能看到效果,所以webpack提供了一个devServer的配置
下载
npm i webpack-dev-server -D
配置
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, 'dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader"],},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: ["style-loader", "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.styl$/,use: ["style-loader", "css-loader", "stylus-loader"],},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},{test: /\.js$/,exclude: /node_modules/, // 排除node_modules代码不编译loader: "babel-loader",},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "public/index.html"),})],// 开发服务器devServer: {host: "localhost", // 启动服务器域名port: "3000", // 启动服务器端口号open: true, // 是否自动打开浏览器},mode: 'production'
}
运行
npx webpack serve
并且当你使用开发服务器时,所有代码都会在内存中编译打包,并不会输出到 dist 目录下。
开发时我们只关心代码能运行,有效果即可,至于代码被编译成什么样子,我们并不需要知道。
在我们日常开发中,我们总是希望我们开发完成后,今天一系列打包优化,性能提升到最好,所以webpack这里也给我们提供了使用不同的配置文件进行配置
适用于dev环境,配合devServe配置,进行开发,并自动实现代码更新,所有代码都会在内存中编译打包,并不会输出到 dist 目录下。
生产模式是开发完成代码后,我们需要得到代码将来部署上线。
这个模式下我们主要对代码进行优化,让其运行性能更好。
优化主要从两个角度出发:
我们分别准备两个配置文件来放不同的配置,分别对应开发模式和生产模式
├── webpack-document (项目根目录)├── 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 (包的依赖管理配置文件)
生产不同的webpack配置,并做里面的绝对路径进行相应的修改
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
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");// 获取处理样式的Loaders
const getStyleLoaders = (preProcessor) => {return [MiniCssExtractPlugin.loader,"css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean);
};
module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {path: undefined, // 开发模式没有输出,不需要指定输出目录filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中// clean: true, // 开发模式没有输出,不需要清空输出结果},// Performance 这些选项可以控制 webpack 如何通知「资源(asset)和入口起点超过指定文件限制」。performance: {hints: false},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: getStyleLoaders(),},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: getStyleLoaders("less-loader"),},{test: /\.s[ac]ss$/,use: getStyleLoaders("sass-loader"),},{test: /\.styl$/,use: getStyleLoaders("stylus-loader"),},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},{test: /\.js$/,exclude: /node_modules/, // 排除node_modules代码不编译loader: "babel-loader",},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "../src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "../public/index.html"),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "static/css/index.css",}),new CssMinimizerPlugin()],// 开发服务器devServer: {host: "localhost", // 启动服务器域名port: "3000", // 启动服务器端口号open: true, // 是否自动打开浏览器},mode: 'development'
}
// path 为 Node.js的核心模块,专门用来处理文件路径
const path = require('path')
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");// 获取处理样式的Loaders
const getStyleLoaders = (preProcessor) => {return [MiniCssExtractPlugin.loader,"css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean);
};
module.exports = {// 入口entry: {// 需要一个相对路径index: './src/index.js'},// 输出output: {// 需要一个绝对路径path: path.resolve(__dirname, '../dist'),clean: true,filename: "static/js/index.js", // 将 js 文件输出到 static/js 目录中},// Performance 这些选项可以控制 webpack 如何通知「资源(asset)和入口起点超过指定文件限制」。performance: {hints: false},// 解析器 module: {rules: [{test: /\.css$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: getStyleLoaders(),},{// 正则匹配所有已.less文件结尾的文件test: /\.less$/,// loader的执行顺序是从右往左的,所以这里先写style-loader,再写css-loader// 如果只使用一个loader的话,可以使用loader属性代替use,如下// loader:"style-loader"use: getStyleLoaders("less-loader"),},{test: /\.s[ac]ss$/,use: getStyleLoaders("sass-loader"),},{test: /\.styl$/,use: getStyleLoaders("stylus-loader"),},{test: /\.(png|jpe?g|gif|webp)$/,type: "asset",// 类似于 module.generator,你可以用 module.parser 在一个地方配置所有解析器的选项。parser: {// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。dataUrlCondition: {maxSize: 10 * 1024 // 小于10kb的图片会被base64处理}},// 可以使用 module.generator 在一个地方配置所有生成器的选项generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "static/imgs/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|svg)$/,// 发送一个单独的文件并导出 URLtype: "asset/resource",generator: {filename: "static/media/[hash:8][ext][query]",},},{test: /\.js$/,exclude: /node_modules/, // 排除node_modules代码不编译loader: "babel-loader",},]},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "../src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "../public/index.html"),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "static/css/index.css",}),new CssMinimizerPlugin()],// 开发服务器// devServer: {// host: "localhost", // 启动服务器域名// port: "3000", // 启动服务器端口号// open: true, // 是否自动打开浏览器// },mode: 'production'
}
{"name": "webpack_document","version": "1.0.0","description": "","main": "index.js",// 为了方便运行不同模式的指令,我们将指令定义在 package.json 中 scripts 里面"scripts": {"start": "npx webpack serve --config ./config/webpack.dev.js","dev": "npx webpack serve --config ./config/webpack.dev.js","build": "npx webpack --config ./config/webpack.prod.js","test": "echo \"Error: no test specified\" && exit 1"},"author": "","license": "ISC","devDependencies": {"@babel/core": "^7.20.12","@babel/preset-env": "^7.20.2","babel-loader": "^9.1.2","css-loader": "^6.7.3","eslint": "^8.33.0","eslint-webpack-plugin": "^3.2.0","html-webpack-plugin": "^5.5.0","less-loader": "^11.1.0","sass": "^1.58.0","sass-loader": "^13.2.0","style-loader": "^3.3.1","stylus-loader": "^7.1.0","webpack": "^5.75.0","webpack-cli": "^5.0.1","webpack-dev-server": "^4.11.1"}
}
开发模式:npm start 或 npm run dev
生产模式:npm run build
如果你学习到这里,恭喜你现在已经是一个webpack小能手了
两种开发模式
开发模式:代码能编译自动化运行
生产模式:代码编译优化输出
Webpack 基本功能
开发模式:可以编译 ES Module 语法
生产模式:可以编译 ES Module 语法,压缩 js 代码
Webpack 配置文件
5 个核心概念
entry
output
loader
plugins
mode
devServer 配置
Webpack 脚本指令用法
webpack 直接打包输出
webpack serve 启动开发服务器,内存编译打包没有输出