一、webpack概述
1、介绍
简单来说,webpack就是将我们使用框架写好的预处理语言,转换为浏览器能识别的js、css语言的工具
2、核心概念
主要分以下几大概念:
entry(入口): webpack打包的入口文件
output(输出文件):定义打包生成的文件名、路径等
loader(加载器):webpack本身只能打包js、json等资源,其他资源需要借助loader,做更进一步的处理
plugins(插件):可通过插件扩展webpack的功能
mode(模式):主要分为开发模式(development)和生产模式(production)
二、开发模式配置
1、基本配置
在开发环境按照webpack
npm i -D webpack webpack-cli
安装完成后,在项目根目录下创建文件webpack.config.js
//webpack.config.js,基于commonjs规范编写
module.exports = {
//入口
entry:"",
//输出
output:{},
//loader
module:{
rules:[]
},
//插件
plugins:[]
//模式
mode:""
}
按标准的目录结构,初始化webpack配置文件
//webpack.config.js,基于commonjs规范编写
module.exports = {
//入口
entry:"./src/main.js",
//输出
output:{
path:path.resolve(__dirname,"dist"),
filename:"main.js"
},
//loader
module:{
rules:[]
},
//插件
plugins:[]
//模式
mode:"development"
}
配置完后,运行打包命令打包
npx webpack
2、处理样式资源
1、css
rules:[{
// 匹配处理css文件
test: /\.css$/,
// 加载顺序,从右到左,从下到上
use: ["style-loader", "css-loader"],
}]
2、less、saas、stylus(以less为例)
rules:[{
test: /\.less$/,
//loader: "" loader只能维护一个加载器
use: ["style-loader", "css-loader", "less-loader"],
}],
3、处理图片资源
rules:[{
test: /\.(jpe?g|png|gif|svg)$/,
type: "asset",
parser: {
// 限制assert资源,能够支持uri打包的文件大小,小于该文件大小的将按asset自动转Base64文本
// 转base64后,可以减少服务器的请求数量,提高加载速度,缺点就是文件会变大
dataUrlCondition: { maxSize: 80 * 1024 },
},
// 将图片文件输出到 static/imgs 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
generator: { filename: "static/imgs/[hash:8][ext][query]" },
},]
4、处理字体资源
rules:[{
test: /\.(ttf|woff2?)$/,
// 视频类的资源,type也是asset/resourc
type: "asset/resource",
generator: { filename: "static/media/[hash:8][ext][query]" },
}],
5、处理其他资源
rules:[{
test: /\.(ttf|woff2?|map4|map3|avi)$/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:8][ext][query]",
}]
6、处理js资源
由于webpack只能处理ES模块化语法,但是不能转换其他语法。这样可能会导致js其他代码不能适配IE浏览器,因此需要通过代码检查和转换工具进行处理:
eslint:代码格式检查工具
babel:js代码转换工具
我们先通过eslint检查代码是否符合规范,然后再通过bebel进行转换
6.1 eslint
6.1.1 eslint介绍
eslint是检查js和jsx语法的工具,我们先引入eslint,并且通过配置文件rules规则,定义不同的代码检查规范
配置文件内容如下:
//以.eslintrc.js为例:
module.exports ={
//可供继承的其他规则
extends:[],
//解析选项
parseOptions:{},
//具体检查规则,参考文档地址:https://eslint.nodejs.cn/docs/latest/rules/
/**错误规则分三种:
* off或0,不检查该项规则
* warn或1,开启规则,警告,但是不影响程序运行
* error 或 2,开启规则,错误,当被触发时,程序会退出
*/
rules:{}
}
//配置选项
parserOptions: {
ecmaVersion: 6, // ES 语法版本
sourceType: "module", // ES 模块化
ecmaFeatures: { // ES 其他特性
jsx: true // 如果是 React 项目,就需要开启 jsx 语法
}
}
extends 继承:
开发中一点点写 rules 规则太费劲了,所以有更好的办法,继承现有的规则。
现有以下较为有名的规则:
- Eslint 官方的规则open in new window:
eslint:recommended
- Vue Cli 官方的规则open in new window:
plugin:vue/essential
- React Cli 官方的规则open in new window:
react-app
6.1.2 集成webpack
1、先下载eslint包
npm i -D eslint eslint-webpack-plugin
2、新建配置文件.eslintrc.js
//.eslintrc.js
module.exports = {
// 继承 Eslint 规则
extends: ["eslint:recommended"],
env: {
node: true, // 启用node中全局变量
browser: true, // 启用浏览器中全局变量
},
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
},
rules: {
/**错误规则分三种:
* off或0,不检查该项规则
* warn或1,开启规则,警告,但是不影响程序运行
* error 或 2,开启规则,错误,当被触发时,程序会退出
*/
"no-var": 2, // 不能使用 var 定义变量
"no-console": "off",
},
};
3、在webpack.config.js中引入eslint
const eslintPlugin= require("eslint-webpack-plugin");
/***在plugins中引入,此处的用法可以参考npm官网:https://www.npmjs.com/package/eslint-*webpack-plugin*/
//context 指定了需要检查文件的根目录
module.exports = {
……
plugins:[new eslintPlugin({context:XXXXX})]
……
}
4、运行打包指令,就可以看到检查效果
npx webpack
5、此外,我们也可以直接在vscode中安装eslint扩展,安装后不用编译也能进行检查
不过安装扩展后eslint是全局检查,需要在项目根目录上新建.eslintignore忽略一些文件
//.eslintigonre
dist
6.2 babel
6.2.1 babel介绍
可以通过在根目录新建babel.config.js,配置解析规则
//babel.config.js
module.exports= {
//可以在presets预设中配置解析器
presets:[]
}
presets 预设:
简单理解就是一组 Babel 插件, 扩展 Babel 功能
@babel/preset-env
: 一个智能预设,允许您使用最新的 JavaScript。@babel/preset-react
:一个用来编译 React jsx 语法的预设@babel/preset-typescript
:一个用来编译 TypeScript 语法的预设
6.2.2 集成webpack
1、安装包
npm i babel-loader @babel/core @babel/preset-env -D
2、在webpack.config.js loader中集成,可参考babel-loader | webpack 中文文档
module.exports ={
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
loader:"babel-loader"
}
]
}
3、在根目录新建babel.config.js,定义配置文件
module.exports = {
presets: ["@babel/preset-env"],
};
4、运行指令npx webpack,此时查看打包后的js文件,es6的箭头函数等语法就转换为常规的js函数
7、处理html资源
webpack支持自动生成一个html5文件,并且在body中自动引入所有webpack生成的文件,如果我们同时还引用了MiniCssExtractPlugin,会在head中的link标签中引入
1、安装包
npm install --save-dev html-webpack-plugin
2、在webpack.config.js plugins中引入
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: 'index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js',
},
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
plugins: [new HtmlWebpackPlugin({template:path.reslove(__dirname,"public/index.html")})],
};
8、其他配置
自动清空上次打包文件:
通过在webpack.config.js中output新增配置clean:true即可
配置开发服务器:
安装webpack-dev-server
//因为兼容性问题,如果nodejs的版本是16,则需要指定webpack-dev-server为4.0的版本
npm i -D webpack-dev-server
安装后,在webpack.config.js中配置开发服务器信息devServer
//webpack.config.js,基于commonjs规范编写
module.exports = {
//入口
entry:"./src/main.js",
//输出
output:{
path:path.resolve(__dirname,"dist"),
filename:"main.js"
},
//loader
module:{
rules:[]
},
//插件
plugins:[]
devServer:{
host:"localhost", //开发服务器地址
port:"3000",
open:true //是否自动打开浏览器
}
//模式
mode:"development"
}
配置后运行自动启用服务命令,启动开发服务器
注:内存编译打包没有输出
npx webpack serve
三、生产环境配置
说明:生产环境打包,除了开发环境的以上打包内容外,还需要对代码进行优化,让其打包的性能更好,打包后的代码在线上的运行性能更佳
1、css处理
1.1、提取css为单独文件
按以上开发环境的打包,css被打包到js文件中,在浏览器中会在style标签中加载,这样可能会出现闪屏,因此需要将css文件提取出来,在link标签中加载
1、安装mini-css-extract-plugin
npm i -D mini-css-extract-plugin
2、在plugins中加载该插件
const miniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
// 入口,入口文件为相对路径
entry: "./src/main.js",
// 输出
output: {
// 输出文件必须为绝对路径
path: path.resolve(__dirname, "../dist"),
filename: "static/js/main.js",
clean: true,
},
// 加载器
module: {
rules: [
{
// 匹配处理css文件
test: /\.css$/,
// 加载顺序,从右到左,从下到上
use: [ miniCssExtractPlugin.loader,"css-loader"],
},
{
test: /\.less$/,
//loader: "" loader只能维护一个加载器
use: [ miniCssExtractPlugin.loader,
"css-loader","less-loader"],
},
],
},
// 插件
plugins: [
//定义输出的css目录及文件名
new miniCssExtractPlugin({ filename: "static/css/main.css" }),
],
// devServer: { host: "localhost", port: "3030", open: true },
//模式
mode: "production",
};
加载后运行打包命令npm run prod即可
1.2、css兼容性处理
通过postcss-loader,控制css后的代码兼容性
1、安装包
npm i postcss-loader postcss postcss-preset-env -D
2、配置loader
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
{
// 其他选项
},
],
],
},
},
},
],
},
],
},
};
3、在package.json中新增browserList配置项,控制css代码的兼容性
{
"browserList": [
"last 4 version",
"> 1%",
"not dead"
]
}
1.3、css压缩
1、安装包
npm i css-minimizer-webpack-plugin -D
2、在webpack.config.js中配置插件
const path = require("path");
const EslintPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { Template } = require("webpack");
const miniCssExtractPlugin = require("mini-css-extract-plugin");
const cssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
function getStyleLoader(processer) {
return [
miniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: { postcssOptions: { plugins: ["postcss-preset-env"] } },
},
,
processer,
].filter(Boolean);
}
module.exports = {
// 入口,入口文件为相对路径
entry: "./src/main.js",
// 输出
output: {
// 输出文件必须为绝对路径
path: path.resolve(__dirname, "../dist"),
filename: "static/js/main.js",
clean: true,
},
// 加载器
module: {
rules: [
{
// 匹配处理css文件
test: /\.css$/,
// 加载顺序,从右到左,从下到上
use: getStyleLoader(),
},
{
test: /\.less$/,
//loader: "" loader只能维护一个加载器
use: getStyleLoader("less-loader"),
},
{
test: /\.(jpe?g|png|gif|svg)$/,
type: "asset",
parser: {
// 限制assert资源,能够支持uri打包的文件大小,小于该文件大小的将按asset自动转Base64文本
// 转base64后,可以减少服务器的请求数量,提高加载速度,缺点就是文件会变大
dataUrlCondition: { maxSize: 80 * 1024 },
},
// 将图片文件输出到 static/imgs 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
generator: { filename: "static/imgs/[hash:8][ext][query]" },
},
{
test: /\.(ttf|woff2?)$/,
// 视频类的资源,type也是asset/resourc
type: "asset/resource",
generator: { filename: "static/media/[hash:8][ext][query]" },
},
{ test: /\.js$/, use: ["babel-loader"], exclude: [/node_modules/] },
],
},
// 插件
plugins: [
new EslintPlugin({ context: path.resolve(__dirname, "src") }),
new HtmlWebpackPlugin({
template: path.join(__dirname, "../public/index.html"),
}),
new miniCssExtractPlugin({ filename: "static/css/main.css" }),
new cssMinimizerWebpackPlugin(),
],
// devServer: { host: "localhost", port: "3030", open: true },
//模式
mode: "production",
};
3、配置完成后,运行打包指令即可
2、html压缩
webpack在生产环境会默认进行html和js的压缩,因此无需做特殊处理