скомпилировать другой каталог для машинописного текста без всех ссылок - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть проект сервера в TS, и я использую ts-node для его запуска. У меня есть другая папка с именем public, где я размещаю статические файлы.

Мне нужен способ записи файлов .ts в папку to_public, чтобы они имели проверки типов с интерфейсами с сервера, но выводились как .js без переноса всех файлов определений.

например.

// A.ts
export interface A { key: string }
// file.ts
import {A} from '../A.ts'
function f(a:A){ console.log(a.key) }

желаемый структура:

  • ЦСИ
    • A.ts
    • to_public
      • file.ts
  • общественность
    • file.js

мой tsconfig.json имеет

   "compilerOptions": {
      ...
     "outDir": "../../public/js/",
   }
  "include": [
   "../../src/public_ts"
  ],

Когда file.ts не ссылается ни на что, это прекрасно работает.

Но когда я ссылаюсь на что-либо из src, копируется вся структура папок. это фактический результат:

  • ЦСИ
    • A.ts
    • to_public
      • file.ts
  • общественность
    • A.js <- не нужно </li>
    • to_public
      • file.js

И хотя скомпилированный file.js ничего не ссылается, и я могу использовать его как есть, я не хочу, чтобы весь мой проект src был скопирован в public.

Любой совет? ТНХ

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Возможное время решения до дальнейших идей, вот что я придумал:

// to_public/definition.d.ts
export * from '../A.ts'

и

// to_public/file.ts
import {IA} from './definition'
function f(a:IA){ console.log(a.key) }
0 голосов
/ 06 ноября 2018

Решение с пакетом:

Ваш сценарий кажется хорошим вариантом использования для упаковщика. Это инструмент, который анализирует ваш код и рисует все зависимости, чтобы создать один выходной файл. Популярные варианты: webpack , browserify и посылка . Это означает, что зависимости, импортированные из A, будут включены в выходной файл, созданный для ваших общедоступных сценариев.

Parcel придерживается принципа «нулевой конфигурации», что означает, что он (очень сильно отличается от webpack или browserify) будет работать без настройки.

Я воссоздал ваш код:

  • ЦСИ
    • A.ts
    • to_public
      • file1.ts
      • file2.ts

У меня установлена ​​глобальная посылка (npm install -g parcel), поэтому я могу просто запустить:

parcel build src/to_public/*

Это смотрит на вашу папку to_public и связывает все скрипты внутри. Parcel знает о машинописи и автоматически вызывает компилятор машинописи. Полученные сценарии копируются в новый каталог dist/. Ваша папка теперь выглядит так:

  • ЦСИ
    • // ...
  • расстояние
  • file2.js

Для файлов за пределами вашей папки to_public вам нужна полная поддержка машинописного текста, но вам не нужно их компилировать. Для этого вы можете добавить флаг noEmit в ваш compilerOptions.

{
    "compilerOptions": {
        "module": "commonjs",
        "noEmit": true
    },
    "exclude": [
        "node_modules"
    ]
}

Посылка имеет несколько очень приятных функций. Например, он кэширует компиляцию и работает довольно быстро, если вы вызываете его несколько раз. Кроме того, он хорошо взаимодействует с другими инструментами из экосистемы Javascript. Взаимодействие с компилятором машинописи без проблем. Parcel использует ваши настройки из tsconfig и даже создает исходные карты по умолчанию.

Конечно, можно привести и веские аргументы в пользу альтернатив. Я рекомендую посылку здесь, потому что это происходит в основном с нулевой стоимостью. Вы просто устанавливаете пакет и без какой-либо конфигурации, он просто работает.

Решение без упаковщика:

Если вы хотите избежать упаковщика, вы можете использовать несколько конфигураций компилятора. Проблема в том, что машинопись должна знать об используемых вами интерфейсах. Это можно сделать, посмотрев на исходный код или прочитав файл определений. Таким образом, ваш ответ является жизнеспособным решением, но было бы неплохо, если бы определения были созданы автоматически. Я установил три конфига компилятора:

  • для общей проверки синтаксиса
  • для создания файлов определений
  • для компиляции общедоступного javascript

Конфигурация по умолчанию - эта, она будет подобрана вашим редактором. Я установил noEmit на true, чтобы избежать случайных компиляций, которые могут испортить структуру вашей папки.

tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "noEmit": true,
        "rootDir": "src"
    }
}

Затем я разбил ваш каталог исходников на src/server и src/to_public. Без этого разделения трудно исключить файлы из компилятора (вы должны перечислить их вручную).

Вот конфиг, который создает файлы объявлений. Он имеет флаг emitDeclarationOnly, а выходной каталог - ваша общедоступная папка javascript:

definitions.json
{
    "compilerOptions": {
        "module": "commonjs",
        "declaration": true,
        "emitDeclarationOnly": true,
        "noResolve": true,
        "rootDir": "src",
        "outDir": "src/to_public"
    }
}

Если вы запустите приведенную выше конфигурацию, она выдаст объявления из вашего серверного кода. Это может быть использовано для последней конфигурации компилятора. Он читает файлы в вашей папке to_public и компилирует их в выходной каталог. Важный флаг компилятора здесь noResolve, это позволит избежать копирования файлов объявлений в выходную папку.

public_scripts.json
{
    "compilerOptions": {
        "module": "commonjs",
        "noResolve": true,
        "rootDir": "src/to_public",
        "outDir":"public/"
    },
    "exclude": ["src/server"]
}

Теперь вы можете скомпилировать код с помощью

tsc -p definitions.json
tsc -p public_scripts.json

Обратите внимание на пути импорта. Если вы хотите использовать server/A.ts в to_public/file.ts, то вы импортируете "./server/A.ts"

...