使用webpack5搭建可用的react开发环境
开始
前言:webpack
从入行到现在,一直都有使用,期间也断断续续的学了一些东西,文章计划记录一下自己从学习的一些东西,正好最近webpack5更新了,研究下新东西,持续更新查漏补缺吧
本文章采用版本号:5.65.0
初始化项目
1、创建文件夹,初始化npm、安装webpack
npm init // 一路enter到底
npm i webpack webpack-cli -D
2、创建项目入口文件src/index.js,这里我们写上一个console
console.log('hello')
初始化配置
1、创建webpack配置文件,设置entry(入口)、output(出口)
我们直接在当前目录下创建webpack.config.js
const path = require('path')
module.exports = {
entry: {
index: path.resolve(__dirname, 'src/index.js')
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
clean: true //每次打包前清空目录
}
}
老版本中clean是使用
clean-webpack-plugin
插件
2、添加构建命令,在package.json中的script添加build命令
"scripts": {
"build": "webpack --config webpack.config.js"
},
3、运行npm run build,如果不出意外的话,会生成dist/index.js文件,这时候我们只需要引用这个文件就ok了
html-webpack-plugin
上面执行完之后我们可能还需要一个html去引用这个js、我们可以在dist目录下手写一个index.html,但是我们开启了clean,每次打包都要手写肯定不合适,这时候我们可以用一个插件解决html-webpack-plugin
1、安装html-webpack-plugin
npm i html-webpack-plugin -D
2、在package.json中添加plugins配置
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './index.html'),
filename: 'index.html'
})
]
3、再次运行npm run build
我们可以看到build之后dist目录下自带了index.html,而且html中还自动引入了index.js,甚至还贴心的加上defer,如果考虑兼容性不想要可以添加配置
scriptLoading: 'blocking'
开发模式
现在我们能进行很简单的打包了,但是还有很多工作没做,比如我们每次改了文件,想看到效果都需要重新打包一次代码,这对开发来说很不友好,所以我们需要一个开发模式,常见的有两种,watch和devServer
watch
该模式如同名字一样,就是监听文件更改自动打包,配置也很简单,我们只需要在增加一条命令即可
"watch": "webpack --config webpack.config.js --watch"
然后我们运行npm run watch
可以看到当前进程并没有终止,尝试更改index.js,有重新执行打包,index.js内容也变更
devServer
该模式就是在本地启动一个服务,该服务可进行监听改变、自动刷新等操作
1、安装 webpack-dev-server
npm i webpack-dev-server -D
2、webpack.config.js增加配置
devServer: {
port: 3000, // 端口
open: true, // 自动打开
compress: true, //启用gzip压缩
client: {
progress: true // 浏览器打印进度
}
}
3、package.json添加命令
"dev": "webpack serve --config webpack.config.js"
完成之后我们执行npm run dev
,执行完之后浏览器会自动打开localhost:3000页面,更改index.js也会自动刷新
支持React
现在我们需要为我们的项目增加React的支持
安装babel
npm i @babel/core -D // babel核心
npm i @babel/preset-env -D // 转义js语法、promise、async等
npm i @babel/preset-react -D // 转移react相关语法(jsx)
npm i babel-loader -D //loader
配置loader
1、添加webpack配置,是的babel处理我们的js和jsx文件
module: {
rules: [
{
test: /(\.jsx|\.js)$/,
use: ["babel-loader"],
exclude: /node_modules/ // 排除node_modules文件
}
],
}
2、添加babel配置、在项目下新增babel.config.js
文件,增加如下配置
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
],
"@babel/preset-react"
]
}
3、增加.browserslistrc
文件配置browserslist
> 1%
last 2 versions
not ie <= 8
4、测试代码
index.js
import {render} from 'react-dom'
import React from 'react'
import App from './App';
render(<App />, document.getElementById('root'))
App.js
import React from 'react'
const App = () => {
return <div>Hello React</div>
}
export default App
然后运行npm run dev
可以正常运行了
处理异常
这里运行起来你可能可以看到一个警告
asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). This can impact web performance.
这是由于单个文件大小超出webpack 性能项配置的大小,性能优化后面讲解,这里可以在webpack加下面配置直接跳过
performance: {
hints: false
},
处理CSS
处理css文件 css-loader
style-loader
1、安装依赖
npm i css-loader -D // 处理css文件
npm i style-loader -D // 处理后使用style插入html中
2、在rules下面添加配置
{
test: /\.css$/,
use:["style-loader","css-loader"],
exclude: /node_modules/
},
现在我们引入一个css文件就可以看到我们打包的页面中带了一个style
处理scss文件 sass-loader
sass
1、安装依赖
npm i sass -D // sass核心
npm i sass-loader -D // loader
2、在rules下面添加配置
{
test: /\.s(a|c)ss$/,
use:["style-loader","css-loader","sass-loader"],
exclude: /node_modules/
}
分离css文件
现在我们的配置是将css打入js中,然后js执行时候使用style标签插入,这会严重增加js的包大小、在生产环境我们通常是分离css和js文件,这就需要使用到一个webpack插件mini-css-extract-plugin
,在开发环境我们依然可以使用style-loader
,因为这相比mini-css-extract-plugin
要更快
1、安装
npm i mini-css-extract-plugin -D
2、使用
...
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const IS_DEV = process.env.NODE_ENV === 'development'
...
// 修改刚才针对scss和css文件的处理
{
test: /\.css$/,
use: [IS_DEV ? "style-loader" : MiniCssExtractPlugin.loader, "css-loader"],
exclude: /node_modules/
},
{
test: /\.s(a|c)ss$/,
use: [IS_DEV ? "style-loader" : MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
exclude: /node_modules/
}
// 在plugins中添加
new MiniCssExtractPlugin({
filename: '[name].[hash].css' // 生成hash名称
}),
CSSModule
只需要在css-loader中开启modules就ok,配置如下
{
test: /\.s(a|c)ss$/,
use: [
IS_DEV ? "style-loader" : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]--[hash:base64:5]'
},
}
},
"sass-loader"
],
exclude: /node_modules/
}
使用postcss
自动添加厂商前缀
作用:自动各浏览器厂商前缀
1、安装
npm i postcss -D
npm i postcss-loader -D
npm i postcss-preset-env -D
2、配置
在webpack中处理css位置添加postcss-loader
,添加后
{
test: /\.s(a|c)ss$/,
use: [
IS_DEV ? "style-loader" : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]--[hash:base64:5]'
},
sourceMap: IS_DEV
}
},
"postcss-loader",
"sass-loader"
],
exclude: /node_modules/
}
然后根目录新建个配置文件postcss.config.js
module.exports = {
plugins: [
['postcss-preset-env']
]
}
处理文件 asset
取代 file-loader
和 url-loader
在webpack5以前,咱们处理图片资源文件一般是 file-loader
结合 url-loader
,小文件base64打入js中,大文件输出文件,webpack5直接自带了处理文件的功能assetModule
,配置起来相对简单一些
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 1 * 1024 // 1kb以下小文件打入js中
}
},
generator: {
filename: 'static/[hash][ext][query]'
}
}
区分环境
我们在开发中通常会有两个环境、开发环境和生产环境,webpack给我们提供了mode进行配置区分,而在打包配置中针对不同环境同一个loader可能配置不一样,这使得我们需要两份不同的配置文件
1、首先我们安装所需要的依赖
npm i webpack-merge -D // 合并配置文件
npm i cross-env -D // process.env兼容多环境
2、 新建一个build目录,用于放置打包配置,新建以下文件
webpack.development.js
开发环境配置
module.exports = {
mode: 'development',
performance: {
hints: false
},
devServer: {
port: 3000, // 端口
open: true, // 自动打开
compress: true, //启用gzip压缩
client: {
progress: true // 浏览器打印进度
}
}
}
webpack.production.js
开发环境配置
module.exports = {
mode: "production"
}
webpack.common.js
公共配置,dev和prod环境都会用到的配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: path.resolve(__dirname, '../src/index.js')
},
output: {
path: path.resolve(__dirname, '../dist'),
filename: '[name].js',
clean: true
},
module: {
rules: [
{
test: /(\.jsx|\.js)$/,
use: ["babel-loader"],
exclude: /node_modules/
}
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../index.html'),
filename: 'index.html',
scriptLoading: 'blocking'
})
]
}
webpack.config.js
根据环境使用不同的配置
const merge = require('webpack-merge').default;
const commonConfig = require('./webpack.common');
const devConfig = require('./webpack.development');
const proConfig = require('./webpack.production');
module.exports = () => {
if(process.env.NODE_ENV === 'development') {
return merge(commonConfig, devConfig, {mode: 'development'})
}
return merge(commonConfig, proConfig, {mode: 'production'})
}
3、修改命令
"build": "cross-env NODE_ENV=production webpack --config ./build/webpack.config.js",
"dev": "cross-env NODE_ENV=development webpack serve --config ./build/webpack.config.js"
现在我们开发时运行npm run dev
,上线运行npm run build
打包即可
为什么使用 cross-env
这是因为设置环境变量时候不同系统命令不同
- Windows
set NODE_ENV=development
- Max
export NODE_ENV=development
cross-env能帮我们兼容不同的系统
结尾
现在这个已经能实现一个react项目的开发和打包,还有许多优化的地方,待后续再写吧
转载自:https://juejin.cn/post/7053188321022836772