webpack中文档
步骤:
1.新建并初始化项目,编写业务源代码
2.下载webpack webpack-cli到当前项目中(版本独立),并配置局部自定义命令
npm i webpack webpack-cli --save-dev
在package.json清单文件配置 如何生成清单文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack" //配置此项即可,前面变量名自行定义,"webpack"固定
},
打包
npm run build //使用npm执行打包
修改Webpack打包入口和出口
入口配置
通过在 webpack configuration 中配置 entry
属性,来指定一个(或多个)不同的入口起点。
webpack.config.js
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, 'src/login/index.js'),
};
出口配置
通过在配置中指定一个 output
字段,来配置这些处理过程:
webpack.config.js
const path = require('path');
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js',
clean: true //生成打包后内容之前,清空之前打包的输出目录
}
通过 output.filename
和 output.path
属性,来告诉 webpack bundle 的名称,以及我们想要 bundle 生成(emit)到哪里
webpack-plugin(插件)
1.HtmlWebpackPlugin(Webpack自动生成html文件)
安装
npm i html-webpack-plugin --save-dev
配置
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
//webpack-plugin(插件)
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public/login.html'), //模板文件
filename: path.resolve(__dirname, 'dist/login/index.html') //输出文件
}),
};
打包css代码
加载器 css-loader: 解析css代码
加载器 style-loader: 把解析后的css代码插入到DOM
安装
npm i css-loader style-loader --save-dev
配置
module.exports = {
//加载器(让webpack 识别更多模块文件内容)
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
};
优化-提取css代码(MiniCssExtractPlugin)
如果由于某种原因你需要将 CSS 提取为一个文件(即不要将 CSS 存储在 JS 模块中)
安装
npm i mini-css-extract-plugin -save-dev
配置
MiniCssExtractPlugin.loader不能和"style-loader"混用
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
//webpack-plugin(插件)
plugins: [
new MiniCssExtractPlugin(),
],
//加载器(让webpack 识别更多模块文件内容)
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
优化-压缩过程(CssMinimizerWebpackPlugin)
自己写的css压缩
安装
npm install css-minimizer-webpack-plugin --save-dev
配置
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
//优化
optimization: {
//最小化
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释(保证js代码还能压缩)
// `...`,
new CssMinimizerPlugin(),
],
},
}
打包less代码
首先,你需要先安装 less
和 less-loader
npm install less less-loader --save-dev
webpack.config.js配置
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
// compiles Less to CSS
'style-loader',
'css-loader',
'less-loader',
],
},
],
},
};
打包图片
资源模块 Webpack5内置资源模块(字体,图片等)打包,无需额外loader
配置:
module: {
rules: [
{
//匹配内容
test: /\.(png|jpg|gif)$/i,
//模式
type: 'asset',
//打包输出地址
generator: {
filename: 'static/[hash][ext][query]'
}
}
],
},
Webpack搭建开发环境
1.配置:
开发模式:development | 调试代码,实施加载,模块热替换等 | 本地开发 |
生产模式: production | 压缩代码,资源优化,更轻量等 | 打包上线 |
webpack.config.js
module.exports = {
//开发环境模式
mode: 'development',
//可以不添加
plugins: [
new HtmlWebpackPlugin({
//网页标题
title: 'Development',
}),
],
};
2.安装开发工具:webpack-dev-server
npm i webpack-dev-server --save-dev
3.配置:package.json
添加一个可以直接运行 dev server 的 script:
"scripts": {
"dev": "webpack serve --open",
},
4.运行:
npm run dev
注意1:webpack-dev-server 借助http 模块创建 8080 默认服务
注意2:默认以 public 文件夹作为服务器根目录
注意3:webpack-dev-server 根据配置,打包相关代码在内存当中,以 output.path 的值作为服务器根目录(webpack.config.js设置的出口)
操作命令更改模式:
"scripts": {
"build": "webpack --mode=production",
"dev": "webpack serve --open --mode=development"
},
根据 webpack.config.js 中的 mode 变量更改打包行为
方案1:webpack.config.js 配置导出函数,但是局限性大(只接受2种)
方案2:借助cross-env (跨平台通用)包命令,设置参数区分环境
步骤:
1.安装
npm i cross-env --save-dev
2.配置自定义命令,传入参数名和值(会绑定到process.env对象下)
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "cross-env NODE_ENV=production webpack --mode=production",
"dev": "cross-env NODE_ENV=development webpack serve --open --mode=development"
},
3.在webpack.config.js区分不同环境使用不同的配置,然后重新打包
module: {
rules: [
{
test: /\.css$/i,
// use: ["style-loader", "css-loader"],
use: [process.env.NODE_ENV === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader, "css-loader"],
},
]
}
方案3:配置不同的webpack.config.js (适用多种模式差异性较大情况)
前端-注入环境变量
作用:在编译时,将前端代码中匹配的变量名,替换为值或表达式
需求:前端项目中,开发模式下打印语句生效,生产模式下打印语句失效
问题:cross-env 设置的只在 Node.js 环境生效,前端代码无法访问process.env.NODE_ENV
webpack.config.js
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
})
],
执行的js代码
if (process.env.NODE_ENV === 'production'){
console.log = function() {}
}
console.log('生成模式下失效打印语句')
开发环境调错 - source map
当 webpack 打包源代码时,可能会很难追踪到 error(错误)和 warning(警告)在源代码中的原始位置。
我们将使用 inline-source-map
选项,这有助于解释说明示例意图(此配置仅用于示例,不要用于生产环境):
webpack.config.js
const config = {....}
//开发环境下使用sourcemap 选项
if (process.env.NODE_ENV === 'development'){
config.devtool = 'inline-source-map'
}
module.exports = config
解析别名 alias
配置模块如何解析,创建 import 引入路径的别名,来确保模块引入变得更简单
例如:原来路径如图,比较长而且相对路径不安全
webpack.config.js
const config = {
//解析
resolve: {
//别名
alias: {
'@': path.resolve(__dirname, 'src')
},
},
}
优化-生产模式下使用CDN
开发模式使用本地第三方库,生产模式下使用 CDN 加载引入
步骤:
1. 在 html 中引入第三方库的 CDN 地址 并用模板语法判断
<% if(htmlWebpackPlugin.options.useCdn){ %>
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap-grid.min.css">
<% } %>
<% if(htmlWebpackPlugin.options.useCdn){ %>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/js/bootstrap.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.min.js"></script>
<% } %>
2. 配置 webpack.config.js 中 externals 外部扩展选项(防止某些 import 的包被打包)
const config = {
plugins: [
//html
new HtmlWebpackPlugin({
useCdn: process.env.NODE_ENV === 'production', // 生产模式引用cdn
})
]
}
//生产环境下使用相关配置
if (process.env.NODE_ENV === 'production'){
//外部扩展(让webpack 防止 import 的包被打包进来
config.externals = {
//key: import from 语句后面的字符串
//value:留在原地的全局变量(最好和cdn在全局暴露的变量一致)
'bootstrap': 'bootstrap',
'axios': 'axios',
}
}
module.exports = config
3. 两种模式下打包观察效果
优化-分割公共代码
把 2 个以上页面引用的公共代码提取
1.配置 webpack.config.js 的 splitChunks 分割功能
// ...
const config = {
// ...
optimization: {
// ...
splitChunks: {
chunks: 'all', // 所有模块动态非动态移入的都分割分析
cacheGroups: { // 分隔组
commons: { // 抽取公共模块
minSize: 0, // 抽取的chunk最小大小字节
minChunks: 2, // 最小引用数
reuseExistingChunk: true, // 当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用
name(module, chunks, cacheGroupKey) { // 分离出模块文件名
const allChunksNames = chunks.map((item) => item.name).join('~') // 模块名1~模块名2
return `./js/${allChunksNames}` // 输出到 dist 目录下位置
}
}
}
}
}
}