文章

前端工程架构与非侵入地增加ts支持

前段时间工作上颇为繁忙,占满了所有的时间,导致业余时间也非常疲惫,没有时间进行技术上的研究与拓展,最近公司的大项目告了一段落,上班氛围轻松,业余时间也有心力学习。

当然黑神话悟空和钢铁雄心4也有一定的责任:)

plat在之前弄完了后台界面后,打算开始弄脚本上云,把我乱七八糟的脚本和运行环境做一个整理。因为逻辑比较复杂,列了个架构图才把后端的系统写完,在此过程中我把协议拓展了一个可以自动生成代码的脚手架

但是开始写前端时遇到了麻烦,协议太多了加上json库的解析的某种不确定性,前端在发送返回结构体的过程中,经常出现多字段少字段、不确定类型的问题。不仅没有合理的提示(变量.后的语法补全简直是包含了宇宙万物)很难写,而且容易崩。

我就想引入类型写明协议中有哪些结构体和类型,但是js中又没有类型系统导致很麻烦。于是我想到引入ts,因为我是通过做这个项目学习大型前端项目的经验的,所以最开始图方便没用ts。现在就需要以兼容模式非侵占的改项目。

前置知识

前端工程的架构

在了解需要改动前端工程有几个部分组成:

  • nodejs npm相关,用来在管理外部依赖、调用打包器等的脚本和写一些项目相关的工程配置。支持安装和引用别的工程脚本、脚手架或工具。也支持脚本工具的全局管理更新等(类似于系统的包管理,可以配置可执行文件)。是所有工程组成的共有框架。如果没有它就必须以文件的形式将前端交给网关。
    • 涉及配置:package.json
  • 构建器,一般由nodejs调用。管理打包(将前端工程与依赖打成一个尽量小尽量分离的前端三剑客),在开发者模式下直接起一个服务器用于展示前端(甚至可以转发请求到开发者的后端)。可以处理一些方言例如jsxts。我用的是vite
    • 涉及配置:vite.config.js
  • 检查器,用于检查代码是否符合规范。我使用的eslint。可以处理一些方言例如jsxts
    • 涉及配置:.eslint.cjs(这个看情况,但是只有语法不同)
  • IDE,自动化调用eslint进行检查并可以便捷图形化地执行npm脚本,我使用的是webstorm

ts是什么东西

typescript是一种语法规范,为js添加了类型与接口等系统。以.ts为结尾。一些第三方库也对此做了支持,所以也有以tsx为结尾的。需要注意ts本身不被浏览器等支持,需要以插件的形式接入翻译器,在打包、运行前将ts转换为js。

如何添加ts支持

IDE层

新建一个.tsx文件,如果IDE支持会在右下角显示

image-cpyv.png

如果没有确认在IDE配置中加入ts支持。

NODE

微软以插件的形式为node提供支持,主要是为项目引入ts的相关翻译器与机制。使配置ts成为可能。

执行指令,需要注意如果你用了第三方框架最后安装框架的type,不然你在ts里面引用js的第三方类型只能any到底了。

npm install --save-dev typescript @types/react @types/react-dom

TS配置

ts自己的配置用于为工程配置ts的功能,需要注意如果是非侵入地使用需要显示提示工程允许js文件,同时需要为项目框架启动支持。

根目录新增文件 tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

eslint

需要配置语法检查相关的内容,用于合理的报错和支持类型系统,不配置这个IDE会报一堆乱七八糟的问题。

首先安装插件

npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

然后再eslint配置中增加

'plugin:@typescript-eslint/recommended',
parser: '@typescript-eslint/parser',
plugins: ['react-refresh', '@typescript-eslint'],

配置好后大概是这样的

module.exports = {
    root: true,
    env: {browser: true, es2020: true},
    extends: [
        'eslint:recommended',
        'plugin:react/recommended',
        'plugin:react/jsx-runtime',
        'plugin:react-hooks/recommended',
        'plugin:@typescript-eslint/recommended',
    ],
    parser: '@typescript-eslint/parser',
    ignorePatterns: ['dist', '.eslintrc.cjs'],
    parserOptions: {ecmaVersion: 'latest', sourceType: 'module'},
    settings: {react: {version: '18.2'}},
    plugins: ['react-refresh', '@typescript-eslint'],
    rules: {
        'react-refresh/only-export-components': [
            'warn',
            {allowConstantExport: true},
        ],
        'react/prop-types': 'off', // 可以在这里关闭 prop-types 检查
    },
}

需要注意,加了这个支持后,可能会在js中报出一些错误,例如之前可以忽略大小写的引用文件,现在会标红。

如果所有的jsx都转换为了tsx,建议开启 react/prop-types,反之不建议。尽量让项目的报错都是可以处理的,然后都处理了,避免warning太多了,习惯性忽略导致缺陷。

vite

一般不用配,vite会在构建时读取ts配置。

使用

新增一个ts文件

import {Button} from "antd";

export function Cmd() {
    const baseurl: string = "/cmd/";
    return <Button type="primary" href={baseurl}>Cmd</Button>
}

在js中引用

import {Cmd} from "./tool/Cmd.tsx";

需要注意一个webstorm的缺陷(我不确定是他的还是因为我中间改了ts,漏了改配置):

  • 直接写Cmd然后alt+enter自动生成的导入代码是import {Cmd} from "./tool/Cmd.jsx";,后缀需要手动改下,不然找不到的。

后言

我前端是半路出家,node是没有系统学过的,也就是写vuereact的时候顺手学了一点。所以很多都是师从chatgpt。gta4以后不冲会员也能上传图片回答问题,甚至可以截图报错,在对话中一点点解决问题。还是很不错的。

image-kmrr.png

还有就是copilot对于重复工作的帮助很大。之前跨文件读取还是有点问题,我需要以注释的形式提示ai。但是现在写逻辑时甚至会根据上一个后端代码的逻辑去找对应的协议和引用的底层代码,并直接生成桥接的代码,可以说是很不错了。

最后,我之前对于web工程还是有点一知半解,整理了一下清晰多了,果然费曼学习法的效果不错。当然不足之处也请读者们斧正。

License:  CC BY 4.0