当前位置:   article > 正文

前端环境搭建react18+typescript+webpack5_pnpm启动react项目

pnpm启动react项目
这里将使用 pnpm ,至于为什么,一个字:快、省、狠!

pnpm 、 npm 和 yarn 都是 Node.js 和 JavaScript 项目的包管理器。每种都有自己的优点和缺点,
选择使用哪一种最终取决于你的具体需求和偏好。 以下是 pnpm 与 npm 和 yarn 相比的一些优势:

  1. 更快的安装和更新时间: pnpm 使用独特的方法来安装包,避免重复包,从而加快安装和更新时
    间。特别是,当安装共享依赖的多个包时, pnpm 只会为每个依赖安装一次,而 npm 和 yarn 会
    为每个包分别安装每个依赖。
  2. 更少的磁盘空间使用:由于 pnpm 避免了包重复,它使用的磁盘空间比 npm 和 yarn 更少。如果
    你的磁盘空间有限,或者你正在处理具有许多依赖项的大型项目,那么这一点尤其重要。
  3. 更好地支持 monorepos : pnpm 旨在与 monorepo 项目很好地配合使用,这些项目是在单个存储
    库中包含多个包或模块的项目。 pnpm 独特的包管理方法可以更轻松地管理 monorepo 中多个包和
    模块的依赖关系。
  4. 更好地支持对等依赖: pnpm 比 npm 和 yarn 对对等依赖有更好的支持。对等依赖项是包所需的
    依赖项,但不应与包一起安装,因为它们已由应用程序或其他依赖项提供。 pnpm 可以比 npm 和
    yarn 更高效、更准确地处理对等依赖。
  5. 更清晰的依赖树: pnpm 生成比 npm 和 yarn 更清晰的依赖树。这是因为 pnpm 对依赖项使用平
    面目录结构,而 npm 和 yarn 使用嵌套目录。扁平结构使得依赖树更容易理解和调试。

一. 初始化项目

在开始webpack配置之前,先手动初始化一个基本的react+ts项目,新建项目文件夹webpack5-react-18, 在项目下执行

pnpm -v

初始化package.json文件

pnpm init

初始化好package.json后,在项目下新增以下所示目录结构和文件

├── build
| ├── webpack.base.js # 公共配置
| ├── webpack.dev.js # 开发环境配置
| └── webpack.prod.js # 打包环境配置
├── public
│ └── index.html # html模板
├── src
| ├── App.tsx
│ └── index.tsx # react应用入口页面
├── tsconfig.json # ts配置
└── package.json

安装webpack依赖

npm i webpack webpack-cli -D

安装react依赖

pnpm i react react-dom

安装react类型依赖

pnpm i @types/react @types/react-dom -D

添加public/index.html内容
在这里插入图片描述

添加tsconfig.json内容
在这里插入图片描述

添加src/App.tsx内容
在这里插入图片描述

添加src/index.tsx内容
在这里插入图片描述

二. 配置基础版React+ts环境

2.1. webpack公共配置

修改webpack.base.js

配置入口文件

在这里插入图片描述

配置出口文件

在这里插入图片描述

配置loader解析ts和jsx

由于webpack默认只能识别js文件,不能识别jsx语法,需要配置loader的预设预设 @babel/preset-typescript 来先ts语法转换为 js 语法,再借助预设 @babel/preset-react 来识别jsx语法。

  • 安装babel核心模块和babel预设
  • npm i babel-loader @babel/core @babel/preset-react @babel/preset-typescript -D

  • 在webpack.base.js添加module.rules配置
  • 在这里插入图片描述
配置extensions

extensionswebpackresolve解析配置下的选项,在引入模块时不带文件后缀时,会来该配置数组里面依次添加后缀查找文件,因为ts不支持引入以 .ts, tsx为后缀的文件,所以要在extensions中配置,而第三方库里面很多引入js文件没有带后缀,所以也要配置下js

  • 修改webpack.base.js,注意把高频出现的文件后缀放在前面
  • 在这里插入图片描述
    这里只配置js, tsxts,其他文件引入都要求带后缀,可以提升构建速度。
添加html-webpack-plugin插件

