insin / nwb

A toolkit for React, Preact, Inferno & vanilla JS apps, React libraries and other npm modules for the web, with no configuration (until you need it)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Move to typescript breaks hot-reload.

sergiop opened this issue · comments

This issue is a Support request

Hi I moved my nwb based project to Typescript. Everything fine except for the automatic reload of the browser on save.

I created the following webpack custom config in nwb.config.js and I added the following dependencies.

What I'am missing?

yarn add @types/react @types/react-dom awesome-typescript-loader typescript -D
  webpack: {
    config(config) {
      config.entry = {
        demo: ['./demo/src/index.tsx'],
      }
      config.resolve.extensions = []
      config.resolve.extensions.push('.ts', '.tsx', '.jsx', '.js')
      config.devtool = 'source-map'
      config.module.rules.push({
        test: /\.tsx?$/,
        loaders: ['awesome-typescript-loader'],
      })

      return config
    },
  },

I'm having the same issue and I tried:

module.exports = {
    webpack: {
        config(config) {
           config.entry = {
                demo: ["./demo/src/index.tsx"]
            };
            config.resolve.extensions = config.resolve.extensions || [
                '.js',
                '.jsx',
            ];
            config.resolve.extensions.push('.ts', '.tsx');
            config.module.rules.push({
                test: /\.tsx?$/,
                loader: 'ts-loader',
            });

            return config;
        },
    },
    devServer: {
        hotOnly: true,
        inline: true,
        hot: true
    }
};

I also ran into this issue and it seems that it's the entrypoint configuration that breaks the hot reloading

config.entry = { demo: ["./demo/src/index.tsx"] };

Remove the above and you will re-enable it. However, the webpack compilation will fail since it the default entrypoint will be missing. Adding index.js to the src folder will solve this seemingly, hot reloading will start as per usual but will throw a warning whenever you modify index.js and will ignore any changes to any other .tsx file in your project.

I created a simple webpack.config.js in a nwb created react-app, using nwb dependencies from 0.23.0 only adding webpack-cli version 3.2.1 (any later version will not allow webpack to finish compiling my project) and that will enable Typescript support with hot reloading and a custom entrypoint.

In conclusion, it seems that it's not the addition of ts-loader or awesome-typescript-loader that breaks hot reloading, it's defining the entrypoint in the webpack section. It does not matter if you use the escape hatch (extra) or provide your own config(config).

for me, as a workaround (I prefer to build components together with the main project, not when publishing) keeping tsc --watch alongside nwb and using .js as entry point works fine (including HMR)

@sergiop When i build the project for the UMD, it works fine. But when i try to use that UMD build, the global variable is set to undefined.

It sets correctly without typescript configurations.

For TS, my module had only named exports, so I added the default for all the named exports, which worked with the UMD build

// Required for drop a tag configuration
export default {
    CAMERA_FOCUS_DURATION,
    CAMERA_PITCH,
    CAMERA_RESET_DURATION,
    CAMERA_ZOOM_DURATION,
    MAP_CONTAINER_CLASS,
    ROW_ZOOM_OFFSET,
    SEATING_ID_PATTERN,
    VenueMapComponent,
    VenueMapErrorEvent,
    VenueMapEvent,
    VenueMapFocusOptions,
    VenueMapInputEvent,
    VenueMapOptions,
    VenueMapRowInputEvent,
    VenueMapSectionInputEvent
};

My config reads as:

const path = require('path');

module.exports = {
    type: 'web-module',
    npm: {
        esModules: false,
        umd: {
            externals: {},
            global: 'VenueMap'
        }
    },
    karma: {
        // omitted 
    },
    webpack: {
        config(originalConfig) {
            const isDev = process.env.NWB_MODE === 'development';
            process.env.NODE_ENV = isDev ? 'development' : 'production';
            const config = {
                ...originalConfig
            };

            config.mode = isDev ? 'development' : 'production';
            // I need to create CSS and JS modules
            config.entry = ['./src/VenueMap.css', './src/VenueMap.ts'];
            config.optimization = {
                noEmitOnErrors: false
            };

            // Change output name
            config.output = {
                ...config.output,
                filename: 'VenueMap.js',
                library: 'VenueMap'
            };

            //  Include TS support
            config.resolve.extensions = config.resolve.extensions || ['.js'];
            config.resolve.extensions.push('.ts');
            config.resolve.alias = config.resolve.alias || {};
            config.resolve.alias['~'] = path.resolve('./node_modules');

            config.module.rules.push({
                loader: 'ts-loader',
                options: { allowTsInNodeModules: true },
                test: /\.ts$/
            });

            // Format with prettier
            config.module.rules.push({
                enforce: 'pre',
                exclude: /node_modules/,
                loader: 'eslint-loader',
                test: /\.(js|ts)$/,
                options: {
                    fix: true
                }
            });

            config.devtool = 'source-map';
            return config;
        }
    }
};

And run it like nwb build-web-module --copy-files