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

аюсь создать загрузчик веб-пакетов, который преобразует файл, содержащий описание структур данных API, в набор интерфейсов TypeScript.

В моем конкретном случае файл представляет собой JSON, но это в конечном итоге не имеет значения - файл является лишь общим источником данных, описывающих взаимодействие между бэкэндом (-ами) веб-приложения и веб-интерфейсом (-ами). В моем MCVE ниже вы можете видеть, что файл JSON содержит пустой объект, чтобы подчеркнуть, как тип и содержимое файла не имеют значения для проблемы.

Моя текущая попытка сообщает о двух ошибках (я полагаю, что вторая вызвана первой):

[at-loader]: Child process failed to process the request:  Error: Could not find file: '/private/tmp/ts-loader/example.api'.
ERROR in ./example.api
Module build failed: Error: Final loader didn't return a Buffer or String

Как я могу сгенерировать код TypeScript с помощью загрузчика веб-пакетов?

package.json
{
  "name": "so-example",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "build": "webpack"
  },
  "dependencies": {
    "awesome-typescript-loader": "^3.2.3",
    "typescript": "^2.6.1",
    "webpack": "^3.8.1"
  }
}
webpack.config.js
const path = require('path');

module.exports = {
  entry: './index.ts',
  output: {
    filename: 'output.js',
  },
  resolveLoader: {
    alias: {
      'my-own-loader': path.resolve(__dirname, "my-own-loader.js"),
    },
  },
  module: {
    rules: [
      {
        test: /\.api$/,
        exclude: /node_modules/,
        use: ["awesome-typescript-loader", "my-own-loader"],
      },
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        loader: "awesome-typescript-loader",
      },
    ]
  },
};
мой-собственный loader.js
module.exports = function(source) {
  return `
interface DummyContent {
    name: string;
    age?: number;
}
`;
};
index.ts
import * as foo from './example';

console.log(foo);
example.api
{}

Я признаю, что существуют другие методы генерации кода. Например, я мог бы преобразовать мои файлы JSON в TypeScript с помощью какого-либо инструмента сборки и проверить их. Я ищу более динамичное решение.

my-own-loader.js экспортирует не json, а строку.

Это правильно, так же как загрузка файла изображения не всегда экспортирует двоичные данные, но иногда выводит структуру данных JavaScript, представляющую метаданные об изображении.

Почему вам нужно определить интерфейсы машинописного текста из файла json? Будут ли интерфейсы использоваться для компиляции машинописи?

Да. Я хочу импортировать файл, который описывает мои структуры данных API и автоматически генерировать соответствующие интерфейсы TypeScript. Наличие общего файла позволяет фронтэнду (-ам) и бэкэнду (-ам) всегда согласовывать, какие данные будут присутствовать.

 Thaadikkaaran13 нояб. 2017 г., 10:56
my-own-loader.js не экспортирует JSON, но строку. Чего ты пытаешься достичь?
 Thaadikkaaran14 нояб. 2017 г., 06:40
Почему вам нужно определить интерфейсы машинописного текста из файла json? Будут ли интерфейсы использоваться для компиляции машинописи?
 Shepmaster13 нояб. 2017 г., 14:31
@Thaadikkaaran Есть ли у вас какие-либо предложения о том, как я мог бы перефразировать мое первое предложение: «преобразует файл JSON в набор интерфейсов TypeScript»? Я думал, что этого будет достаточно, чтобы объяснить мою цель. Мой конкретный пример - использовать JSON-файл для определения формы (a.k.a. TypeScriptinterface) объектов, передаваемых между внешним интерфейсом и внутренним интерфейсом.

Ответы на вопрос(2)

вы можете использовать пакет npmСваггер-TS-генератор генерировать из него файлы TypeScript:

Swagger TypeScript генератор кода

Узловой модуль для генерации кода TypeScript для Angular (2 и выше) на основе метаданных Webapi в формате Swagger v2.

По сути, вы даете ему благородный URL, и он генерирует TypeScript. Примеры для Gulp, но они должны довольно хорошо переноситься на WebPack:

var swagger = {
    url: 'http://petstore.swagger.io/v2/swagger.json',
    //url: 'http://127.0.0.1/ZIB.WebApi.v2/swagger/docs/v1',
    swaggerFile: folders.swaggerFolder + files.swaggerJson,
    swaggerFolder: folders.swaggerFolder,
    swaggerTSGeneratorOptions: {
        modelFolder: folders.srcWebapiFolder,
        enumTSFile: folders.srcWebapiFolder + 'enums.ts',
        enumLanguageFiles: [
            folders.srcLanguagesFolder + 'nl.json',
            folders.srcLanguagesFolder + 'en.json',
        ],
        modelModuleName: 'webapi.models',
        enumModuleName: 'webapi.enums',
        enumRef: './enums',
        namespacePrefixesToRemove: [
        ],
        typeNameSuffixesToRemove: [
        ]
    }
}
 Shepmaster16 нояб. 2017 г., 13:24
