文章目录
概述
简介
Webpack 是一个现代 JS 应用程序的静态模块打包器(module bundler)
• 模块(模块化开发,可以提高开发效率,避免重复造轮子)
• 打包(将各个模块,按照一定的规则组装起来)
• 官网:https://webpack.js.org/
特点
• 功能强大(打包、构建、发布 Web 服务)
• 学习成本高
功能
• 将多个文件合并(打包),减少 HTTP 请求次数,从而提高效率
• 对代码进行编译,确保浏览器兼容性
• 对代码进行压缩,减小文件体积,提高加载速度
• 检测代码格式,确保代码质量
• 提供热更新服务,提高开发效率
• 针对不同环境,提供不同的打包策略
核心概念
• 入口(Entry)
打包时,第⼀个被访问的源码⽂件。默认是 src/index.js (可以通过配置⽂件指定)Webpack通过⼊⼝,加载整个项⽬的依赖。
• 出口(Output)
打包后,输出的⽂件名称,默认是 dist/main.js(可以通过配置⽂件指定)。
• 加载器(Loader)
专⻔⽤来处理⼀类⽂件(⾮ JS)的⼯具
- Webpack 默认只能识别 JS,想要处理其他类型的⽂件,需要对应的 loader
命名⽅式:xxx-loader(css-loader | html-loader | file-loader)
- 加载器是以 -loader 为后缀的 npm 包
常⽤加载器:https://www.webpackjs.com/loaders/
当前,打包时,我们也可以将不同类型的⽂件,单独打包
• 插件(Plugins)
实现 loader 之外的其他功能,Plugin 是 Webpack 的⽀柱,⽤来实现丰富的功能
命名⽅式:xxx-webpack-plugin(html-webpack-plugin)
常⽤插件:https://www.webpackjs.com/plugins/
- 插件是以 -webpack-plugin 为后缀的 npm 包
常⽤插件:https://www.webpackjs.com/plugins/
• 模式(Mode)
-
Mode 是⽤来区分环境的关键字
-
不同环境的打包逻辑不同,因此,需要区分
三种模式(名称固定,不能改)
- development(开发环境:⾃动优化打包速度,添加⼀些调试过程中的辅助)
- production(⽣产环境:⾃动优化打包结果)
- none(运⾏最原始的打包,不做任何额外处理)
• 模块(Module)
Webpack 中,模块的概念⽐较宽泛(⼀切皆为模块)
JS 模块
⼀段 CSS
⼀张图⽚
⼀个字体⽂件
……
模块详情:https://www.webpackjs.com/concepts/modules/
• 依赖图(Dependency Graph)
依赖就是必须要加载的内容。例如:使⽤ Bootstrap 之前必须先引⼊ jQuery
最佳实践
- 初始化项⽬
1 mkdirmyproject
2 cd myproject
3 npm init –y
mkdir myproject && cd myproject && npm init –
- 安装 Webpack
1 npm install -D webpack webpack-cli
- 创建⼊⼝⽂件(myproject/src/index.js)
1 /**
2 * Webpack 打包⼊⼝⽂件
3 */
4
5 console.log('Hello Webpack')
- 执⾏打包(必须指定 mode)
webpack ./src/index.js --output-path ./dist --mode=developm
Webpack 版本
• Webpack 4 于 2018 年 2 月发布
• Webpack 5 于 2020 年 10 月发布
安装命令需要调整(默认安装 5)
• npm install webpack -D # webpack 5
• npm install webpack@4 -D # webpack 4
配置文件
配置⽂件是⽤来简化命令⾏选项的
配置前:webpack ./src/index.js --output-path ./dist --mode=development
配置后:webpack
默认的配置⽂件名称是 webpack.config.js
- webpack.config.js 是以 CommonJS规范进⾏组织的
使⽤ Webpack 的过程,⼤部分就是跟配置⽂件打交道的过程
配置详情 https://www.webpackjs.com/configuration/
常用配置
/**
* Webpack 的配置⽂件
*/
const { resolve } = require('path')
module.exports = {
// 打包模式
mode: 'production',
// ⼊⼝⽂件
entry: './src/index.js',
// 出⼝配置
output: {
// 输出⽬录(输出⽬录必须是绝对路径)
path: resolve(__dirname, 'output'),
// 输出⽂件名称
filename: 'bundle.js'
},
// 模块配置
module: {
rules: [
// 指定多个配置规则
]35
},
// 开发服务器
devServer: {
},
// 插件配置
plugins: [
]
}
基础
打包 CSS
转换css
非 JS 文件打包,需要对应的 loader
• css-loader 将 CSS 转化为 JS(将 CSS 输出到打包后的 JS 文件中)
• style-loader 把包含 CSS 内容的 JS 代码,挂载到页面的 、<style> 标签当中
- 安装(npm i css-loader style-loader –D)
- 配置
• 匹配后缀名: test: /.css$/i,
• 指定加载器: use: [‘style-loader’,‘css-loader’]
Loader 执行顺序:先右后左(先下后上)
const path = require('path')
module.exports = {
// 模式
mode: 'none',
// ⼊⼝
entry: './src/index.js',
// 出⼝
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
// loader 配置
module: {
// 配置⽂件类型规则,不同的规则使⽤不同的 loader 进⾏处理
rules: [
{
// test 后跟随正则表达式,匹配⽂件类型
test: /\.css$/,
// use 表示使⽤什么 loader 来处理上述类型的⽂件
use: [
// 2. 将 JS 中的样式⽂件,嵌⼊到⻚⾯的 style 标签中
'style-loader',
//这⾥需要注意。在处理 CSS ⽂件时,各个 loader 的使⽤,有先后顺序。例如,我们先使⽤
//css-loader 将 CSS 代码转成 JS 代码,然后,再由 style-loader 将 JS 代码中的样式挂载
//到⻚⾯中。因此,需要先使⽤ css-loader,然后再使⽤ style-loader。
//这⾥需要强调的是:use 数组中,loader 的加载顺序是从下往上(从右向左),即最后⼀个
//loader 最先执⾏。因此,css-loader 在后,style-loader 在前。
//如果项⽬中除了 .css ⽂件之外,还有 .less ⽂件。我们还需要对 .less ⽂件进⾏打包。这⾥
//的打包顺序是:先将 .less ⽂件转成 .css ⽂件,然后,在打包 .css ⽂件。
//打包 .less ⽂件我们需要安装 less 和 less-loader
//less 打包逻辑
//声明 less ⽂件
// 1. css-loader 将样式⽂件转成 CommonJS 模块,加载到 JS 中
'css-loader'
]
}
]
}
}
转换LESS
use: [‘less-loader’,‘css-loader’,‘style-loade’]
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
将 CSS 打包成独⽴⽂件
安装( npm install mini-css-extract-plugin -D)
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'none',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [
// 'style-loader', // 将 CSS 嵌⼊到 HTML 中(现在,不再需要
CSS 嵌⼊到 HTML 中)
MiniCssExtractPlugin.loader // 将 CSS 打包到独⽴⽂件中
'css-loader'
]
},
{
test: /\.less$/,
use: [
// 'style-loader',
MiniCssExtractPlugin.loader
'css-loader',
'less-loader'
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
// 指定输⼊位置和⽂件名称
filename: 'css/[name].css',
}),
],
}
解决 CSS 中的图⽚引⼊问题
问题:将 CSS 单独打包到独⽴⽂件时,往往会发⽣路径的变更。此时,CSS 中的背景图⽚地址可能需要更改。
解决:为 MiniCssExtractPlugin.loader 指定公共路径
{
test: /\.css$/,
use: [
// 'style-loader', // 将 CSS 嵌⼊到 HTML 中(现在,不再需要将 CSS 嵌⼊到 HTML 中)
// MiniCssExtractPlugin.loader // 将 CSS 打包到独⽴⽂件中
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../' // 为背景图⽚指定路径
}
},
'css-loader'
]
},
添加前缀
安装( npm install postcss-loader autoprefixer -D)
module: {
rules: [
//此时运⾏ webpack 会报错:'No PostCSS Config found',原因是 PostCSS 需要⼀个配置,⽤来设置
//autoprefixer 的设置标准(即需要指定兼容哪些浏览器)
//解决:添加 PostCSS 的配置 - 在项⽬根⽬录下添加 postcss.config.js
//指定兼容规则
//有两种指定⽅式,⼆选⼀即可:
//1. 可以在 package.json 中指定(推荐)
//2. 在项⽬根⽬录下创建 .browserslistrc
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader' // 添加这⼀⾏,注意添加的顺序
]
},
]
}
//此时运⾏ webpack 会报错:'No PostCSS Config found',原因是 PostCSS 需要⼀个配置,⽤来设置
//autoprefixer 的设置标准(即需要指定兼容哪些浏览器)
//解决:添加 PostCSS 的配置 - 在项⽬根⽬录下添加 postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
}
指定兼容规则
有两种指定方式,二选一即可:
https://www.npmjs.com/package/browserslist
- 可以在 package.json 中指定(推荐)
"browserslist": [
"last 1 version", // 最后的⼀个版本
"> 1%" // 代表全球超过 1% 使⽤的浏览器
]
- 在项⽬根⽬录下创建 .browserslistrc
"browserslist": [
"last 1 version", // 最后的⼀个版本
"> 1%" // 代表全球超过 1% 使⽤的浏览器
]
格式校验
StyleLint
在前端开发中,我们使⽤ StyleLint 来检测 CSS 代码。
StyleLint 是检测 CSS 代码格式的插件。
# stylelint 是运⾏⼯具,stylelint-config-standard 是 stylelint 的推荐(https://github.com/stylelint/stylelint-config-standard)
配置
npm i --g stylelint stylelint-config-standard
压缩css
安装(npm install optimize-css-assets-webpack-plugin -D)
const path = require('path')
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
mode: 'none',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [49
'style-loader',
'css-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
},
plugins: [
new OptimizeCssAssetsPlugin()
]
}
打包 HTML html-webpack-plugin
https://www.npmjs.com/package/html-webpack-plugin
安装
npm i html-webpack-plugin -D # webpack 5
或
npm i html-webpack-plugin@4 -D # webpack 4
引入 const HtmlWebpackPlugin = require('html-webpack-plugin')
配置 plugins: [new HtmlWebpackPlugin() // 添加这⼀⾏]
(在 webpack.config.js 的 plugins 插件中添加 HtmlWebpackPlugin)
执行命令 webpack
设置 HTML 模板
plugins: [
// ⽤于⽣成 index.html
new HtmlWebpackPlugin({
template: './src/index.html', // 指定 HTML 的模板
})
]
设置 HTML 配置项
少量配置可以在 HtmlWebpackPlugin 中指定
⼤量配置建议指定 HTML ⽂件的模板
plugins: [
// ⽤于⽣成 index.html
new HtmlWebpackPlugin({
template: './src/index.html', // 指定 HTML 的模板
title: 'Webpack Plugin Sample', // 添加 HTML 的 title
meta: { // 添加 HTML 的 mea
viewport: 'width=device-width, initial-scale=1.0'
}
}),
// ⽤于⽣成 about.html
new HtmlWebpackPlugin({
filename: 'about.html' // 指定声明的⽂件名,如果有多个模板,可以实例化多次
})
]
声明HTML模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="<%= htmlWebpackPlugin.options.viewport %>">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div class="container">
<h1><%= htmlWebpackPlugin.options.title %></h1>
</div>
</body>
</html>
压缩HTML
除了创建模板⽂件外,htmlWebpackPlugin 还可以通过配置,实现压缩 HTML 的效果
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./src/index.html",
title: "Webpack Demo666",
minify:{
removeRedundantAttributes: true, // 删除多余的属性
collapseWhitespace: true, // 折叠空⽩区域
removeAttributeQuotes: true, // 移除属性的引号
removeComments: true, // 移除注释
collapseBooleanAttributes: true // 省略只有 boolean 值的属性值 例如:readonly checked
}
}),
]
- minify 选项可以配置压缩的内容
打包 JS
编译
babel
安装 ( npm install babel-loader @babel/core @babel/preset-env -D)
@babel/core 包含 Babel 转换的核⼼ API
@babel/preset-env 包含最新 JS 语法的转换规则
babel-loader Webpack 中,转换 JS 的加载器
添加配置
const path = require('path')
module.exports = {
mode: 'none',
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist'),
publicPath: 'dist/'
},
module: {
rules: [
{
test: /\.m?js$/i,
exclude: /node_modules/, // 排除不需要打包的⽬录
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}
启⽤ babel-loader 后 ES6+ 的语法会转成 ES5。但是 babel 只会对基本语法进⾏转移。像 promise
这样的⾼级语法,Babel 就不能转换。
polyfill
安装(npm i @babel/polyfill -D)
使用
在⼊⼝⽂件中引⼊ @babel/polyfill
import ‘@babel/polyfill’
@babel/polyfill 会对所有的 JS 新语法进⾏转译(没⽤到的新语法也会被转译),因此打包后的 JS 会⾮常⼤
core-js
core-js 可以按需转译(即只转译⽤到的新语法)
安装(npm i core-js -D)
使用
const path = require('path')
module.exports = {
mode: 'none',
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist'),
publicPath: 'dist/'
},
module: {
rules: [
{
test: /\.m?js$/i,
exclude: /node_modules/, // 排除不需要打包的⽬录
use: {
loader: 'babel-loader',
options: {
// presets: ['@babel/preset-env']
presets: [
[
'@babel/preset-env',
{
// 按需加载57
useBuiltIns: 'usage',
// 指定 core-js版本
corejs: {
version: 3
},
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
}
}
]
}
}
格式校验
之前进⾏格式校验使⽤的是 eslint-loader,但 eslint-loader 已经废弃。
现在推荐使⽤ eslint-webpack-plugin 来进⾏ JS 的格式校验
详情查看:https://www.npmjs.com/package/eslint-webpack-plugin
安装 (npm i eslint eslint-config-airbnb-base eslint-webpack-plugin eslin
t-plugin-import -D)
说明
-
eslint(⽤来对 JS 进⾏格式校验的⼯具)
- https://eslint.org/
-
eslint-config-airbnb-base(格式校验规则)
- https://github.com/airbnb/javascript
- https://www.npmjs.com/package/eslint-config-airbnb-base
-
eslint-webpack-plugin(Webpack 的 eslint 插件)
- https://www.npmjs.com/package/eslint-webpack-plugin
-
eslint-plugin-import(⽤于在 package.json 中读取 eslintConfig 配置项)
使用
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
// ...
plugins: [new ESLintPlugin(options)],
// ...
};
设置配置项
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
plugins: [
// # 使⽤ 配置项都可以在 eslint-webpack-plugin 的 github 上找到
new ESLintPlugin({
fix: true,
extensions: ['js', 'json', 'coffee'],
exclude: '/node_modules/'
}),
]
};
指定 eslint 配置
- 指定 eslint 配置的⽅式有多种
在 package.json 中,通过 eslintConfig 指定
在项⽬根⽬录下,通过 .eslintrc 指定(.eslintrc 可以通过 eslint --init 命令⽣成)
// package.json59
"eslintConfig": {
"extends": "airbnb-base",
//#!!!!如果没使⽤ alias 下⾯的不⽤配置!!!!!
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.config.js"
}
}
}
}
打包图片
样式中的图⽚引⼊
打包图⽚时,最常⽤两个 loader
- file-loader 将⽤到的图⽚直接复制到 dist ⽬录下,过滤掉不⽤的图⽚
- url-loader 将⼩于指定⼤⼩的图⽚,转成 base64,超过指定⼤⼩的图⽚依然使⽤ file-loader 进⾏复制
安装(npm install file-loader url-loader -D)
配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// 打包模式
mode: 'development',
// ⼊⼝⽂件
entry: './src/index.js',
// 输出
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.bundle.js',
},
// loader 配置
module: {
rules: [
{
test: /\.(png|gif|jpe?g)$/,61
use: {
loader: 'url-loader',
options: {
limit: 2 * 1024, // 2 kb 设置图⽚⼤⼩,⼩于该数值的图⽚会被转成 base64
name: "images/[name].[ext]"
}
},
}
]
},
// plugin 配置
plugins: [
new HtmlWebpackPlugin({
title: "Webpack Demo",
template: "./src/index.html"
})
]
};
上述配置可以处理样式⽂件中的图⽚引⼊,例如:
body {
/* background-color: #dbf; */
background: url(./images/1.jpg) no-repeat;
}
HTML 中的图⽚引⼊
安装(npm install html-loader -D)
配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// 打包模式
mode: 'development',
// ⼊⼝⽂件
entry: './src/index.js',
// 输出
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.bundle.js',
},
// loader 配置
module: {
rules: [
{
test: /\.(png|gif|jpe?g)$/,
use: {
loader: 'url-loader',
options: {
limit: 2 * 1024, // 2 kb
name: "images/[name].[ext]",
// url-loader 默认采⽤ ES Module 进⾏解析,⽽ html-loader引⼊图⽚使⽤的是 CommonJS
// 解决:关闭 url-loader 的 ES Module 解析,使⽤ CommonJS进⾏解析
esModule: false
}
},
},
{
test: /\.(htm|html)$/i,
// 负责处理 HTML 中的 img 图⽚
loader: 'html-loader',
options: {
// webpack4 中只需要在 url-loader 配置 esModule:false
// webpack5 需要 html-loader 也配置 esModule:false
esModule: false
}
}
]
},
// plugin 配置
plugins: [
new HtmlWebpackPlugin({
title: "Webpack Demo",
template: "./src/index.html"
})
]
};
html-loader 与 html-webpack-plugin 冲突
问题
⼊⼝⻚⾯中默认使⽤的 lodash 模板未被解析⽣效。
虽然 html-loader 可以解决 HTML ⽂件中的图⽚加载问题,但 HTML 中的 ejs 语法失效了
原因
⼊⼝⻚⾯中默认使⽤的 lodash 模板未被解析⽣效。
虽然 html-loader 可以解决 HTML ⽂件中的图⽚加载问题,但 HTML 中的 ejs 语法失效了
- 这⾥,我们已经声明了通过 html-loader 来处理 html ⽂件,因此 ejs 语法失效
这⾥,我们已经声明了通过 html-loader 来处理 html ⽂件,因此 ejs 语法失效
const _ = require('lodash');
module.exports = function (source) {
// Get templating options
const options = this.getOptions();
const force = options.force || false;
const allLoadersButThisOne = this.loaders.filter((loader) => lo
ader.normal !== module.exports);
// 如果有其他 loader 进⾏处理,则直接返回
if (allLoadersButThisOne.length > 0 && !force) {
return source;
}
// 否则使⽤ lodash.template 的模板进⾏语法解析
const template = _.template(source, {
interpolate: /<%=([\s\S]+?)%>/g,
variable: 'data', ...options
});
解决
将模板⽂件统⼀为 ejs 格式
- 先通过 htmlWebpackPlugin 处理 ejs ⽂件,然后 html-loader 继续做后续处理
- 修改模板⽂件后缀(src/index.html => src/index.ejs)
- 修改配置中的模板名称
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./src/index.ejs", // 这⼀⾏
title: "Webpack Demo",
})
]
- 将模板⽂件中的图⽚引⼊,改成 ejs 语法
<!-- 旧写法 -->
<img src="./images/xph.gif" alt="">
<!-- 新写法 -->
<img src="<%= require('./images/xph.gif') %>" alt="">
打包字体
下载字体⽂件
https://www.iconfont.cn/
file-loader
module.exports = {
// ....
// 模块配置
module: {
rules: [
// 匹配字体⽂件
{
test: /\.(eot|svg|ttf|woff|woff2)$/i,
use: {
loader: 'file-loader',
options: {
name: 'fonts/[name].[ext]'
}
}
}
]
}
}
copy-webpack-plugin
不需要处理的其他⽂件,可以直接复制到输出⽬录
https://www.npmjs.com/package/copy-webpack-plugin
clean-webpack-plugin
每次打包之前,先删除输出⽬录中的历史⽂件(保证输出⽬录中的打包⽂件是最新的)
https://www.npmjs.com/package/clean-webpack-plugin
资源模块(asset modules)
Webpack 5 提供了⼀个新的特性 - 资源模块。通过资源模块也可以加载图⽚或字体,⽽⽆需使⽤ loader
module.exports = {
// ....
// 模块配置
module: {
rules: [
// 处理图⽚
{
test: /\.(png|gif|jpe?g)$/i,
// use: {
// loader: "url-loader",
// options: {
// // 指定图⽚⼤⼩,⼩于该数值的图⽚,会被转成 base64
// limit: 8 * 1024, // 8 kb
// // [name] 是图⽚原来的名称
// // [ext] 是图⽚原来的后缀名
// name: "image/[name].[ext]",
// // url-loader 默认采⽤ ES Modules 规范进⾏解析,但是 html-loader 引⼊图⽚使⽤的是 CommonJS 规范
// // 解决:关闭 url-loader 默认的 ES Modules 规范,强制 url-loader 使⽤ CommonJS 规范进⾏打包
// esModule: false
// }
// }
// 使⽤资源模块
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
filename: "image/[name][ext]"
}
},
// 匹配字体⽂件
{
test: /\.(eot|svg|ttf|woff|woff2)$/i,
// use: {
// loader: 'file-loader',
// options: {
// name: 'fonts/[name].[ext]'
// }
// }
// 使⽤资源模块处理字体⽂件
// asset 可以在 asset/resource 和 asset/inline 之间进⾏选择
// 如果⽂件⼩于 8kb,则使⽤ asset/inline 类型
// 如果⽂件⼤于 8kb,则使⽤ asset/resource 类型
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
filename: "fonts/[name][ext]"
}
},
]
}
}
资源模块(Asset Modules)
https://webpack.docschina.org/guides/asset-modules/
资源模块(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 和发送⼀个单独的⽂件之间⾃动选择。之前通过使⽤ urlloader,并且配置资源体积限制实现。
即:不需要上述 loader,我们在 Webpack 5 中,也可以处理图⽚字体等资源⽂件
例如:
module.exports = {
// ......
// 模块配置
module: {
rules: [
// 处理图⽚
// {
// test: /\.(png|gif|jpe?g)$/i,
// use: {
// loader: "url-loader",
// options: {
// // 指定图⽚⼤⼩,⼩于该数值的图⽚,会被转成 base64
// limit: 8 * 1024, // 8 kb
// // [name] 是图⽚原来的名称
// // [ext] 是图⽚原来的后缀名
// name: "image/[name].[ext]",
// // url-loader 默认采⽤ ES Modules 规范进⾏解析,但是 html-loader 引⼊图⽚使⽤的是 CommonJS 规范
// // 解决:关闭 url-loader 默认的 ES Modules 规范,强制 url-loader 使⽤ CommonJS 规范进⾏打包
// esModule: false
// }
// }
// },
// 通过资源模块来处理图⽚
{
test: /\.(png|gif|jpe?g)$/i,
type: 'asset',
// 现在,webpack 将按照默认条件,⾃动地在 resource 和 inline 之间进⾏选择:
// ⼩于 8kb 的⽂件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。
// ⾃定义设置
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
filename: "image/[name][ext]" // 单独指定 名字
}
},
// 通过资源模块来处理字体
{
test: /\.(eot|svg|ttf|woff|woff2)$/i,
// use: {
// loader: 'file-loader',
// options: {
// name: 'fonts/[name].[ext]'
// }
// }
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
filename: "fonts/[name][ext]" // 单独指定 名字
}
},
// ......
]
}
}
开发服务器(Dev Server)
Webpack Dev Server(Webpack 开发服务器),https://www.npmjs.com/package/webpack-dev-server
安装 (https://www.npmjs.com/package/webpack-dev-server 或 npm i webpack-dev-server -g)
运行
1 # webpack 4
2 webpack-dev-server ...
3
4 # webpack 5
5 webpack server ...
- Webpack Dev Server 将打包内容放到内存中(⽽⾮磁盘),内存的读写性能远⼤于磁盘,因此
Webpack Dev Server 的热更新效率⼤于 browser-sync
运⾏ 并 ⾃动打开浏览器 (webpack server --open)
为 Webpack Dev Server 指定配置
devServer: {
// 项⽬构建后路径
contentBase:resolve(__dirname,'output'),73
// 启动gzip压缩
compress:true,
// 端⼝号
port:3000,
// ⾃动打开浏览器
open: true,
// 开启热更新
hot: true,
// 开启接⼝代理
proxy: {
'/api': {
// http://localhost:8080/api/users -> https://api.github.co
api/users
target: 'https://api.github.com',
// http://localhost:8080/api/users -> https://api.github.co
users
pathRewrite: {
'^/api': ''
},
// 不能使⽤ localhost:8080 作为请求 GitHub 的主机名
changeOrigin: true
}
}
},
更多配置详情:https://webpack.docschina.org/configuration/dev-server