Tsconfig.json для проекта с `src` и` test`

У меня есть (желаемая) структура:

- 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, как это предложено в структуре выше.

Ответ 1

Как насчет полного разделения тестов?
Что-то вроде:

- 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, тогда вы получите то, что просили, без необходимости использовать другие инструменты.

Ответ 2

Не используйте тесты из tsconfig. Используйте mocha для тестирования, для поиска тестов не нужен tsconfig.

В package.config используйте что-то вроде

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

В tsconfig.json выполните

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

Смотрите Настройка tsconfig с папкой spec/test

Ответ 3

Я решил эту проблему с помощью 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. Файлы тестов скомпилированы из папки спецификаций и хранятся в одном месте. Во время компиляции файлов спецификаций вы "исправляете" пути импорта, чтобы они ссылались на скомпилированный вывод - используя gulp -replace.

Есть еще несколько вещей; перед недавним обновлением vscode, outDir мог указывать только на одну папку. Таким образом, чтобы получить контрольные точки на тестах как хорошо, spec js должен был быть рядом с файлами ts. Вы могли бы избежать этого, если хотите, хотя я его не тестировал.

И вот рефакторинг:

введите описание изображения здесь

Ответ 4

Вы можете использовать опцию rootDirs в tsconfig.json, например:

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

На этой странице можно найти документы Typescript (поиск виртуальных каталогов с субтитрами rootDirs): Разрешение модуля

Ответ 5

Простое решение, которое я нашел, это создание npm script, который компилирует и удаляет нежелательные файлы/папки в папке lib.

Включите в свой пакет package.json следующий script, чтобы удалить тестовую папку в вашем каталоге lib после компиляции ts.

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

Ответ 6

Примечание. Мой ответ - если вы используете Mocha в качестве инструмента тестирования.

Соответствующая информация скрыта на нескольких страницах.

Во-первых, на главной странице мокко homepage:

--require, -r Требуется модуль перед загрузкой пользовательского интерфейса или тестовых файлов.

This is useful for: Compilers such as... TypeScript via ts-node (using --require ts-node/register)

Следовательно, вы должны установить ts-node через npm install ts-node --save-dev.


Во-вторых, на мокко вики.

Я не буду цитировать это, но вы должны бежать:

$ 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 test & исходные файлы, исходная карта не требуется; Ваши номера линий и стек вызовов остаются пригодными для использования.