Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

awesome-typescript-loader does not pick up changes in JSON

Assume I have some JSON file (let's name it template.json)

{
    "myField1": "",
    "myField2": ""
}

I also have a kind of generic class

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 */
    }
}

I'm using it like a type in my Typescript project:

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.

I'm running the webpack dev-server, and use it somewhere:

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>
        )
    }
}

After that I'm adding a new field into my template.json:

{
    "myField1": "",
    "myField2": "",
    "myField3": ""   
}

Saving it. webpack dev-server picks up this change in template.json. Allright. One important thing is that autocomplete of VSCode works (it shows this myField3 in list of available fields). Fine.

At this moment, when I'm trying to use myField3 in MyComponent (like <p>{typedField.myField3}</p>), awesome-typescript-loader sends an error during compilation:

Property 'myField3' does not exist on type '{ "myField1": string; "myField2": string; }'

Obviously, awesome-typescript-loader did not pick up changes in template.json which is used as type in my GenericClass.

How can I beat it? After restart of the dev-server it works fine until I make changes in template.json.

Partial webpack.config.js, package.json and tsconfig.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/**/*"
    ]
}

Update

I can confirm that this occurs only with imported *.json. Probably, the problem can be in touch with resolveJsonModule setting for TypeScript, but not sure. Setting useCache and usePrecompiledFiles to false explicitly for awesome-typescript-loader in webpack.config.js does not help. I mean, changed webpack.config.js now looks like:

{
    test: /\.(t|j)sx?$/,
    loader: "awesome-typescript-loader",
    options: {
        useCache: false,
        usePrecompiledFiles: false
    },
    exclude: /node_modules\/(?!superagent)/,
},
like image 543
Limbo Avatar asked Feb 14 '19 16:02

Limbo


1 Answers

This is a bug in awesome-typescript-loader. As of v5.2.1, here's a quick fix:

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

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

Apparently the author forget to include .json extension as a valid target.

like image 79
hackape Avatar answered Nov 15 '22 00:11

hackape