[0 to 1] 搭建一个极简的 React 工程

久在樊笼里,复得返自然。

随着前端的发展,前端工程化 早已不是一个新鲜的话题了,这个赛道已经成熟到 react 都不在自己文档中提自己的 create-react-app 了。而我在工作之后使用最多的便是 umijs,它有一套完整工程化体系,在项目初期基本上不需要时间成本上手,可以立即开展业务迭代。轮子用久了,都不会走路了 , 前不久打算写一个组件库,正好复习一下 webpack 工程。

工程结构

整个工程项目包含三部分:业务代码静态检查打包工具 。业务代码由最基本的三件套即 react , typescript , css 组成,静态检查则由 eslint 负责,最后由 webpack 负责打包。

项目配置

package.json

因为是个最简单的 react 应用,甚至不涉及路由部分,因此只有两个 dependencies:

json 复制代码
"dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  }

devDependencies 涉及较多依赖,部分安装依赖解释如下:

  1. @types/react , @types/react-dom:react的类型定义
  2. typescript:指定项目的 typescript 版本
  3. @babel/core@babel/preset-env:babel 的核心配置
  4. ts-node :解决后缀名是 .ts 的 webpack 编译
  5. webpackwebpack-dev-serverwebpack-cli:webpack 的依赖

webpack 配置

项目根目录新建 public/index.html 用来配合 webpack-dev-server。

在项目的根目录新建 webpack 目录用来存放 webpack 的配置文件,新建 webpack/webpack.dev.config.ts 作为开发调试项目的配置。

ts 复制代码
import path from 'path';
import type { Configuration } from 'webpack';
import webpackBor from 'webpackbar'
const rootPath = path.join(__dirname,'../');

const webpack: Configuration = {
  //* 模式
  mode: 'development',
  
  //* 主入口文件
  entry: './src/index.tsx',

  //* 输出文件
  //! 暂时不考虑拆包
  // todo
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },

  resolve: {
    //* 解析文件的优先级 ts > tsx > js > jsx
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
  },

  //* 处理模块对应的不同 loader
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ],
  },

  //* dev server 相关配置
  //@ts-ignore
  devServer: {
    static: path.join(rootPath, 'public'),
    port: 3000,
    open: true,
    client: {
      overlay: true, //* 增加 overlay
      progress: true, //* 增加进度条
    }
  },

  //* 关闭 webpack 编译的产物日志,只保留错误的
  stats: "errors-only",
  
  //* 增加 webpack 打包编译条
  plugins: [
    new webpackBor({
      basic: true,
      profile: false
    })
  ]
}

export default webpack

其中 babel-loader 用来处理 ts -> jscss-loader 用来解析处理 css 文件,style-loader 则是用来渲染 css 样式。 webpackBar 则是一个显示webpack打包进度的插件😏,效果如下

babel 配置

json 复制代码
{
  "presets": [
    [
      "@babel/preset-env", //* babel 的预设,必须包含 corejs
      {
        "browserslistEnv": "> 0.25%, not dead",
        "useBuiltIns": "usage",
        "corejs": "3"
      }
    ],
    [
        "@babel/preset-react", //* 一些 react 的预设,若不想 import react 需将 runtime 置为 automatic
        {
          "runtime": "automatic"
        }
    ],
    [
        "@babel/preset-typescript"
    ]
  ]
}

一些小坑

react 的 17 版本后,新的 JSX 转换不再依赖 React 环境,在转换时会自动引入react 的 runtime,体现在代码上的便是少了这一行代码

tsx 复制代码
import React from 'react;

但是在 babel 中,如果不加 "runtime": "automatic"(默认是 classic)则不会自动导入 jsx 的 runtime 函数,结果就是项目会出现 React is not defined 的错误

eslint 配置

js 复制代码
/* eslint-disable no-undef */
module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: './tsconfig.json',
  },
  plugins: ['@typescript-eslint'],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    "plugin:react/recommended",
    "plugin:react/jsx-runtime"
  ],
  rules: {
    "@typescript-eslint/ban-ts-comment": "off", //! 关闭 ts-check 确保可以写一些 后门
  },
};

之前习惯写 ts-ignore(见上图) , 但在最新的规则里面是不允许直接写的😶‍🌫️(这里就偷个懒,对如果是团队项目推荐开启,关了不利于 review)

tsconfig.json

json 复制代码
{
  "compilerOptions": {
    "target": "ES6",
    "module": "ES6",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "jsx": "react-jsx",
    "importHelpers": true,
    "sourceMap": true,
    "allowSyntheticDefaultImports": true,
    "moduleResolution": "bundler"
  },
  "ts-node": {
    "compilerOptions": {
      "module": "CommonJS",
      "allowSyntheticDefaultImports": true
    }
  },
  "include": [
    "./src/**/*",
    "./webpack"
  ],
  "exclude": [
    "node_modules",
    "./webpack/dist/**/*",
    ".eslintrc.js"
  ]
}

其中 ts-node 的相关配置是为了解决 webpack 自身没法识别 .ts 后缀文件

一点趣事

在配置 tsconfig 的时候,由于我想使用自动转换 react,即每个文件都不引入 react,需要把 "jsx":"react" 这项配置改成 "jsx":"react-jsx"。但改了之后所有的 html 的 jsx 标签会报这个错

查阅百度发现需要把 jsx 这项配置改成 "jsx":"react" 死循环了属于是🤺。

其实将 moduleResolution 这个配置改成 moduleResolution:"bundler" 就可以了

启动命令

package.json 中增加调试脚本:

json 复制代码
"scripts": {
    "start": "webpack serve --config webpack/webpack.dev.config.ts"
  },

项目成果跑起来,完结撒花 ~🎉🎉🎉


hi, there👋

i am siroi

一个接触前端 2.5 年的新人,欢迎关注我的微信公众号:siroi的前端手册

让我们一起愉快的玩耍吧🤓

相关推荐
Jiaberrr2 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy2 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白3 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、3 小时前
Web Worker 简单使用
前端
web_learning_3213 小时前
信息收集常用指令
前端·搜索引擎
tabzzz3 小时前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack
200不是二百3 小时前
Vuex详解
前端·javascript·vue.js
滔滔不绝tao3 小时前
自动化测试常用函数
前端·css·html5
码爸3 小时前
flink doris批量sink
java·前端·flink
深情废杨杨3 小时前
前端vue-父传子
前端·javascript·vue.js