# webpack5搭建React开发脚手架
# 1. 初始化npm环境
npm init -y
生成package.json文件
# 2. 本地安装webpack、webpack-cli
npm install webpack webpack-cli -D
webpack@5.64.4
webpack-cli@4.9.1
# 3. 最基本目录结构及配置
npm install webpack-dev-server html-webpack-plugin webpack-merge -D
- 当前目录结构
配置步骤
webpack.config.base.js
配置入口、出口、模板plugin
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: path.resolve(__dirname, '../src/index.js'), output: { filename: 'boundle.js', path: path.resolve(__dirname, '../dist'), clean: true, }, plugins: [ new HtmlWebpackPlugin({ title: 'webpack5从0到1搭建React开发脚手架' }) ] }webpack.config.dev.js
配置开发服务器相关参数、source-map
const path = require('path'); const { merge } = require('webpack-merge'); const baseConfig = require('./webpack.config.base'); module.exports = merge(baseConfig, { mode: 'development', devServer: { static: { directory: path.resolve(__dirname, '../dist'), }, port: 9000, hot: true, open: true, }, devtool: 'source-map', })webpack.config.build.js
const { merge } = require('webpack-merge'); const baseConfig = require('./webpack.config.base'); module.exports = merge(baseConfig, { mode: 'production', })package.json
"scripts": { "start": "webpack serve --config ./build/webpack.config.dev.js", "build": "webpack --config ./build/webpack.config.build.js" },
# 4. babel-loader配置
npm install -D babel-loader @babel/core @babel/preset-env
npm install -D @babel/plugin-transform-runtime @babel/runtime
npm install -S corejs@3
webpack.config.base.js 增加如下配置内容:
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
}
],
],
plugins: ['@babel/plugin-transform-runtime'],
cacheDirectory: true,
}
}
}
]
},
# 5. 配置支持react语法
npm install -D @babel/preset-react
npm install -S react react-dom
wepack.config.base.js内容修改:
module: {
rules: [
{
-- test: /\.jsx?$/,
++ test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
-- plugins: ['@babel/plugin-transform-runtime'],
++ presets: [
['@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3
}
],
'@babel/preset-react'
],
plugins: ['@babel/plugin-transform-runtime'],
cacheDirectory: true,
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
-- title: 'webpack5从0到1搭建React开发脚手架',
template: path.resolve(__dirname, '../index.html'),
})
]
根目录增加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从0到1搭建React开发脚手架</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
新建src/App.jsx和src/index.js进行React基本测试
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App />, document.getElementById('app'));
App.jsx:
import React from 'react';
export default function App() {
return <div>
react jsx!
</div>
}
# 5.1 解析扩展名
让import Counter from './components/counter';能解析到counter下的入口文件。
webpack.config.base.js:
resolve: {
extensions: ['.js', '.jsx'],
},
# 6. 配置Sass-loader及抽取压缩css
npm install -S sass sass-loader css-loader style-loader
npm install -D mini-css-extrat-plugin css-minimizer-webpack-plugin
开发模式下:
不用抽离和压缩css。
webpack.config.dev.js:
module: {
rules: [
{
test: /\.(css|scss|sass)$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
生成模式下:
有必要抽离和压缩css。
webpack.config.build.js:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module: {
rules: [
{
test: /\.(css|scss|sass)/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader'
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'styles/[contenthash].css'
})
],
optimization: {
minimizer: [
new CssMinimizerPlugin()
]
}
# 6.1 配置postcss
npm install -D postcss-loader postcss postcss-preset-env
修改配置文件:webpack.config.dev/build.js
rules: [
{
test: /\.(css|scss|sass)$/,
use: [
'style-loader', 'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
['postcss-preset-env']
]
}
}
},
'sass-loader'
]
}
]
# 7. 配置图片资源解析 AssetModules
webpack5新增的4种AssetModules类型,可以用来代替以往的file-loader、url-loader。
webpack.config.base.js新增:
{
test: /\.(png|jpg|jpeg|gif)$/,
type: 'asset/resource',
generator: {
filename: 'images/[contenthash][ext]'
}
},
{
test: /\.svg$/,
type: 'asset',
generator: {
filename: 'images/[contenthash][ext]',
},
parser: {
dataUrlCondition: {
maxSize: 4 * 1024
}
}
}
# 8. 配置字体图标
以阿里字体图标为例子。https://www.iconfont.cn/下载字体文件。
# 8.1 Symbol方式接入(推荐方式):
第一步:引入项目下面生成的 symbol 代码:
# <script src="./iconfont.js"></script>
React中推荐用模块方式导入:
import './iconfont.js'
第二步:加入通用 CSS 代码(引入一次就行):
<style>
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
第三步:挑选相应图标并获取类名,应用于页面:推荐封装成组件
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-xxx"></use>
</svg>
这一步有注意事项:
1. xlink:href要改成camelCase,即:xlinKHref。
# 8.2 font-class引用:
webpack.config.base.js:
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
type: 'asset/resource',
generator: {
filename: 'font/[name][ext]',
}
}
第一步:引入字体图标文件:
# 新建font文件夹,放入iconfont.ttf等字体文件
# 修改iconfont.css字体图标文件路径:
@font-face {
font-family: "iconfont"; /* Project id */
src: url('./font/iconfont.ttf?t=1638679880337') format('truetype');
}
第二步:引入项目下面生成的 fontclass 代码:
<link rel="stylesheet" href="./iconfont.css">
第三步:挑选相应图标并获取类名,应用于页面:
<span class="iconfont icon-xxx"></span>
# 9. 配置编译目标target
package.json: 编译后的文件支持哪些浏览器版本
"browserslist": [
"last 2 versions",
"> 1%",
"IE 10"
],
webpack.config.base.js:
target: 'browserslist',
# 10. 配置ESLint
可以安装eslint-loader进行eslint规范提示。
为了能在编写代码的同时查看到Eslint提示,推荐以下配置方式。
第一步:安装Eslint插件。(vscode插件市场安装即可)
第二步:安装eslint包。
npm install -D eslint
第三步:生成eslint配置文件.
npx eslint --init
# 根据提示完成选择即可
# 过程中可能会安装一些lint插件,比如react hooks相关的lint插件。
第四步:修改eslint配置文件如下:
以下是完成react hooks的规则,其他规则可自行在rules下定义。
生成配置文件时可以选择.json、.js、.yaml几种格式,以下使用的是.json方式
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"plugin:react/recommended",
"plugin:react-hooks/recommended"
],
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"react"
],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"no-console": "warn",
}
}
第五步:忽略不需要进行eslint检查的文件或文件夹
.eslint.json文件同级目录新建.eslintignore文件。
build
# 11. 配置打包压缩
生成环境有可能需要将打包结果进行压缩。
npm install -D filemanager-webpack-plugin
webpack.config.build.js增加:
const FileManagerPlugin = require('filemanager-webpack-plugin');
# plugins增加:
new FileManagerPlugin({
events: {
onEnd: {
copy: [{
source: path.resolve(__dirname, '../src/text.json'),
destination: 'dist/text.json'
}],
archive: [
{
source: path.resolve(__dirname, '../dist'),
destination: `dist/production_${new Date().getTime()}.tar.gz`,
format: 'tar',
options: {
gzip: true,
gzipOptions: {
level: 1,
},
globOptions: {
nomount: true,
},
}
}
]
}
},
runTasksInSeries: true,
})
# 12. 一些优化
输出js路径及名称,。
webpack.config.base.js:
output: { filename: 'scripts/[name].[contenthash].boundle.js', path: path.resolve(__dirname, '../dist'), pathinfo: false, clean: true, },将src目录定义一个别名,简短模块化导入路径。
webpack.config.base.js:
resolve: { extensions: ['.js', '.jsx'], alias: { '@': path.resolve(__dirname, '../src') } },optimization配置优化。
webpack.config.build.js:
optimization: { runtimeChunk: true, minimizer: [ new CssMinimizerPlugin() ], splitChunks: { chunks: 'all', cacheGroups: { commons: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', }, }, } }
← 服务器环境初始化 Axios-HTTP库 →