ebpack需要把最终构建好的静态资源都引入到一个html文件中,这样才能在浏览器中运行,html-webpack-plugin就是来做这件事情的,安装依赖:

  • npm i html-webpack-plugin -D

  • 因为该插件在开发和构建打包模式都会用到,所以还是放在公共配置webpack.base.js里面
    加粗样式

  • 到这里一个最基础的react基本公共配置就已经配置好了,需要在此基础上分别配置开发环境和打包环境了。

2.2. webpack开发环境配置

1. 安装 webpack-dev-server

开发环境配置代码在webpack.dev.js中,需要借助 webpack-dev-server在开发环境启动服务器来辅助开发,还需要依赖webpack-merge来合并基本配置,安装依赖:

npm i webpack-dev-server webpack-merge -D

  • 修改webpack.dev.js代码, 合并公共配置,并添加开发模式配置
    在这里插入图片描述
2. package.json添加dev脚本
  • 在package.json的scripts中添加
    在这里插入图片描述
    执行npm run
    dev,就能看到项目已经启动起来了,访问http://localhost:3000/,就可以看到项目界面,具体完善的react模块热替换在下面会讲到。

2.3. webpack打包环境配置

1. 修改webpack.prod.js代码

在这里插入图片描述

2. package.json添加build打包命令脚本
  • 在package.json的scripts中添加build打包命令
    在这里插入图片描述

  • 执行npm run build,最终打包在dist文件中, 打包结果:
    在这里插入图片描述

3. 浏览器查看打包结果
  • 打包后的dist文件可以在本地借助node服务器serve打开,全局安装serve

    npm i serve -g

  • 然后在项目根目录命令行执行serve -s dist,就可以启动打包后的项目了。

到现在一个基础的支持react和ts的webpack5就配置好了,但只有这些功能是远远不够的,还需要继续添加其他配置。

三. 基础功能配置

配置环境变量
  • 环境变量按作用来分分两种

     区分是开发模式还是打包构建模式
     
     区分项目业务环境,开发/测试/预测/正式环境
    
    • 1
    • 2
    • 3
  • 区分开发模式还是打包构建模式可以用process.env.NODE_ENV,因为很多第三方包里面判断都是采用的这个环境变量。

  • 区分项目接口环境可以自定义一个环境变量process.env.BASE_ENV,设置环境变量可以借助cross-env和webpack.DefinePlugin来设置。

    • cross-env:兼容各系统的设置环境变量的包
    • webpack.DefinePlugin:webpack内置的插件,可以为业务代码注入环境变量
  • 安装cross-env

    npm i cross-env -D

  • 修改package.json的scripts脚本字段,删除原先的dev和build,改为
    在这里插入图片描述

  • dev开头是开发模式,build开头是打包模式,冒号后面对应的dev/test/pre/prod是对应的业务环境的开发/测试/预测/正式环境。

  • process.env.NODE_ENV环境变量webpack会自动根据设置的mode字段来给业务代码注入对应的

  • development和prodction,这里在命令中再次设置环境变量NODE_ENV是为了在webpack和babel的配置文件中访问到。

  • 在webpack.base.js中打印一下设置的环境变量

  • 在这里插入图片描述

  • 执行npm run build:dev,可以看到打印的信息

  • 在这里插入图片描述

  • 当前是打包模式,业务环境是开发环境,这里需要把process.env.BASE_ENV注入到业务代码里面,就可以通过该环境变量设置对应环境的接口地址和其他数据,要借助webpack.DefinePlugin插件。

  • 修改webpack.base.js

  • 在这里插入图片描述

  • 配置后会把值注入到业务代码里面去,webpack解析代码匹配到process.env.BASE_ENV,就会设置到对应的值。测试一下,在src/index.tsx打印一下两个环境变量

  • 在这里插入图片描述

  • 执行npm run dev:test,可以在浏览器控制台看到打印的信息

  • 在这里插入图片描述
    当前是开发模式,业务环境是测试环境。

