一:初始化环境
初始化 package.json文件
yarn init -y
安装Webpack
webpack-cli 是webpack的命令行工具,可以在命令行中使用webpack
yarn add -D webpack webpack-cli
配置react支持
yarn add react react-dom
在根目录下创建webpack.config.js 文件
二:配置react环境
配置babel环境支持
- babel-loader
- @babel/core
- @babel/preset-env
- @babel/plugin-transform-runtime
- @babel/preset-react
babel-loader 将jsx文件转译为JS文件
jsx文件写出来的Dom,实际上会通过bable 翻译成对象的形式
@babel/core 内部核心模块的转译实现
babel-loader 仅仅是识别出了jsx 文件,内部的核心模块的转译需要@babel/core 实现
@babel/preset-env 将基础的ES6语法向下转译,兼容不同的浏览器
@babel/preset-env 只会转译一些低级的ES6语法,高级的语法,async await ,Promise是无法转换的
@babel/plugin-transform-runtime 转译高级的ES6语法
@babel/plugin-transform-runtime 将高级的ES6语法向下转译,兼容不同的浏览器
@babel/preset-react
内置了一系列babel plugin去转化jsx代码成为我们想要的js代码
安装babel环境插件
yarn add -D @babel/core @babel/preset-env babel-loader @babel/plugin-transform-runtime @babel/preset-react
在根目录下的webpack.config.js 文件中进行配置
{
test: /\.jsx?$/,
use: "babel-loader",
},
在根目录下新建.babelrc文件
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"regenerator": true
}
]
]
}
在根目录下新建src文件夹,src文件夹下新建index.jsx 文件
import React from "react";
import ReactDOM from "react-dom";
const App = () => {
return (
<div>Webacpk5</div>
)
}
ReactDOM.render(<App />, document.getElementById("root"));
在根目录下新建public文件夹,pubilc文件夹下新建index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>webpack5</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
三:配置HTML页面
html-webpack-plugin
创建一个html文件,并把Webpack打包后的静态资源插入到该HTML文件中
安装 html-webpack-plugin
yarn add --dev html-webpack-plugin
在webpack.config.js 文件中顶部,引入html-webpack-plugin
const htmlWebpackPlugin = require("html-webpack-plugin");
在模块中配置插件的规则
new htmlWebpackPlugin({
filename: "index.html",
template: path.resolve(__dirname, "./public/index.html"),
}),
四:配置热更新
webpack-dev-server
webpack为我们提供了devServer配置,支持我们每次更新代码热重载
安装 webpack-dev-server
yarn add -D webpack-dev-server
在wepack.config.js 文件下,创建devServer对象
devServer: { // 服务
// 当使用 [HTML5 History API] 时,任意的 `404` 响应被替代为 `index.html`
historyApiFallback: true,
open: true, // 自动打开浏览器
// 默认为true
hot: true,
// 是否开启代码压缩
compress: true,
// 启动的端口
port: 9000,
},
在package.json 新增调试命令
"scripts": {
"start": "webpack serve",
"build": "webpack"
},
打开终端,执行npm start
成功运行,一个简易的react Webpack5已经配置好了
清空每次打包后dist残留的文件
yarn add -D clean-webpack-plugin
每次打包后,磁盘会残留之前打包的文件,每次打包前需要清除这些文件
安装 yarn add -D clean-webpack-plugin
yarn add -D clean-webpack-plugin
在webpack.config.js 文件的顶部引入clean-webpack-plugin 插件
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
在plugins 中,启用插件
new CleanWebpackPlugin(),
五:配置图片和字体
assets模块是webpack5自带,不用下载
// 图片
{
test: /\.(png|jpe?g|svg|gif)$/,
type: "asset/inline",
},
// 字体
{
test: /\.(eot|ttf|woff|woff2)$/,
type: "asset/resource",
generator: {
filename: "fonts/[hash][ext][query]",
},
},
六:配置路径别名
在webpack.config.js 文件下新建resolve对象
resolve: { // 别名
alias: {
"@": path.resolve(__dirname, "./src"),
},
mainFiles: ["index", "main"],
},
七:JS压缩
webpack5 自带最新的 terser-webpack-plugin
在webpack.config.js文件的顶部引入terser-webpack-plugin模块
const TerserPlugin = require("terser-webpack-plugin");
在webpack.config.js文件下 新建optimization对象,进行如下配置
new TerserPlugin({
parallel: 4, // 并发数量
terserOptions: {
parse: {
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
inline: 2,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
scii_only: true,
},
},
}),
八:CSS的配置
配置CSS文件的支持,这里配置是对less支持,如果要支持sass支持,将less改为sass即可
- postcss-loader
- css-loader
- MiniCssExtractPlugin
- MiniCssExtractPlugin
- style-loader
postcss-loader
postcss-loader 同时支持直接在loader中配置规则选项,也支持单独建立文件配置,这里我们选择单独使用文件进行配置:
安装后续用到的插件
yarn add -D cssnano autoprefixer@latest postcss-loader postcss
yarn add less less-loader --dev
新建一个postcss.config文件在根目录下
// 单独文件配置插件postcss-loader的规则
// 此处使用到 autoprefixer cssnano 两个插件
// autoprefixer 为CSS内容添加浏览器厂商前缀兼容
// cssnano 尽可能小的压缩CSS代码
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano')({
preset: 'default',
}),
],
}
css-loader
解析CSS文件中的@import/require
安装css-loader
yarn add -D css-loader
在module模块中增加如下规则
// CSS和Less
{
test: /\.(sa|sc|le|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
"css-loader",
"postcss-loader",
// 当解析antd.less,必须写成下面格式,否则会报Inline JavaScript is not enabled错误
{
loader: "less-loader",
options: { lessOptions: { javascriptEnabled: true } }},
],
},
MiniCssExtractPlugin
为每个包含CSS 的 JS 文件创建一个 CSS 文件。它支持按需加载 CSS 和 SourceMaps
MiniCssExtractPlugin 和 style-loader 的区别
- style-loader 是将CSS 插入到HTML的头部文件中
- MiniCssExtractPlugin 是将拆分生成CSS 形成单独的CSS文件
安装 MiniCssExtractPlugin
yarn add -D mini-css-extract-plugin
在webpack.config.js文件顶部引入模块
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
在插件模块中开启插件
// 开启压缩CSS插件
new MiniCssExtractPlugin({
filename: "assets/[name].css",
}),
九:编译进度条
progress-bar-webpack-plugin
查看编译进度
安装 progress-bar-webpack-plugin
yarn add progress-bar-webpack-plugin --dev
在文件的顶部引入对应的模块
// 编译进度条
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
在插件规则中开启编译进度条插件
new ProgressBarPlugin({
format: `:msg [:bar] ${chalk.green.bold(':percent')} (:elapsed s)`
})
十:根据不同环境,拆分webpack.config.js文件
webpack-merge
使用 webpack-marge 合并通用配置和特定环境配置
安装 webpack-merge
yarn add webpack-merge --dev
在根目录下新建config文件夹,新建webpack.common, webpack.dev, webpack.pre
webpack.common
// webpack-merge
// 使用 webpack-marge 合并通用配置和特定环境配置
// yarn add webpack-merge --dev
const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // css抽离
const chalk = require('chalk')
const ProgressBarPlugin = require('progress-bar-webpack-plugin') // 编译进度条
module.exports = {
resolve: {
// 配置路径别名
alias: {
'@': path.resolve(__dirname, './src'),
},
mainFiles: ['index', 'main'],
},
module: {
rules: [
{
test: /\.jsx?$/,
use: 'babel-loader',
},
{
test: /\.(le|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
'postcss-loader',
// 当解析antd.less,必须写成下面格式,否则会报Inline JavaScript is not enabled错误
{ loader: 'less-loader', options: { lessOptions: { javascriptEnabled: true } } },
],
},
{
test: /\.(png|jpe?g|svg|gif)$/,
type: 'asset/inline',
},
{
test: /\.(eot|ttf|woff|woff2)$/,
type: 'asset/resource',
generator: {
filename: 'fonts/[hash][ext][query]',
},
},
],
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../public/index.html'),
}),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: 'assets/[name].css',
}),
// 进度条
new ProgressBarPlugin({
format: ` :msg [:bar] ${chalk.green.bold(':percent')} (:elapsed s)`,
}),
],
}
webpack.dev
const { merge } = require('webpack-merge')
const common = require('./webpack.common')
module.exports = merge(common, {
mode: 'development',
// 开发工具,开启 source map,编译调试
devtool: 'eval-cheap-module-source-map',
cache: {
type: 'filesystem', // 使用文件缓存
},
entry: './src/index.jsx',
devServer: {
historyApiFallback: true,
open: true, // 自动打开页面
// 默认为true
hot: true,
// 是否开启代码压缩
compress: true,
// 启动的端口
port: 8888,
},
})
webpack.pre
const TerserPlugin = require('terser-webpack-plugin') // js压缩
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') // css压缩
const { merge } = require('webpack-merge')
const common = require('./webpack.common')
module.exports = merge(common, {
mode: 'production',
entry: './src/index.jsx',
output: {
path: __dirname + '/../dist',
// [contenthash:8] - 本应用打包输出文件级别的更新,导致输出文件名变化
filename: '[name]-[contenthash:8].js',
// 编译前清除目录
clean: true,
},
//terser-webpack-plugin 默认开启了 parallel: true 配置,并发运行的默认数量: os.cpus().length - 1 ,
// 配置的 parallel 数量为 4,使用多进程并发运行压缩以提高构建速度。
optimization: {
// 通过配置 optimization.runtimeChunk = true,为运行时代码创建一个额外的 chunk,减少 entry chunk 体积,提高性能。
// runtimeChunk: true,
minimizer: [
new TerserPlugin({
parallel: 4,
terserOptions: {
parse: {
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
inline: 2,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
},
}),
new CssMinimizerPlugin({
parallel: 4,
}),
],
},
})
修改package.json 文件中的调试命令
"scripts": {
"start": "webpack serve --config config/webpack.dev.js",
"build": "webpack --config config/webpack.prd.js"
},