【问题标题】:tsconfig.json for project with `src` and `tests`带有 `src` 和 `tests` 的项目的 tsconfig.json
【发布时间】:2017-03-12 11:26:16
【问题描述】:

我有一个(想要的)这样的结构:

- tsconfig.json
- src
    - app.ts
- tests
    - appTest.ts
    - appTest.js
- dist
    - app.js

如果没有 tests 文件夹,这样的 tsconfig.json 就可以正常工作:

{
    "compilerOptions": {
        "outDir":"dist"
    },
    "include" :[
        "src/**/*.ts"
    ]
}

但是,如果我将tests/**/*.ts 添加到include 元素,它还会将我的测试文件编译为dist 并更改其文件夹结构(可以理解,但不受欢迎)。

我可以告诉 TypeScript 编译器在项目中包含测试文件以支持诸如重构之类的事情,但在输出到 dist 时忽略它们吗?具体来说,我希望.js 按照上述结构中的建议编译到tests 目录中。

【问题讨论】:

标签: typescript


【解决方案1】:

您可以在tsconfig.json 中使用rootDirs 选项,例如:

{
  "compilerOptions": {
    "rootDirs": [
      "src",
      "tests"
    ]
  }
}

这可以在Typescript文档中查到,在这个页面(搜索Virtual Directory with rootDirs副标题):Module Resolution