处理css和less文件
  • 在src下新增app.css

  • 在这里插入图片描述

  • 在src/App.tsx中引入app.css

  • 在这里插入图片描述

  • 执行打包命令npm run build:dev,会发现有报错, 因为webpack默认只认识js,是不识别css文件的,需要使用loader来解析css, 安装依赖:

  • npm i style-loader css-loader -D

  •  style-loader: 把解析后的css代码从js中抽离,放到头部的style标签中(在运行时做的) 
    
    • 1
  •  css-loader:解析css文件代码
    
    • 1
  • 因为解析css的配置开发和打包环境都会用到,所以加在公共配置webpack.base.js中

>// webpack.base.js
// ...
module.exports = {
  // ...
  module: { 
    rules: [
      // ...
      {
        test: /\.css$/, //匹配 css 文件
        use: ['style-loader','css-loader']
      }
    ]
  },
  // ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

上面提到过,loader执行顺序是从右往左,从下往上的,匹配到css文件后先用css-loader解析css, 最后借助style-loader把css插入到头部style标签中。

配置完成后再npm run build:dev打包,借助serve -s dist启动后在浏览器查看,可以看到样式生效了。

在这里插入图片描述

  • 支持less或scss
  • 项目开发中,为了更好的提升开发体验,一般会使用css超集less或者scss,对于这些超集也需要对应的loader来识别解析。以less为例,需要安装依赖:

npm i less-loader less -D

  •  less-loader: 解析less文件代码,把less编译为css
    
    • 1
  •  less: less核心
    
    • 1

实现支持less也很简单,只需要在rules中添加less文件解析,遇到less文件,使用less-loader解析为css,再进行css解析流程,修改webpack.base.js:

>// webpack.base.js
module.exports = {
  // ...
  module: {
    // ...
    rules: [
      // ...
      {
        test: /.(css|less)$/, //匹配 css和less 文件
        use: ['style-loader','css-loader', 'less-loader']
      }
    ]
  },
  // ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 测试一下,新增src/app.less
>#root {
  h2 {
    font-size: 20px;
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 在App.tsx中引入app.less,执行npm run build:dev打包,借助serve -s dist启动项目,可以看到less文件编写的样式编译css后也插入到style标签了了。
  • 在这里插入图片描述
  • 处理css3前缀兼容
  • 虽然css3现在浏览器支持率已经很高了, 但有时候需要兼容一些低版本浏览器,需要给css3加前缀,可以借助插件来自动加前缀, postcss-loader就是来给css3加浏览器前缀的,安装依赖:

npm i postcss-loader autoprefixer -D

  • postcss-loader:处理css时自动加前缀
  • autoprefixer:决定添加哪些浏览器前缀到css中
  • 修改webpack.base.js, 在解析css和less的规则中添加配置
 >module.exports = {   // ...   module: { 
       rules: [
         // ...
         {
           test: /.(css|less)$/, //匹配 css和less 文件
           use: [
             'style-loader',
             'css-loader',
             // 新增
             {
               loader: 'postcss-loader',
               options: {
                 postcssOptions: {
                   plugins: ['autoprefixer']
                 }
               }
             },
             'less-loader'
           ]
         }
       ]   },   // ... }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 配置完成后,需要有一份要兼容浏览器的清单,让postcss-loader知道要加哪些浏览器的前缀,在根目录创建
    .browserslistrc文件

IE 9 # 兼容IE 9
chrome 35 # 兼容chrome 35

  • 以兼容到ie9和chrome35版本为例,配置好后,执行npm run build:dev打包,可以看到打包后的css文件已经加上了ie和谷歌内核的前缀

  • 在这里插入图片描述

  • 上面可以看到解析css和less有很多重复配置,可以进行提取postcss-loader配置优化一下

  • postcss.config.jspostcss-loader的配置文件,会自动读取配置,根目录新建postcss.config.js

>module.exports = {
  plugins: ['autoprefixer']
}
  • 1
  • 2
  • 3
  • 修改webpack.base.js, 取消postcss-loader的options配置
>// webpack.base.js
// ...
module.exports = {
  // ...
  module: { 
    rules: [
      // ...
      {
        test: /.(css|less)$/, //匹配 css和less 文件
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]
      },
    ]
  },
  // ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 提取postcss-loader配置后,再次打包,可以看到依然可以解析css, less文件, css3对应前缀依然存在。
babel预设处理js兼容

现在js不断新增很多方便好用的标准语法来方便开发,甚至还有非标准语法比如装饰器,都极大的提升了代码可读性和开发效率。但前者标准语法很多低版本浏览器不支持,后者非标准语法所有的浏览器都不支持。需要把最新的标准语法转换为低版本语法,把非标准语法转换为标准语法才能让浏览器识别解析,而babel就是来做这件事的,这里只讲配置,更详细的可以看Babel 那些事儿

安装依赖

npm i babel-loader @babel/core @babel/preset-env core-js -D

  •  babel-loader: 使用 babel 加载最新js代码并将其转换为 ES5(上面已经安装过)
    
    • 1
  •  @babel/corer: babel 编译的核心包
    
    • 1
  •  0 @babel/preset-env: babel 编译的预设,可以转换目前最新的js标准语法
    
    • 1
  •  core-js: 使用低版本js语法模拟高版本的库,也就是垫片
    
    • 1
修改webpack.base.js
>// webpack.base.js
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /.(ts|tsx)$/,
        use: {
          loader: 'babel-loader',
          options: {
            // 执行顺序由右往左,所以先处理ts,再处理jsx,最后再试一下babel转换为低版本语法
            presets: [
              [
                "@babel/preset-env",
                {
                  // 设置兼容目标浏览器版本,这里可以不写,babel-loader会自动寻找上面配置好的文件.browserslistrc
                  // "targets": {
                  //  "chrome": 35,
                  //  "ie": 9
                  // },
                   "useBuiltIns": "usage", // 根据配置的浏览器兼容,以及代码中使用到的api进行引入polyfill按需添加
                   "corejs": 3, // 配置使用core-js低版本
                  }
                ],
              '@babel/preset-react',
              '@babel/preset-typescript'
            ]
          }
        }
      }
    ]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

此时再打包就会把语法转换为对应浏览器兼容的语法了。

为了避免webpack配置文件过于庞大,可以把babel-loader的配置抽离出来, 新建babel.config.js文件,使用js作为配置文件,是因为可以访问到process.env.NODE_ENV环境变量来区分是开发还是打包模式。

>// babel.config.js
module.exports = {
  // 执行顺序由右往左,所以先处理ts,再处理jsx,最后再试一下babel转换为低版本语法
  "presets": [
    [
      "@babel/preset-env",
      {
        // 设置兼容目标浏览器版本,这里可以不写,babel-loader会自动寻找上面配置好的文件.browserslistrc
        // "targets": {
        //  "chrome": 35,
        //  "ie": 9
        // },
        "useBuiltIns": "usage", // 根据配置的浏览器兼容,以及代码中使用到的api进行引入polyfill按需添加
        "corejs": 3 // 配置使用core-js使用的版本
      }
    ],
    "@babel/preset-react",
    "@babel/preset-typescript"
  ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

移除webpack.base.js中babel-loader的options配置

>// webpack.base.js
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /.(ts|tsx)$/,
        use: 'babel-loader'
      },
      // 如果node_moduels中也有要处理的语法,可以把js|jsx文件配置加上
      // {
      //  test: /.(js|jsx)$/,
      //  use: 'babel-loader'
      // }
      // ...
    ]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
babel处理js非标准语法

现在react主流开发都是函数组件和react-hooks,但有时也会用类组件,可以用装饰器简化代码。

新增src/components/Class.tsx组件, 在App.tsx中引入该组件使用

在这里插入图片描述

需要开启一下ts装饰器支持,修改tsconfig.json文件

>// tsconfig.json
{
  "compilerOptions": {
    // ...
    // 开启装饰器使用
    "experimentalDecorators": true
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面Class组件代码中使用了装饰器,目前js标准语法是不支持的,现在运行或者打包会报错,不识别装饰器语法,需要借助babel-loader插件,安装依赖

>npm i @babel/plugin-proposal-decorators -D

在babel.config.js中添加插件
>module.exports = { 
  // ...
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }]
  ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

现在项目就支持装饰器了。

复制public文件夹

一般public文件夹都会放一些静态资源,可以直接根据绝对路径引入,比如图片,css,js文件等,不需要webpack进行解析,只需要打包的时候把public下内容复制到构建出口文件夹中,可以借助copy-webpack-plugin插件,安装依赖

npm i copy-webpack-plugin -D

开发环境已经在devServer中配置了static托管了public文件夹,在开发环境使用绝对路径可以访问到public下的文件,但打包构建时不做处理会访问不到,所以现在需要在打包配置文件webpack.prod.js中新增copy插件配置

>// webpack.prod.js
// ..
const path = require('path')
const CopyPlugin = require('copy-webpack-plugin');
module.exports = merge(baseConfig, {
  mode: 'production',
  plugins: [
    // 复制文件插件
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../public'), // 复制public下文件
          to: path.resolve(__dirname, '../dist'), // 复制到dist目录中
          filter: source => {
            return !source.includes('index.html') // 忽略index.html
          }
        },
      ],
    }),
  ]
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在上面的配置中,忽略了index.html,因为html-webpack-plugin会以public下的index.html为模板生成一个index.htmldist文件下,所以不需要再复制该文件了。

