awesome-typescript-loader 不接受 JSON 中的更改

Posted

技术标签:

【中文标题】awesome-typescript-loader 不接受 JSON 中的更改【英文标题】:awesome-typescript-loader does not pick up changes in JSON 【发布时间】:2019-07-08 18:28:55 【问题描述】:

假设我有一些 JSON 文件(我们将其命名为 template.json


    "myField1": "",
    "myField2": ""

我也有一种泛型类

export default GenericClass<T> 
    // Creating an empty constuctor with passed type.
    // to allow define type automatically.
    // This allow us not to manually set generic type for class
    // and also allows Webpack to pick up changes.
    constructor(template?: T)  

    // ...some fields and methods

    get typedField(): T 
        return /* something slightly calculated */
    

我在我的 Typescript 项目中像使用类型一样使用它:

import GenericClass from "path/to/GenericClass"
import template from "template.json"

export type TemplateType = typeof template
export default new GenericClass(template)

// we can also write
//     export default new GenericClass<TemplateType>()
// but in this case the changes in template.json
// won't be picked up by Webpack.
// However, this does not affects the problem,
// it occurs in both cases.

我正在运行webpack dev-server,并在某处使用它:

import * as React from "react"
import GenericInstance from "path/to/GenericInstance"

export default MyComponent extends React.Component 
    render() 
        var  typedField  = GenericInstance
        return (
            <main>
                <p>typedField.myField1 /* ok */</p>
                <p>typedField.myField2 /* ok */</p>
            </main>
        )
    

之后,我将在template.json 中添加一个新字段:


    "myField1": "",
    "myField2": "",
    "myField3": ""   

保存。 webpack dev-server 在 template.json 中获得了这一变化。好的。 一件重要的事情是 VSCode 的自动完成功能(它在可用字段列表中显示此 myField3)。很好。

此时,当我尝试在MyComponent(如&lt;p&gt;typedField.myField3&lt;/p&gt;)中使用myField3 时,awesome-typescript-loader 在编译期间发送错误:

类型 ' "myField1": string; 上不存在属性 'myField3' “myField2”:字符串; '

很明显,awesome-typescript-loader 没有发现 template.json 中的更改,GenericClass 中用作类型。

我怎样才能打败它?重新启动开发服务器后,它可以正常工作,直到我在 template.json 中进行更改。

部分webpack.config.jspackage.jsontsconfig.json

config = 
    rules: 
        
            test: /\.tsx?$/,
            loader: "awesome-typescript-loader",
            exclude: /node_modules/
        ,
        
            enforce: "pre",
            test: /\.js$/,
            loader: "source-map-loader"
        ,
    


    "devDependencies": 
        "awesome-typescript-loader": "^5.2.1",
        "source-map-loader": "^0.2.4",
        "typescript": "^3.3.3",
        "webpack": "^4.29.3",
        "webpack-cli": "^3.2.3",
        "webpack-dev-server": "^3.1.14"
    


    "compilerOptions": 
        "module": "esnext",
        "target": "es5",
        "moduleResolution": "node",
        "baseUrl": "src",
        "allowSyntheticDefaultImports": true,
        "noImplicitAny": true,
        "strict": false,
        "sourceMap": true,
        "outDir": "dist/",
        "jsx": "react",
        "traceResolution": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "allowJs": true,
        "declaration": false,
        "removeComments": true,
        "noLib": false,
        "preserveConstEnums": true,
        "suppressImplicitAnyIndexErrors": true,
        "types": [ "node" ],
        "lib": ["es6", "dom", "dom.iterable"],
        "downlevelIteration": true,
        "resolveJsonModule": true,
        "typeRoots": [
            "./node_modules/@types"
        ]
    ,
    "include": [
        "src/**/*"
    ]


更新

我可以确认这只发生在导入的 *.json 中。问题可能与 TypeScript 的 resolveJsonModule 设置有关,但不确定。将useCacheusePrecompiledFiles 显式设置为falsewebpack.config.js 中的awesome-typescript-loader 没有帮助。我的意思是,更改后的webpack.config.js 现在看起来像:


    test: /\.(t|j)sx?$/,
    loader: "awesome-typescript-loader",
    options: 
        useCache: false,
        usePrecompiledFiles: false
    ,
    exclude: /node_modules\/(?!superagent)/,
,

【问题讨论】:

在 typescript 中使用 json 文件作为模块时,模块的缓存行为可能不同。您能否将该 json 文件更改为 typescript 模块/对象文字并导出? @DerAlex 感谢您的评论。 AFAIK,默认情况下禁用 atl 中的文件缓存。我明白你在说什么,而且,可能这是真的,但如果这是真的,那么,似乎没有办法解决它(根据atl docs)。我很难将 json 与模块或对象字面量交换,因为很多事情都依赖于它,但我会尝试 :) "之后我在我的 template.json 中添加了一个新字段:" 你在这句话下面的 JSON 中漏掉了一个逗号 @Seblor 是的,当然,只是一个错字。我从头开始在这个问题中创建了代码) 可以,达到2000分后无需等待审核即可编辑问题和答案。 【参考方案1】:

这是awesome-typescript-loader 中的一个错误。从 v5.2.1 开始,这里有一个快速修复:

// node_modules/awesome-typescript-loader/dist/instance.js

// ln: 214:
- var EXTENSIONS = /\.tsx?$|\.jsx?$/;
+ var EXTENSIONS = /\.tsx?$|\.jsx?|\.json$/;

显然作者忘记将.json 扩展名作为有效目标。

【讨论】:

公关被解雇:github.com/s-panferov/awesome-typescript-loader/pull/629 感谢您的回答。我修改了你提到的文件,但没有解决问题:( @LevitatorImbalance 这很奇怪。根据您的描述,我能够重现该错误,并通过修改该行解决了我的错误。我们的设置一定有其他不同吗? 您可能希望在该instance.js 文件中放置一个console.log,以检查它是否是at-loader 实例使用的实际源文件。 好吧,检查所有,扩展被修改。将import * as template from "template.json" 更改为import template from "template.json",问题就消失了。但是您的解决方案和拉取请求是完全正确的。谢谢!

以上是关于awesome-typescript-loader 不接受 JSON 中的更改的主要内容,如果未能解决你的问题,请参考以下文章

awesome-typescript-loader 不接受 JSON 中的更改

使用 Webpack 2 和 awesome-typescript-loader 的 baseUrl 和路径解析

TS2304:找不到名称“要求”

使用jQuery和Visual Studio SPA模板

可选链打包报错

react的ts配置