Из-за быстрого ознакомления с этими пакетами readme, это, кажется, опережающий инструмент генерации кода. Как я уже упоминал в этом вопросе, я уже знаю, что могу запустить команду, которая генерирует файлы и затем регистрирует их, но я ищу более динамичное решение.
Решение Вопроса

действительно интересный вопрос. Код, с которым я работал, чтобы соединить этот ответ, основан на упомянутом MCVE, идоступен здесь.

Файл отсутствует?

Это действительно самое бесполезное сообщение об ошибке. Файл явно находится в этом месте, но TypeScript откажется загружать все, что не имеет приемлемого расширения.

Эта ошибка по сути скрываетреальный ошибка, которая

TS6054: File 'c:/path/to/project/example.api' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'.

Это можно проверить, взломавtypescript.jsи вручную добавив файл. Это уродливо, как это часто бывает с детективной работой (начинается со строки 95141 в версии 2.6.1):

for (var _i = 0, rootFileNames_1 = rootFileNames; _i < rootFileNames_1.length; _i++) {
    var fileName = rootFileNames_1[_i];
    this.createEntry(fileName, ts.toPath(fileName, this.currentDirectory, getCanonicalFileName));
}
this.createEntry("c:/path/to/project/example.api", ts.toPath("c:/path/to/project/example.api", this.currentDirectory, getCanonicalFileName));

Концептуально, вы просто передаете строку между загрузчиками, но получается имя файлаявляется важно здесь.

Возможное исправление

Я не видел способ сделать это сawesome-typescript-loader, но если вы готовы использоватьts-loader вместо этого вы, безусловно, можете сгенерировать TypeScript из файлов с произвольными расширениями, скомпилировать этот TypeScript и вставить его в свойoutput.js.

ts-loader имеетappendTsSuffixTo вариант, что может быть использовано для обхода известногоболь при расширении файла, Конфигурация вашего веб-пакета может выглядетьнравится если вы пошли по этому пути:

rules: [
  {
    test: /\.api$/,
    exclude: /node_modules/,
    use: [
      { loader: "ts-loader" },
      { loader: "my-own-loader" }
    ]
  },
  {
    test: /\.tsx?$/,
    exclude: /node_modules/,
    loader: "ts-loader",
    options: {
      appendTsSuffixTo: [/\.api$/]
    }
  }
]

Обратите внимание на интерфейсы и DX

Интерфейсы стираются компилятором. Это можно продемонстрировать, запустивtsc против чего-то вродеэто

interface DummyContent {
    name: string;
    age?: number;
}

противэто

interface DummyContent {
    name: string;
    age?: number;
}

class DummyClass {
    printMessage = () => {
        console.log("message");
    }
}

var dummy = new DummyClass();
dummy.printMessage();

Чтобы обеспечить хороший опыт разработчика, вам может потребоваться записать эти интерфейсы в файл только в среде разработчика. Вам не нужно выписывать их для производственной сборки, и вам не нужно (или не нужно) проверять их в управлении версиями.

Разработчикам, вероятно, нужно выписать их, чтобы у их IDE было что-то, в чем можно было бы окунуться. Вы можете добавить*.api.ts в.gitignoreи не пускать их в хранилище, но я подозреваю, что они должны будут существовать в рабочих пространствах разработчиков.

Например, в моем примере репо, новый разработчик должен будет запуститьnpm install (по-прежнему)а также npm run build (чтобы создать интерфейсы в их локальной среде), чтобы избавиться от всех их красных волнистых попугайчиков.

 Shepmaster17 нояб. 2017 г., 05:24
Я не привязан к awesome-typcript-loader, я в основном просто использовал его, потому что он предлагал некоторые потенциальные ускорения (которые мне могут даже не понадобиться). Ваше мнение об опыте разработчиков интересно - один изДругие причины, по которым я хочу это выяснить, в том, что я используютипизации-для-CSS-модули-погрузчик, Это генерирует файлы .d.ts,ноначальная сборка не удалась, потому что файлов там нет, Это означает, что CI должен построить его дважды, что позволит первому потерпеть неудачу.

Ваш ответ на вопрос