测试一下,在public中新增一个favicon.ico图标文件,在index.html中引入

在这里插入图片描述

再执行npm run build:dev打包,就可以看到public下的favicon.ico图标文件被复制到dist文件中了。

在这里插入图片描述

处理图片文件

对于图片文件,webpack4使用file-loaderurl-loader来处理的,但webpack5不使用这两个loader了,而是采用自带的asset-module来处理

修改webpack.base.js,添加图片解析配置

>module.exports = {
  module: {
    rules: [
      // ...
      {
        test:/.(png|jpg|jpeg|gif|svg)$/, // 匹配图片文件
        type: "asset", // type选择asset
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024, // 小于10kb转base64位
          }
        },
        generator:{ 
          filename:'static/images/[name][ext]', // 文件输出目录和命名
        },
      },
    ]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

测试一下,准备一张小于10kb的图片和大于10kb的图片,放在src/assets/imgs目录下, 修改App.tsx:

>import React from 'react'
import smallImg from './assets/imgs/5kb.png'
import bigImg from './assets/imgs/22kb.png'
import './app.css'
import './app.less'

function App() {
  return (
    <>
      \<img src={smallImg} alt="小于10kb的图片" />
      \<img src={bigImg} alt="大于于10kb的图片" />
    </>
  )
}
export default App
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  •  这个时候在引入图片的地方会报:找不到模块“./assets/imgs/22kb.png”或其相应的类型声明,需要添加一个图片的声明文件
    
    • 1

