实践!使用Webpack搭建【React + TS】开发环境

本文详细介绍了如何在Node16.20.1和Webpack5.89.0环境下搭建React18.2.0的开发环境,包括安装依赖、配置webpack基础、环境变量、处理CSS/LESS、优化构建速度、缓存和多线程等关键步骤,以及如何使用Webpack的插件和配置技巧。
摘要由CSDN通过智能技术生成

一. 搭建基础开发环境

2.1 前置工作

本章节将按照 entry,output,loader,plugin,其他配置 的顺序带大家搭建一个基础的React开发环境。在正式开始之前我们先做好如下前置工作:

版本:

node:16.20.1

webpack:5.89.0

react:18.2.0

步骤1:  安装 webpack 与 webpack-cli

pnpm i webpack webpack-cli -D

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

pnpm init -y

初始化好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依赖
pnpm i webpack webpack-cli -D
安装react依赖
pnpm i react react-dom -S

安装react类型依赖

pnpm i @types/react @types/react-dom -D
添加public/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-react-ts</title>
</head>
<body>
  <!-- 容器节点 -->
  <div id="root"></div>
</body>
</html>
添加tsconfig.json内容
{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": false,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react", // react18这里也可以改成react-jsx
  },
  "include": ["./src"]
}
添加src/App.tsx内容
import React from 'react'

function App() {
  return <h2>webpack5-react-ts</h2>
}
export default App
添加src/index.tsx内容
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

const root = document.getElementById('root');
if(root) {
  createRoot(root).render(<App />)
}

配置基础版React+ts环境

 webpack公共配置

修改webpack.base.js

1. 配置入口文件
// webpack.base.js
const path = require('path')

module.exports = {
  entry: path.join(__dirname, '../src/index.tsx'), // 入口文件
}
2、 配置出口文件
// webpack.base.js
const path = require('path')

module.exports = {
  // ...
  // 打包文件出口
  output: {
    filename: 'static/js/[name].js', // 每个输出js的名称
    path: path.join(__dirname, '../dist'), // 打包结果输出路径
    clean: true, // webpack4需要配置clean-webpack-plugin来删除dist文件,webpack5内置了
    publicPath: '/' // 打包后文件的公共前缀路径
  },
}
3、配置extensions

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

修改webpack.base.js,注意把高频出现的文件后缀放在前面

// webpack.base.js
module.exports = {
  // ...
  resolve: {
    extensions: ['.js', '.tsx', '.ts'],
  }
}
4、添加html-webpack-plugin插件

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

pnpm i html-webpack-plugin -D

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

// webpack.base.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public/index.html'), // 模板取定义root节点的模板
      inject: true, // 自动注入静态资源
    })
  ]
}

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

webpack开发环境配置

1. 安装 webpack-dev-server

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

pnpm i webpack-dev-server webpack-merge -D

修改webpack.dev.js代码, 合并公共配置,并添加开发模式配置

// webpack.dev.js
const path = require('path')
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.base.js')

// 合并公共配置,并添加开发环境配置
module.exports = merge(baseConfig, {
  mode: 'development', // 开发模式,打包更加快速,省了代码优化步骤
  devtool: 'eval-cheap-module-source-map', // 源码调试模式,后面会讲
  devServer: {
    port: 3000, // 服务端口号
    compress: false, // gzip压缩,开发环境不开启,提升热更新速度
    hot: true, // 开启热更新,后面会讲react模块热替换具体配置
    historyApiFallback: true, // 解决history路由404问题
    static: {
      directory: path.join(__dirname, "../public"), //托管静态资源public文件夹
    }
  }
})
package.json添加dev脚本

package.jsonscripts中添加

// package.json
"scripts": {
  "dev": "webpack-dev-server -c build/webpack.dev.js"
},
修改webpack.prod.js代码
// webpack.prod.js

const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.base.js')
module.exports = merge(baseConfig, {
  mode: 'production', // 生产模式,会开启tree-shaking和压缩代码,以及其他优化
})
package.json添加build打包命令脚本
"scripts": {
    "dev": "webpack-dev-server -c build/webpack.dev.js",
    "build": "webpack -c build/webpack.prod.js"
},

基础功能配置

配置环境变量

环境变量按作用来分分两种

  1. 区分是开发模式还是打包构建模式
  2. 区分项目业务环境,开发/测试/预测/正式环境

区分开发模式还是打包构建模式可以用process.env.NODE_ENV,因为很多第三方包里面判断都是采用的这个环境变量。

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

