【问题标题】:How to dynamically load json schema to typescript with webpack如何使用 webpack 将 json 模式动态加载到 typescript
【发布时间】:2017-12-16 12:20:04
【问题描述】:

我有一个描述对象 Person 的 json 模式。我希望能够以这种方式直接将该模式加载到打字稿文件中:

import Person from './schema/person.schema.json';

为此,我创建了一个加载器,它将 json 文件转换为 typescript 接口声明(使用json-schema-to-typescript),然后将结果传递给 ts-loader。

我的 webpack 是这样配置的:

webpack.config.js(摘录)

module: {
  rules: [
    {
      test: /\.ts$/,
      loader: 'ts-loader',
    },
    {
      test: /\.schema\.json$/,
      loader: 'ts-loader!jsonschema-loader',
      exclude: /(node_modules)/,
    },
  ]
},

question 之后,我配置了一个声明,以便将 json 文件视为字符串:

declaration.d.ts

declare module '*.schema.json' {
  const schema: string;
  export default schema;
}

我的加载器会即时更改它处理的文件名,所以 ts-loader 认为它加载的是person.schema.ts。此外,我检查了我的加载程序的结果是正确的。这里是:

/**
 * This file was automatically generated by json-schema-to-typescript.
 * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
 * and run json-schema-to-typescript to regenerate this file.
 */

export interface Person {
  firstName: string;
  lastName: string;
  /**
   * Age in years
   */
  age?: number;
  [k: string]: any;
}

但是,当我构建我的项目时,Person 未被识别为对象并且编译失败:

index.js

import Person from './schema/person.schema.json';

const person: Person = {
  lastName: 'Doe',
  firstName: 'John',
};
console.log(person);

编译失败:

ERROR in ./src/index.ts
(3,15): error TS2304: Cannot find name 'Person'.

虽然我在声明中将 .schema.json 文件的导出定义为字符串,但我的加载器会动态地将文件名 (this.resourcePath) 更改为 ts 文件,因此 ts-loader 应该将其视为标准 ts 文件并导出Person 对象。

我做错了什么?

【问题讨论】:

  • 可能会有所帮助,stackoverflow.com/q/31173738/794088
  • 由于 Person 不是默认导出,请尝试: import { Person } from './schema/person.schema.json';
  • @Daniel 实际上,他需要export default interface Person

标签: typescript webpack loader jsonschema


【解决方案1】:

使用appendTsSuffixTo

如果您使用ts-loaderappendTsSuffixTo option,我认为您的设置将起作用,而不是在您的自定义加载程序中自己更改文件名。如 cmets 中所述,您可能还需要调整 Person 的导入或导出方式。

使用appendTsSuffixTo,您将从加载程序中删除this.resourcePath = this.resourcePath + '.ts';(或类似代码)。然后将您的 webpack 配置调整为如下所示:

  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'ts-loader',
        options: {
            appendTsSuffixTo: [/\.schema.json$/]
          }
      },
      {
        test: /\.schema\.json$/,
        loader: 'ts-loader!my-own-loader',
        exclude: /(node_modules)/,
      },
    ]
  },

您也可以使用这种方法摆脱typings.d.ts

但是为什么呢?

我并不清楚为什么你的方法行不通;直觉上它似乎应该等同于使用appendTsSuffixTo。于是我通过ts-loader调试了一下,看看发生了什么。

如果我自己修改resourcePathts-loader/dist/index.js 中的情况基本正常,但ts-loader/dist/servicesHost.js 中的情况开始出现问题。

具体来说,当我在加载程序中更改this.resourcePath 时,我看到resolveModuleName() 为我的example.schema.json 文件返回undefined。但是,我看到它在使用 appendTsSuffixTo 时可以正确解决。

我不是ts-loader 的贡献者(或专家),但我对此的看法是,在加载程序中修改this.resourcePath 时,您的.schema.json 文件确实会编译,但随后无法解决无论在哪里导入。

其他注意事项

让你的 webpack 构建运行是一回事;在 IDE 中提供良好的开发人员体验是另一回事。有关此问题的更多想法,请参阅this answer 与密切相关的问题,并请参阅 this Github repo 以获取可能有用的工作示例代码。

【讨论】:

    猜你喜欢
    • 2017-08-22
    • 2013-08-24
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 2018-07-29
    • 2015-04-18
    相关资源
    最近更新 更多