• TypeScript Project References npm 包构建小实践


    npm 包输出 es/cjs 产物

    在开发一个 npm 包时,通常需要同时输出 ES 模块和 CommonJS 模块的产物供不同的构建进行使用。在只使用tsc进行产物编译的情况下,我们通常可以通过配置两个独立的 tsconfig.json 配置文件,并在一个 npm script 中 执行两次 tsc 命令来实现

    项目结构

    假设我们的项目结构如下:

    my-package/
    ├── src/
    │   └── index.ts
    ├── dist/
    │   ├── es/
    │   └── cjs/
    ├── package.json
    ├── tsconfig.es.json
    └── tsconfig.cjs.json
    

    配置 TypeScript

    tsconfig.es.json

    为 ES 模块创建一个 tsconfig.es.json 文件:

    {
        "compilerOptions": {
            "rootDir": "src",
            "module": "ESNext",
            "moduleResolution": "Node",
            "outDir": "dist/es"
        },
        "include": ["src"]
    }
    

    tsconfig.cjs.json

    为 CommonJS 模块创建一个 tsconfig.cjs.json 文件:

    {
        "compilerOptions": {
            "rootDir": "src",
            "module": "CommonJS",
            "moduleResolution": "Node",
            "outDir": "dist/cjs"
        },
        "include": ["src"]
    }
    

    配置构建脚本

    在 package.json 中,我们可以添加以下脚本来构建我们的项目,执行两次 tsc 并分别指定不同的配置文件

    {
        "scripts": {
            "build": "tsc -p tsconfig.es.json && tsc -p tsconfig.cjs.json",
        }
    }
    

    通过运行 npm run build,可以生成同时包含 ES 模块和 CommonJS 模块的产物

    TypeScript 的 references 是什么

    TypeScript 的项目引用(Project References)是 TypeScript 3.0 引入的一项功能,允许一个 TypeScript 项目引用另一个 TypeScript 项目。这使得我们可以将大型代码库拆分为多个较小的项目,并且这些项目可以相互依赖

    Project References 的好处

    • 增量编译:当项目引用被正确配置时,TypeScript 只会重新编译发生变化的部分,从而大幅提升编译速度。
    • 模块化:通过项目引用,可以将代码库拆分为多个独立的、可复用的模块,提升代码的可维护性和可读性。
    • 类型安全:项目引用确保了项目之间的类型安全,避免了类型不一致的问题。

    配置

    要使用项目引用,需要在 tsconfig.json 中添加 references 字段。例如:

    {
      "compilerOptions": {
        "composite": true,
        "declaration": true,
        "outDir": "./dist"
      },
      "include": ["src"],
      "references": [
        { "path": "../other-project" }
      ]
    }
    

    相应的子项目需要存在相应的tsconfig.json配置,并且配置compilerOptions.composite=true,这样才能被主项目引用。如

    {
        "compilerOptions": {
            "composite": true,
            "types": [],
            "rootDir": "src",
            "module": "ESNext",
            "moduleResolution": "Node",
            "outDir": "dist"
        }
    }
    

    使用 TypeScript 的 references 后如何实现一个命令 tsc 输出 ES 和 CommonJS 产物并且提升增量编译的性能

    仍以上面的项目结构为例子,我们使用 TypeScript 的项目引用来实现这个需求。

    项目结构

    假设我们的项目结构如下:

    my-package/
    ├── src/
    │   └── index.ts
    ├── dist/
    │   ├── es/
    │   └── cjs/
    ├── package.json
    ├── tsconfig.json
    ├── tsconfig.base.json
    ├── tsconfig.es.json
    └── tsconfig.cjs.json
    

    首先,我们需要在根目录下创建一个 tsconfig.json 文件,用于配置项目引用:

    {
      "files": [],
      "references": [
        { "path": "./tsconfig.es.json" },
        { "path": "./tsconfig.cjs.json" }
      ]
    }
    

    配置 tsconfig.es.json

    为 ES 模块创建一个 tsconfig.es.json 文件:

    {
        "extends": "./tsconfig.base.json",
        "compilerOptions": {
          "outDir": "./dist/es",
          "module": "ESNext"
        }
      }
    

    配置 tsconfig.cjs.json

    为 CommonJS 模块创建一个 tsconfig.cjs.json 文件:

    {
        "extends": "./tsconfig.base.json",
        "compilerOptions": {
          "outDir": "./dist/cjs",
          "module": "CommonJS"
        }
    }
    

    公共配置 tsconfig.base.json

    为了避免重复配置,我们可以创建一个 tsconfig.base.json 文件,包含通用的配置:

    
    {
      "compilerOptions": {
        "target": "ES5",
        "declaration": true,
        "moduleResolution": "node",
        "esModuleInterop": true,
        "skipLibCheck": true,
        "composite": true,
        "rootDir": "src"
      },
      "include": ["src"]
    }
    

    构建脚本

    在 package.json 中,我们可以添加以下脚本来构建我们的项目

    {
      "scripts": {
        "build": "tsc -b"
      }
    }
    

    此时我们不再需要执行两次 tsc 命令,而是只需要执行一次 tsc -b 命令即可输出符合我们需求的 es + cjs 产物(和上面的两次执行 tsc 是一样的效果)。

    在这个场景下 TypeScript 会根据项目引用的配置,自动构建 ES 模块和 CommonJS 模块,并且只会重新编译发生变化的部分,从而提升增量编译的性能

  • 相关阅读:
    python pytesseract 中文文字批量识别
    vue网页缓存页面与不缓存页面处理
    java自定义注解
    [附源码]计算机毕业设计JAVA基于JSP的美妆购买网站
    一文搞懂什么是归一化,以及几种常用的归一化方法(超详细解读)
    第1章 Java 概述及开发环境搭建
    糟糕,接口被刷了,怎么办?
    unity中的模型坐标系与3dmax导出的模型坐标系不一致的解决方案
    SpringCloud Alibaba之Seata分布式事务学习笔记
    【深入理解设计模式】模板方法模式
  • 原文地址:https://blog.csdn.net/flytam/article/details/140109365