【讨论】:

    【解决方案2】:

    从 tsconfig 中省略测试。使用 mocha 进行测试,不需要 tsconfig 来查找测试。

    在 package.config 中,使用类似

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

    在 tsconfig.json 中,做

    "include": [
        "src/**/*.ts"
    ],
    

    见Setting up tsconfig with spec/test folder

    【讨论】:

    • 我用mocha 6.1.4 尝试了这个解决方案并收到以下错误消息:ERROR: --compilers is DEPRECATED and no longer supported. 请参阅git.io/vdcSr 了解迁移信息。
    • 我使用了以下命令:mocha test/ --require ts-node/register --recursive
    【解决方案3】:

    如何完全分离测试?
    比如:

    - scripts
        - tsconfig.json
        - src
            - app.ts
        - dist
            - app.js
    - tests
        - tsconfig.json
        - src
            - appTest.ts
        - bin
            - appTest.js
    

    然后scripts/tsconfig.json 将如下所示:

    "compilerOptions": {
        "outDir": "dist",
        "rootDir": "src",
        ...
    }
    

    tests/tsconfig.json 看起来像:

    "compilerOptions": {
        "outDir": "bin",
        "rootDir": "src",
        ...
    }
    

    编辑

    我在webstorm中查看了这个解决方案,有两种选择:

    (1) 测试从scripts/dist导入的文件:

    scripts/tsconfig.json:

    "compilerOptions": {
        "outDir": "dist",
        "rootDir": "src",
        "declaration": true
    }
    

    tests/tsconfig.json:

    "compilerOptions": {
        "outDir": "bin",
        "rootDir": "src"
    }
    

    tests/src/apptest.ts:

    import * as app from "../../scripts/dist/app";
    
    ...
    

    tests/bin 的结果将如下所示:

    - tests
        - bin
            - apptest.js
    

    当你在scripts 中重构时,比如说scripts/src/app.ts 那么它确实对tests/src/apptest.ts 没有影响,但是由于源代码中的重构,编译它会失败。
    所以你会知道你需要更改测试文件(虽然它不会是自动的)。

    (2) 测试从scripts/src导入的文件:

    scripts/tsconfig.json 文件不需要启用declaration 选项,因为我们将直接使用源代码。

    tests/src/apptest.ts:

    import * as app from "../../scripts/dist/src";
    
    ...
    

    重构源代码将根据需要更改测试文件,但tests/bin 中的输出是这样的:

    - tests
        - bin
            - scripts
                - src
                    - app.js
            - tests
                - src
                    - apptest.js
    

    如果您不介意 tests/bin 的这种结构,那么您无需使用其他工具即可获得所需的内容。

    【讨论】:

      【解决方案4】:

      我已经通过使用 gulp 并将编译分为两个步骤解决了这种问题:

      var gulp = require('gulp');
      var ts = require('gulp-typescript');
      var sourcemap = require('gulp-sourcemaps');
      var replace = require('gulp-replace');
      
      var path = require('path');
      var merge = require('merge2');
      
      var paths = {
        source: "source/",
        output: "dist/",
        spec: "spec/"
      }
      
      gulp.task('compile:typescript', function () {
        var project = ts.createProject('tsconfig.json', {
          typescript: require('typescript')
        });
      
        var tsResult =  gulp.src(paths.source + '**/*.ts')
          .pipe(sourcemap.init())
          .pipe(project());
      
        return merge([
          tsResult.dts.pipe(gulp.dest(paths.output)),
          tsResult.js //fix issue with relative source path
            .pipe(sourcemap.write('.', { 
              sourceRoot: function (file) {              
                var relative = path.relative(file.path, path.join(__dirname, "source"));
                var relativeSource = path.join(relative, 'source')
                return relativeSource;
              }
            }))
            .pipe(gulp.dest(paths.output))
        ]);
      });
      
      gulp.task('compile:tests', function () {
        var project = ts.createProject('tsconfig.json', {
          typescript: require('typescript')
        });
      
        var tsResult = gulp.src(paths.spec + '**/*spec.ts')
          .pipe(sourcemap.init())
          .pipe(project());
      
        return tsResult.js //fix issue with relative source path
          .pipe(sourcemap.write('.', {
            sourceRoot: function (file) {
              var relative = path.relative(file.path, path.join(__dirname, "spec"));
              var relativeSource = path.join(relative, 'spec')
              return relativeSource;
            }
          }))
          .pipe(replace(/(require\('\..\/source\/)/g, 'require(\'..\/dist\/'))
          .pipe(gulp.dest(paths.spec));
      });
      

      您的测试源代码将来自实际源文件的import;这意味着你得到了正确的重构。

      源代码被编译到 dist 文件夹中。测试文件从 spec 文件夹编译并存储在同一位置。在编译规范文件期间,您“修复”导入路径,以便它们链接到编译的输出 - 使用 gulp-replace。

      还有一些其他的东西;在最近对 vscode 进行更新之前,outDir 只能指向一个文件夹。因此,为了在测试中也获得断点,规范 js 必须紧邻 ts 文件。如果你愿意,你现在可以避免这种情况,尽管我没有测试过。

      这里是重构:

      【讨论】:

        【解决方案5】:

        我发现一个简单的解决方案是创建一个 npm 脚本,它编译并删除 lib 文件夹中不需要的文件/文件夹。

        在您的 package.json 中包含以下脚本,以在 ts 编译后删除 lib 目录中的测试文件夹。

        "scripts": {
            "build": "./node_modules/.bin/tsc && rm -r ./lib/test",
        },
        

        【讨论】:

          【解决方案6】:

          注意:如果您使用 Mocha 作为测试工具,我的回答是。

          相关信息隐藏在几页中。

          首先,关于mocha的homepage:

          --要求,-r 在加载用户界面或测试文件之前需要一个模块。

          这对于:编译器如 ... TypeScript via ts-node (使用 --require ts-node/register) 很有用

          因此,您应该通过npm install ts-node --save-dev 安装ts-node。


          其次,关于 mocha 的wiki。

          我不会引用它,但你必须运行:

          $ mocha --require ts-node/register "test/**/*.ts"

          所以你的 package.json 可能看起来像这样:

            "scripts": {
              "pretest": "npx tsc",
              "test": "mocha './test/**/*.ts' --require ts-node/register --recursive"
            },
          

          你的 tsconfig.json 像这样:

            "include": [
              "./src"
            ]
          

          您不需要将您的/tests 文件夹包含到转译过程中。而且由于您直接在 .ts 测试和源文件上运行,因此不需要源映射;您的行号和调用堆栈仍然可用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-02-05
            • 2020-12-29
            • 2016-07-03
            • 2016-02-10
            • 2016-12-06
            • 2016-01-16
            • 1970-01-01
            • 2021-12-08
            相关资源
            最近更新 更多