12

I'm using webpack@4.16.1, webpack-dev-server@3.1.4 and ts-loader@4.4.2.

I use Interface/index.ts to manage imports, to organize multiple interface imports.

But When I change interface file, webpack-dev-server(or ts-loader, I don`t know) not reload & transpile changed interface file.

Interface/IHelloState.ts

export interface IHelloState {
    message: string;
}

Interface.index.ts

export {IHelloState} from "./IHelloState";

index.tsx

import * as React from "react";
import * as ReactDOM from "react-dom";
import "./index.css";
import {IHelloState} from "./Interface";

const helloState: IHelloState = {
    message: "hello!"
};

ReactDOM.render(<div>{helloState.message}</div>, document.getElementById("root"));

When I change Interface/IHelloState.ts like:

Interface/IHelloState.ts

export interface IHelloState {
    // message: string;
}

Nothing happens. Not even "[HMR] Checking for updates on the server..." or "[HMR] Nothing hot updated." shows.

When I change Interface/IHelloState.ts and index.tsx like:

Interface/IHelloState.ts

export interface IHelloState {
    message: string;
    state: boolean;
}

index.tsx

import * as React from "react";
import * as ReactDOM from "react-dom";
import "./index.css";
import {IHelloState} from "./Interface";

const helloState: IHelloState = {
    message: "hello!",
    state: true
};

Now and error reports.

[tsl] ERROR in (PATH...)\index.tsx(8,5)
      TS2322: Type '{ message: string; state: boolean; }' is not assignable to type 'IHelloState'.
  Object literal may only specify known properties, and 'state' does not exist in type 'IHelloState'.

What should I change?

I run webpack-dev-server with webpack-dev-server --config webpack.dev.config.js --hot.

This is my config file.

webpack.dev.config.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");

module.exports = Object.assign(require("./webpack.base.config"), {
    entry: [
        path.join(__dirname, "src/app/index.tsx"),

        "webpack/hot/only-dev-server"
    ],

    output: {
        path: path.join(__dirname, "build/app"),
        filename: "static/js/bundle.[hash].js"
    },

    module: {
        rules: [
            {
                test: /\.jsx?$/,
                loader: "babel-loader"
            }, {
                test: /\.tsx?$/,
                loader: "ts-loader",
                options: {
                    configFile: "tsconfig.app.json"
                }
            },
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    {
                        loader: "css-loader",
                        options: {
                            modules: false
                        }
                    }
                ]
            },
            {
                exclude: [/\.tsx?/, /\.jsx?$/, /\.html$/, /\.css$/, /\.json$/],
                loader: "file-loader",
                options: {
                    name: "static/files/[hash].[ext]"
                }
            }
        ]
    },

    resolve: {
        extensions: [".ts", ".tsx", ".js", ".jsx", ".css", ".json"]
    },

    plugins: [
        new HtmlWebpackPlugin({
            template: path.join(__dirname, "src/app/index.html")
        }),

        new webpack.HotModuleReplacementPlugin()
    ],

    devServer: {
        historyApiFallback: {
            index: "/"
        }
    },

    target: "electron-renderer",

    mode: "development"
});
kuroneko0441
  • 415
  • 5
  • 14
  • But an interface change does not affect the actual code.. – Nurbol Alpysbayev Nov 15 '18 at 04:21
  • @Nurbol Alpysbayev Oh, I fixed my example. The problem is, if real object type not matches cached interface(not changed interface), type error occurs. Thank you for your mention. – kuroneko0441 Nov 15 '18 at 05:06
  • 1
    @J.Lee What change did you have to do to fix this? I am running into the same problem now. – Shawn Jan 12 '19 at 04:34
  • @Shawn I could not find any useful solution. My temporary solution is just restarting the webpack dev server. – kuroneko0441 Jan 13 '19 at 22:36
  • @J.Lee Thanks for getting back to me, I didn't have any luck using ts-loader but I switched to awesome-typescript-loader and it seems to be handling this issue now. I haven't tested it too much so I'm not 100% sure but its worth a read on that loader. – Shawn Jan 14 '19 at 16:38
  • 1
    have the same issue, any solution for this ? – que1326 Mar 12 '19 at 12:22
  • 1
    @que1326 Can you test changing `Interface` to `Class`? I didn't fully test it, but I rememeber it worked. – kuroneko0441 Mar 18 '19 at 08:55

1 Answers1

7

I encountered a similar issue. What solved it for me was to change the filenames of files that contain only interfaces from *.ts to *.d.ts.

Apparently, the ts-loader generates output only for files that give JavaScript output, and typescript definition files. The output is then read by the webpack watcher, and webpack updates if one of these files changes.

In your case, you have files that generate no JavaScript output and are not typescript definition files. So no output will be generated from them, and the webpack watcher won't notice when they change.

Sol
  • 21
  • 1
  • 5
ahuvi81
  • 86
  • 1
  • 4
  • Yeah, it was the problem. Type definitions does not change javascript output, and dev-server only reloads when javascript output changed. – kuroneko0441 Oct 26 '19 at 15:33