新增src/images.d.ts文件,添加内容

>declare module '*.svg'
declare module '*.png'
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.gif'
declare module '*.bmp'
declare module '*.tiff'
declare module '*.less'
declare module '*.css'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

添加图片声明文件后,就可以正常引入图片了, 然后执行npm run build:dev打包,借助serve -s dist查看效果,可以看到可以正常解析图片了,并且小于10kb的图片被转成了base64位格式的。

在这里插入图片描述

css中的背景图片一样也可以解析,修改app.tsx。
在这里插入图片描述

修改app.less
在这里插入图片描述

可以看到背景图片也一样可以识别,小于10kb转为base64位。
在这里插入图片描述

处理字体和媒体文件

字体文件和媒体文件这两种资源处理方式和处理图片是一样的,只需要把匹配的路径和打包后放置的路径修改一下就可以了。修改webpack.base.js文件:

>// webpack.base.js
module.exports = {
  module: {
    rules: [
      // ...
      {
        test:/.(woff2?|eot|ttf|otf)$/, // 匹配字体图标文件
        type: "asset", // type选择asset
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024, // 小于10kb转base64位
          }
        },
        generator:{ 
          filename:'static/fonts/[name][ext]', // 文件输出目录和命名
        },
      },
      {
        test:/.(mp4|webm|ogg|mp3|wav|flac|aac)$/, // 匹配媒体文件
        type: "asset", // type选择asset
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024, // 小于10kb转base64位
          }
        },
        generator:{ 
          filename:'static/media/[name][ext]', // 文件输出目录和命名
        },
      },
    ]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

