首页 > 解决方案 > 根据同一个通用本地模块打包多个 Typescript 项目

问题描述

我正在开发一组 VSTS 扩展。每个扩展都是它自己的小节点项目,有自己的package.json和自己的node_modules文件夹。文件夹结构如下:

 - MyExtension
   - package.json // containing all dev-dependencies
   - tslint.json
   - Tasks
     - tsconfig.json
     - Common
       - common.ts    // containing functioanlity shared across tasks
       - package.json // containing all runtime dependencies for all projects
     - My1stTask
       - package.json // containing all prod-dependencies
       - task.ts      // containing task implementation
     - ...
     - ...
     - My6thTask
       - package.json // containing all prod-dependencies
       - task.ts      // containing task implementation

VSTS 构建任务的工作方式是它们应该是完全独立的。到目前为止,我已经通过将Common项目的内容复制到每个任务中,然后运行tsc将它们全部转换为 JavaScript 来解决这个问题。

这还不错,但需要不断复制 Common 的内容才能进行任何测试。

我尝试使用本地文件引用,在每个任务的 package.json 中添加了一个依赖项file:../common,这在开发时有效,但这不会导致公共模块在生成扩展后成为任务的一部分。

我的背景不是 Node 开发,而是 C#。我已经搜索了所有内容,但没有找到适用于 vsts-extensions 的解决方案。

有没有一种方法可以让我“无缝”地完成这项工作,而不必承担 bower 或 grunt 并简单地让每个 MyXthTask 在其node_modules文件夹中拥有本地公共模块的副本?

标签: typescriptnpmazure-pipelines-build-taskazure-devops-extensions

解决方案


我尝试了@matt-mccutchen 的方法,但不幸的是,由于这些任务需要commonjs

"compilerOptions": {
  "module": "commonjs",
  "target": "es6", 

但我确实找到了适合我的解决方案。

Tasks文件夹中,我添加了一个tsconfig.json定义我的默认设置并包含公共库中的文件的文件夹:

{
  "compileOnSave": true,
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "sourceMap": true,
    "strict": false,
    "strictNullChecks": false,
    "removeComments": true
  },
  "files": [
    "./Common/uuidv5.d.ts",
    "./Common/Common.ts"
  ]
}

然后在每个任务中,我创建了一个tsconfig.json将输出文件夹设置为该项目的当前文件夹并从文件夹中继承tsconfig.jsonTasks

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
      "outDir": "./", 
      "sourceRoot": "./"
  },
  "files": [
      "InstallExtension.ts"
  ]
}

这导致:

 - MyExtension
   - package.json // containing all dev-dependencies
   - tslint.json
   - Tasks
     - tsconfig.json   // Including Common by default
     - Common
       - common.ts     // containing functionality shared across tasks
       - package.json  // containing all runtime dependencies for Common
       - tsconfig.json // containing build configuration for just the common files, inherits from ..\Task\tsconfig.json
     - My1stTask
       - package.json  // containing all prod-dependencies for the task
       - task.ts       // containing task implementation
       - tsconfig.json // containing build configuration for the task, inherits from ..\Task\tsconfig.json
     - ...
     - ...
     - My6thTask
       - package.json // containing all prod-dependencies
       - task.ts      // containing task implementation
       - tsconfig.json // containing build configuration for the task, inherits from ..\Task\tsconfig.json

编译任务时如下

     - My6thTask
       - Common
         - Common.js   // Compiled common
       - My6thTask
         - task.js     // Compiled task
       - package.json  // containing all prod-dependencies
       - task.ts       // containing task implementation
       - task.json     // defining the task UI
       - tsconfig.json // containing build configuration for the task

我唯一需要添加的task.ts是以下内容:

///<reference path="../Common/Common.ts"/>
import * as common from "../Common/Common";

并将 task.json 中的执行处理程序更改为指向新位置:

  "execution": {
    "Node": {
      "target": "InstallExtension/InstallExtension.js", // was: InstallExtension.js
      "argumentFormat": ""
    }
  }

一切似乎都很好:D。结合使用,glob-exec我能够在构建干净时将构建时间减少到不到一分钟:

"initdev:npm": "npm install & glob-exec --parallel --foreach \"Tasks/*/tsconfig.json\" -- \"cd {{file.dir}} && npm install\"",
"compile:tasks": "glob-exec \"Tasks/*/tsconfig.json\" -- \"tsc -b {{files.join(' ')}}\"",
"lint:tasks": "glob-exec --parallel --foreach \"Tasks/*/tsconfig.json\" -- \"tslint -p {{file}}\"",

推荐阅读