cross-env:兼容各系统的设置环境变量的包

webpack.DefinePluginwebpack内置的插件,可以为业务代码注入环境变量

安装cross-env

pnpm i cross-env -D

修改package.jsonscripts脚本字段,删除原先的devbuild,改为

"scripts": {
    "dev:dev": "cross-env NODE_ENV=development BASE_ENV=development webpack-dev-server -c build/webpack.dev.js",
    "dev:test": "cross-env NODE_ENV=development BASE_ENV=test webpack-dev-server -c build/webpack.dev.js",
    "dev:pre": "cross-env NODE_ENV=development BASE_ENV=pre webpack-dev-server -c build/webpack.dev.js",
    "dev:prod": "cross-env NODE_ENV=development BASE_ENV=production webpack-dev-server -c build/webpack.dev.js",
    
    "build:dev": "cross-env NODE_ENV=production BASE_ENV=development webpack -c build/webpack.prod.js",
    "build:test": "cross-env NODE_ENV=production BASE_ENV=test webpack -c build/webpack.prod.js",
    "build:pre": "cross-env NODE_ENV=production BASE_ENV=pre webpack -c build/webpack.prod.js",
    "build:prod": "cross-env NODE_ENV=production BASE_ENV=production webpack -c build/webpack.prod.js",
  },
处理css和less文件

src下新增app.css

h2 {
    color: red;
    transform: translateY(100px);
}

src/App.tsx中引入app.css

import React from 'react'
import './app.css'

function App() {
  return <h2>webpack5-rea11ct-ts</h2>
}
export default App

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

pnpm i style-loader css-loader -D

style-loader: 把解析后的css代码从js中抽离,放到头部的style标签中(在运行时做的)

css-loader: 解析css文件代码

因为解析css的配置开发和打包环境都会用到,所以加在公共配置webpack.base.js

// webpack.base.js
// ...
module.exports = {
  // ...
  module: { 
    rules: [
      // ...
      {
        test: /\.css$/, //匹配 css 文件
        use: ['style-loader','css-loader']
      }
    ]
  },
  // ...
}

 优化构建速度

构建耗时分析

当进行优化的时候,肯定要先知道时间都花费在哪些步骤上了,而speed-measure-webpack-plugin插件可以帮我们做到,安装依赖:

pnpm i speed-measure-webpack-plugin -D

使用的时候为了不影响到正常的开发/打包模式,我们选择新建一个配置文件,新增webpack构建分析配置文件build/webpack.analy.js

const prodConfig = require('./webpack.prod.js') // 引入打包配置
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); // 引入webpack打包速度分析插件
const smp = new SpeedMeasurePlugin(); // 实例化分析插件
const { merge } = require('webpack-merge') // 引入合并webpack配置方法

// 使用smp.wrap方法,把生产环境配置传进去,由于后面可能会加分析配置,所以先留出合并空位
module.exports = smp.wrap(merge(prodConfig, {

}))

修改package.json添加启动webpack打包分析脚本命令,在scripts新增:

{
  // ...
  "scripts": {
    // ...
    "build:analy": "cross-env NODE_ENV=production BASE_ENV=production webpack -c build/webpack.analy.js"
  }
  // ...
}
 开启持久化存储缓存

webpack5之前做缓存是使用babel-loader缓存解决js的解析结果,cache-loader缓存css等资源的解析结果,还有模块缓存插件hard-source-webpack-plugin,配置好缓存后第二次打包,通过对文件做哈希对比来验证文件前后是否一致,如果一致则采用上一次的缓存,可以极大地节省时间。

webpack5 较于 webpack4,新增了持久化缓存、改进缓存算法等优化,通过配置 webpack 持久化缓存,来缓存生成的 webpack 模块和 chunk,改善下一次打包的构建速度,可提速 90% 左右,配置也简单,修改webpack.base.js

// webpack.base.js
// ...
module.exports = {
  // ...
  cache: {
    type: 'filesystem', // 使用文件缓存
  },
}
开启多线程loader

webpackloader默认在单线程执行,现代电脑一般都有多核cpu,可以借助多核cpu开启多线程loader解析,可以极大地提升loader解析的速度,thread-loader就是用来开启多进程解析loader的,安装依赖

pnpm i thread-loader -D

使用时,需将此 loader 放置在其他 loader 之前。放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行。

修改webpack.base.js