四、配置react模块热更新

 - 热更新上面已经在**devServer**中配置**hot**为**true**,
   在**webpack4**中,还需要在插件中添加了HotModuleReplacementPlugin,在webpack5中,只要devServer.hot为true了,该插件就已经内置了。
   现在开发模式下修改css和less文件,页面样式可以在不刷新浏览器的情况实时生效,因为此时样式都在style标签里面,style-loader做了替换样式的热替换功能。但是修改App.tsx,浏览器会自动刷新后再显示修改后的内容,但我们想要的不是刷新浏览器,而是在不需要刷新浏览器的前提下模块热更新,并且能够保留react组件的状态。
   可以借助|**@pmmmwh/react-refresh-webpack-plugin**插件来实现,该插件又依赖于**react-refresh**,
   安装依赖:
  • 1
  • 2
  • 3
  • 4
  • 5

<npm i @pmmmwh/react-refresh-webpack-plugin react-refresh -D

配置react热更新插件,修改webpack.dev.js
在这里插入图片描述

为babel-loader配置react-refesh刷新插件,修改babel.config.js文件

>const isDEV = process.env.NODE_ENV === 'development' // 是否是开发模式
module.exports = {
  // ...
  "plugins": [
    isDEV && require.resolve('react-refresh/babel'), // 如果是开发模式,就启动react热更新插件
    // ...
  ].filter(Boolean) // 过滤空值
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

测试一下,修改App.tsx代码

在这里插入图片描述

在两个输入框分别输入内容后,修改App.tsx中h2标签的文本,会发现在不刷新浏览器的情况下,页面内容进行了热更新,并且react组件状态也会保留。
在这里插入图片描述

在这里插入图片描述

  •   新增或者删除页面hooks时,热更新时组件状态不会保留。
    
    • 1

新增或者删除页面hooks时,热更新时组件状态不会保留。

五、总结

到目前为止已经使用webpack5把react18+ts的开发环境配置完成,并且配置比较完善的保留组件状态的热更新,以及常见的优化构建速度和构建结果的配置,完整代码已上传到webpack5-react-ts。还有细节需要优化,比如把容易改变的配置单独写个config.js来配置,输出文件路径封装。这篇文章只是配置,如果想学好webpack,还需要学习webpack的构建原理以及loader和plugin的实现机制。
本文是总结自己在工作中使用webpack5搭建react+ts构建环境中使用到的配置, 肯定也很多没有做好的地方,后续有好的使用技巧和配置也会继续更新记录。

附上上面安装依赖的版本
>"devDependencies": {
    "@babel/core": "^7.18.2",
    "@babel/plugin-proposal-decorators": "^7.18.2",
    "@babel/plugin-transform-runtime": "^7.18.5",
    "@babel/preset-env": "^7.18.2",
    "@babel/preset-react": "^7.17.12",
    "@babel/preset-typescript": "^7.17.12",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
    "@types/react": "^18.0.12",
    "@types/react-dom": "^18.0.5",
    "autoprefixer": "^10.4.7",
    "babel-loader": "^8.2.5",
    "compression-webpack-plugin": "^10.0.0",
    "copy-webpack-plugin": "^11.0.0",
    "core-js": "^3.23.0",
    "cross-env": "^7.0.3",
    "css-loader": "^6.7.1",
    "css-minimizer-webpack-plugin": "^4.0.0",
    "html-webpack-plugin": "^5.5.0",
    "less": "^4.1.3",
    "less-loader": "^11.0.0",
    "mini-css-extract-plugin": "^2.6.1",
    "postcss": "^8.4.14",
    "postcss-loader": "^7.0.0",
    "purgecss-webpack-plugin": "^4.1.3",
    "react-refresh": "^0.14.0",
    "speed-measure-webpack-plugin": "^1.5.0",
    "style-loader": "^3.3.1",
    "thread-loader": "^3.0.4",
    "typescript": "^4.7.3",
    "webpack": "^5.73.0",
    "webpack-bundle-analyzer": "^4.5.0",
    "webpack-cli": "^4.9.2",
    "webpack-dev-server": "^4.9.1",
    "webpack-merge": "^5.8.0"
  },
  "dependencies": {
    "react": "^18.1.0",
    "react-dom": "^18.1.0"
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/138937?site
推荐阅读
相关标签
  

闽ICP备14008679号