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

一. 搭建基础开发环境

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内容



  
  
  
  webpack5-react-ts


  
  
添加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 

webpack5-react-ts

} 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()
}

配置基础版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-env和webpack.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 

webpack5-rea11ct-ts

} 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 (
    <>
      小于10kb的图片
      大于于10kb的图片
      
{/* 小图片背景容器 */}
{/* 大图片背景容器 */} ) } 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

你可能感兴趣的:(webpack,react.js,javascript)