如何使用webpack动态加载json模式到typescript

问题描述 投票:5回答:1

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

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对象。

我究竟做错了什么?

typescript webpack loader jsonschema
1个回答
2
投票

使用appendTsSuffixTo

我认为如果您使用ts-loaderappendTsSuffixTo option,您的设置将起作用,而不是自己在自定义加载程序中更改文件名。如评论中所述,您可能还需要调整导入或导出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调试了一下,看看发生了什么。

如果我自己修改resourcePath,在ts-loader/dist/index.js上看起来很好,但在ts-loader/dist/servicesHost.js开始出现问题。

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

我不是ts-loader的贡献者(或专家),但我对此的看法是,在加载器中修改this.resourcePath时,你的.schema.json文件确实会编译,但无论何时导入它都无法解决。

其他考虑因素

让你的w​​ebpack构建运行是一回事;在IDE中提供良好的开发人员体验是另一回事。有关这方面的更多想法,请参阅this answer一个密切相关的问题,有关工作示例代码的this Github repo可能会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.