// webpack.base.js
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /.(ts|tsx)$/,
        use: ['thread-loader', 'babel-loader']
      }
    ]
  }
}
配置alias别名

webpack支持设置别名alias,设置别名可以让后续引用的地方减少路径的复杂度。

修改webpack.base.js

module.export = {
  // ...
   resolve: {
    // ...
    alias: {
      '@': path.join(__dirname, '../src')
    }
  }
}

修改tsconfig.json,添加baseUrlpaths

{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    }
  }
}

src/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的图片" />
      <div className='smallImg'></div> {/* 小图片背景容器 */}
      <div className='bigImg'></div> {/* 大图片背景容器 */}
    </>
  )
}
export default App

总结


理解模块化:Webpack是一个模块打包工具,可以将多个模块打包成一个或多个文件,方便开发者调用。
掌握配置文件:Webpack的配置文件(webpack.config.js)允许自定义打包规则,满足项目的特定需求。
熟悉Loader和Plugin:Loader用于处理模块的加载,Plugin用于扩展Webpack的功能。了解常见的Loader和Plugin,如Babel Loader、CSS Loader等。
掌握代码拆分:代码拆分可以将大型项目分成多个较小的包,提高应用的加载性能。
学习热更新:Webpack支持热更新技术,允许在开发过程中实时查看代码修改后的效果,提高开发效率。
学习React:
理解组件化思想:React提倡将页面拆分成多个独立的、可复用的组件,从而提高代码的可维护性和可扩展性。
了解路由:学习如何使用React Router实现单页面应用的路由功能。
编写脚手架:
掌握脚手架概念:脚手架是一种用于搭建和管理项目的工具,可以帮助开发者快速启动项目、统一项目规范等。
学会使用常见脚手架框架:如Jest、Express、Babel等,搭建项目结构。
熟悉脚手架配置:根据项目需求,配置相关插件和加载器,提高开发效率。
webpack和react是现代前端开发的核心技术。编写脚手架则有助于提高开发效率、规范项目结构。接下来,可以尝试结合实际项目,运用所学知识进行开发,不断提升自己的技能水平。

最后,分享本人分享在gitee上的一个完整的脚手架WNanXuan/webpackFrame

  • 26
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
搭建 React + TypeScript 项目的步骤如下: 1. 创建一个新的项目文件夹 ``` mkdir my-react-ts-app cd my-react-ts-app ``` 2. 初始化项目 ``` npm init -y ``` 3. 安装必要的依赖 ``` npm install --save react react-dom npm install --save-dev typescript @types/react @types/react-dom webpack webpack-cli webpack-dev-server awesome-typescript-loader html-webpack-plugin ``` 4. 创建一个 TypeScript 配置文件 ``` touch tsconfig.json ``` 5. 将以下内容添加到 tsconfig.json 文件中 ``` { "compilerOptions": { "outDir": "./dist/", "module": "es6", "target": "es5", "lib": ["es6", "dom"], "sourceMap": true, "jsx": "react", "moduleResolution": "node", "esModuleInterop": true }, "include": [ "./src/**/*" ] } ``` 6. 添加一个 index.html 文件到项目根目录 7. 添加以下内容到 index.html 文件中 ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>My React TypeScript App</title> </head> <body> <div id="root"></div> </body> </html> ``` 8. 创建一个 src 目录 ``` mkdir src ``` 9. 在 src 目录中创建一个 App.tsx 文件 ``` touch src/App.tsx ``` 10. 将以下内容添加到 App.tsx 文件中 ```tsx import React from 'react'; const App = () => { return ( <div> <h1>Hello, World!</h1> </div> ); }; export default App; ``` 11. 在 src 目录中创建一个 index.tsx 文件 ``` touch src/index.tsx ``` 12. 将以下内容添加到 index.tsx 文件中 ```tsx import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render(<App />, document.getElementById('root')); ``` 13. 在项目根目录中创建一个 webpack.config.js 文件 ``` touch webpack.config.js ``` 14. 将以下内容添加到 webpack.config.js 文件中 ```js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/index.tsx', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'], }, module: { rules: [ { test: /\.tsx?$/, loader: 'awesome-typescript-loader', }, ], }, plugins: [ new HtmlWebpackPlugin({ template: 'index.html', }), ], devServer: { contentBase: path.join(__dirname, 'dist'), compress: true, port: 3000, }, }; ``` 15. 运行 npm start 启动项目 ``` npm start ``` 以上就是从零搭建一个 React + TypeScript 的完整项目的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值