使用 spec/test 文件夹设置 tsconfig

Setting up tsconfig with spec/test folder

假设我将我的代码放在 src 下并在 spec 下测试:

+ spec
+ --- classA.spec.ts
+ src
+ --- classA.ts
+ --- classB.ts
+ --- index.ts
+ tsconfig.json

我只想将 src 转译到 dist 文件夹。因为 index.ts 是我包的入口点,所以我的 tsconfig.json 看起来像这样:

{
  "compileOptions": {
    "module": "commonjs"
    "outDir": "dist"
  },
  "files": {
    "src/index.ts",
    "typings/main.d.ts"
  }
}

但是,这个 tsconfig.json 不包含测试文件,所以我无法解析其中的依赖关系。

另一方面,如果我将测试文件包含到 tsconfig.json 中,那么它们也会被转译到 dist 文件夹中。

如何解决这个问题?

我认为你不应该在你的配置中使用 'files' 选项。相反,您可以排除不需要的文件并像这样:

{ 
    "compilerOptions": { 
        "module": "commonjs", 
        "outDir": "dist"
    },
    "exclude": [
        "node_modules",
        "dist",
        "typings/browser.d.ts",
        "typings/browser/**"
    ]
} 

这将在 'dist' 文件夹中保留您的原始结构,而不会混合测试和应用程序 js 文件:

--dist
----spec
-------....
----src
-------....

我最终定义了多个配置文件并使用 extends 来简化它们。

假设我有两个文件:tsconfig.jsontsconfig.build.json

// tsconfig.json
{
  ...
  "exclude": [...]
}

// tsconfig.build.json
{
  ...
  "files": [ "typings/index.d.ts", "src/index.ts" ]
}

这样,我可以很好地控制要构建的内容(使用 tsc -p tsconfig.build.json)以及 ts language service (IDE) 处理的内容。

更新:现在随着我的项目的增长,我最终拥有了更多的配置文件。我使用 TypeScript 中现在可用的 "extend" 功能:

// tsconfig.base.json
{
  // your common settings. Mostly "compilerOptions".
  // Do not include "files" and "include" here,
  // let individual config handles that.
  // You can use "exclude" here, but with "include",
  // It's pretty much not necessary.
}

// tsconfig.json
{
  // This is used by `ts language service` and testing.
  // Includes source and test files.
  "extends": "./tsconfig.base.json",
  "atom": { ... },
  "compilerOptions": {
    // I set outDir to place all test build in one place,
    // and avoid accidentally running `tsc` littering test build to my `src` folder.
    "outDir": "out/spec"  
  }
  "include": [ ... ]
}

// tsconfig.commonjs.json or tsconfig.systemjs.json or tsconfig.global.json etc
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    // for some build this does not apply
    "declaration": true/false,
    "outDir": "dist/<cjs, sys, global, etc>",
    "sourceRoot": "..."
  },
  // Only point to typings and the start of your source, e.g. `src/index.ts`
  "files": [ ... ],
  "include": [ ... ]
 }

这在某种程度上取决于您使用的测试框架,但我喜欢使用 ts-node 来编译我的测试文件。使用 mocha,您的 npm test 脚本可能如下所示:

"mocha": "mocha test/ --compilers ts:ts-node/register --recursive"

在您的 tsconfig.json 中,确保删除 rootDir 选项。

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "removeComments": true,
        "sourceMap": true,
        "outDir": "lib"
    },
    "include": [
        "src/**/*.ts"
    ],
    "exclude": [
        "node_modules",
        "lib",
        "typings/**"
    ]
}

当您尝试 运行 打字稿 rootDir 设置为 src 或任何应用程序代码的基本文件夹时,它将不允许在位于的目录中进行任何编译外面,这样的tests。使用 ts-node,您可以轻松地将所有内容分开,而无需单独的 TypeScript 配置文件。

这里是管理源和测试的详细解决方案:

  • 编译包括源代码和测试folders/files
  • build 仅包含源代码
  • IDE (VSCode, ...)

配置

该解决方案基于其他答案中提到的 2 个 tsconfig.json 文件。

主要./tsconfig.json(用于编译和IDE):

{
  "compileOptions": {
    "module": "commonjs"
    "outDir": "dist"
  },
  "include": [
    "spec/**/*.spec.ts"
  ],
  "files": [
    "src/index.ts"
  ]
}

第二个./tsconfig-build.json(用于构建):

{
  "extends": "./tsconfig.json",
  "exclude": [
    "spec/**/*.spec.ts"
  ]
}

注意:我们排除了之前包含的测试文件

建造

构建命令:tsc -p tsconfig-build.json

npm run build如果在package.json中添加了脚本:

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

只需添加一个包含要编译并包含在构建中的源文件的目录。接下来,在 tsconfig.json 中指定您的排除目录。对于您的用例,没有必要拥有多个 tsconfig 文件。

{
  "include": [ "src/**/*" ],
  "exclude": [ "./spec" ]
}

对我来说是因为我的 jest 版本是 26 而我的 ts-jest 版本是 27 所以他们不同步。

yarn jest --version
yarn add ts-jest@26

我的jest.config.js

module.exports = {
    preset: "ts-jest",
    moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
    transform: {
        "^.+\.tsx?$": "ts-jest",
    },
    globals: {
        "ts-jest": {
            diagnostics: false,
        },
    },
    testMatch: ["**/*.(test|spec).(ts|tsx|js|jsx)"],
    coveragePathIgnorePatterns: ["/node_modules/"],
    coverageReporters: ["json", "lcov", "text", "text-summary"],
    transformIgnorePatterns: [
        "<rootDir>/node_modules/(?!(firebase/.*|react/.*)/)",
    ],
    testEnvironment: "jest-environment-jsdom-sixteen",
    moduleNameMapper: {
        "\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
            "<rootDir>/__mocks__/mocks.js",
        "\.(css|less|scss)$": "<rootDir>/__mocks__/mocks.js",
        "^src/(.*)": "<rootDir>/src/",
    },
};