50

I want to enable Webpack HMR in a NodeJS project written in TypeScript.

But module.hot is not available:

  • @types/webpack-env defines:

    declare var module: __WebpackModuleApi.Module
    
  • Which conflicts with @types/node definition:

    declare var module: NodeModule
    

Removing @types/node, solves the issue, but disables process:

process.env.NODE_ENV === 'production' // [ts] Cannot find name 'process'
kube
  • 13,176
  • 9
  • 34
  • 38

6 Answers6

54

As few guys wrote here it's the best way:

npm i -D @types/webpack-env

For me it works as expected, resolving issue with not recognized hot property.

In my project I'm using those versions:

"@types/node": "^8.0.19",
"@types/webpack-env": "^1.13.0"

I don't know if question is still up to date but for my problem installing types for webpack help me.

WooCaSh
  • 5,180
  • 5
  • 36
  • 54
46

Conflict resolution

@types/webpack-env was since updated:

The code in the original question now only needs @types/webpack-env.

But importing @types/node alongside won't conflict anymore.


Installation

npm install --save-dev @types/webpack-env

And if you also need NodeJS environment definitions:

npm install --save-dev @types/node
kube
  • 13,176
  • 9
  • 34
  • 38
25

Could be as simple as adding following line at the top of the file.

///<reference types="webpack-env" />
user1595858
  • 3,700
  • 15
  • 66
  • 109
  • 3
    This works for me after installing the typings for webpack-env: npm install --save-dev @types/webpack-env – Patrik Jun 20 '17 at 06:10
  • this is very weird but worked for me in NX development https://nx.dev/ I installed first `@types/webpack-env` and later your reference line on the top of file. Thanks – Danish Jun 02 '20 at 14:18
6

You can augment the global scope and use interface merging to reopen the NodeModule interface and add the missing hot property.

import webpack = require("webpack");

declare global {
    interface NodeModule {
        hot: {
            accept(dependencies: string[], callback: (updatedDependencies: string[]) => void): void;
            accept(dependency: string, callback: () => void): void;
            accept(errHandler?: (err: any) => void): void;
            decline(dependencies: string[]): void;
            decline(dependency: string): void;
            decline(): void;

            dispose(callback: (data: any) => void): void;
            addDisposeHandler(callback: (data: any) => void): void;

            removeDisposeHandler(callback: (data: any) => void): void;
            // ...
        }
    }
}

But really, this augmentation should potentially be done in the Webpack declaration file itself.

Daniel Rosenwasser
  • 21,855
  • 13
  • 48
  • 61
  • Yes I thought there would be an official solution, with a definition available somewhere. – kube Nov 12 '16 at 22:47
  • You can absolutely send a PR and we'll accept it if the API is appropriate. I mostly wrote the answer up based on what I could find from the current documentation. Would you consider this the accepted answer otherwise? – Daniel Rosenwasser Nov 12 '16 at 23:13
  • 1
    In fact everything is well defined in `@types/webpack-env`, it was an error from my side as I added `@types/node` to be able to use modules and require and I should not have. – kube Nov 12 '16 at 23:28
  • I updated my question as I'm now facing issues with `process`. – kube Nov 12 '16 at 23:59
  • 1
    Adding `@types/webpack-env` worked out for me. I suppose We do not have the same libs imported. – Adrian Moisa Mar 12 '17 at 07:53
  • @AdrianMoisa The type definition conflict was solved at the time of your message. That's why everything worked so well. :) – kube Jan 06 '19 at 18:53
4

Change .hot by ['hot']

if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => {

Use

if (module['hot']) {
    module['hot'].accept();
    module['hot'].dispose(() => {
4

This fixes it

yarn add @types/webpack-env --dev

VScode would work immediately

Intellij would need a restart

Gal Bracha
  • 19,004
  • 11
  • 72
  • 86