webpack-contrib / webpack-hot-middleware

Webpack hot reloading you can attach to your own server
MIT License
2.34k stars 296 forks source link

After get a success message "[HMR] App is up to date." the result is not showing in the browser. #351

Open navichawla92 opened 5 years ago

navichawla92 commented 5 years ago

"use strict"; require("dotenv").config(); var webpack = require("webpack"); var path = require("path"); var ProgressBarPlugin = require("progress-bar-webpack-plugin");

    var API_ROOT = process.env.API_ROOT || 
         "http://localhost:8080/api/";
    var ASSETS_HOST = "http://127.0.0.1:8080";
    var RECAPTCHA_SITE_KEY = process.env.RECAPTCHA_SITE_KEY;
    var theme = {
    "primary-color": "#75BF43",
    "font-size-base": "13px"
    };

    var nodeModulesDir = path.resolve(__dirname, "node_modules");
    var srcDir = path.resolve(__dirname, "src");

    process.traceDeprecation = true;

    module.exports = {
    cache: true,
    devtool: "eval-source-map",

    mode: "development",

    entry: {
    app: ["webpack-hot-middleware/client", "./src/app"]
    },
    output: {
    path: path.join(__dirname, "dist"),
    publicPath: "/",
    filename: "js/[name].bundle.js"
    },
    resolve: {
    modules: [
    path.resolve(__dirname, "node_modules"),
    ],
    extensions: [".html", ".js", ".jsx", ".json", ".css", ".sass", ".scss", 
    ".less", ".jpeg", ".png", ".gif", ".jpg"]
    },

    plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new ProgressBarPlugin(),
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
    new webpack.DefinePlugin({
    API_ROOT: JSON.stringify(API_ROOT),
    ASSETS_HOST: JSON.stringify(ASSETS_HOST),
    RECAPTCHA_SITE_KEY: JSON.stringify(RECAPTCHA_SITE_KEY),
    process: {
    env: {
    NODE_ENV: JSON.stringify(process.env.NODE_ENV)
    }
    }
    }),
    ],

    stats: {
    colors: true
    },

    module: {
    rules: [
    {
    test: /\.(jsx|js)?$/,
    enforce: "pre",
    exclude: [nodeModulesDir],
    loader: "eslint-loader"
    },

    {
    test: /\.js$/,
    loader: "babel-loader",
    exclude: [nodeModulesDir],
    options: {
    cacheDirectory: true,
    plugins: [
    "transform-decorators-legacy",
    "add-module-exports",
    "lodash",
    ["import", { libraryName: "antd", style: true }]
    ],
    presets: ["es2015", "stage-0", "react"]
    }
    },
    {
    test: /\.scss$/,
    use: [
    {
    loader: "style-loader"
    },
    {
    loader: "css-loader",
    options: {
    sourceMap: true,
    modules: true,
    localIdentName: "[name]__[local]___[hash:base64:5]"
    }
    },
    {
    loader: "sass-loader",
    options: {
    sourceMap: true
    }
    }
    ],
    include: [srcDir]
    },
    {
    test: /\.scss$/,
    use: [
    {
    loader: "style-loader"
    },
    {
    loader: "css-loader",
    options: {
    sourceMap: true
    }
    },
    {
    loader: "sass-loader",
    options: {
    sourceMap: true
    }
    }
    ],
    exclude: [srcDir]
    },
    {
    test: /(?!module)\.less$/,
    use: [
    {
    loader: "style-loader"
    },
    {
    loader: "css-loader",
    options: {
    sourceMap: true
    }
    },
    {
    loader: "less-loader",
    options: {
    sourceMap: true,
    modifyVars: theme
    }
    }
    ]
    },
    {
    test: /\.module\.less$/,
    use: [
    {
    loader: "style-loader"
    },
    {
    loader: "css-loader",
    options: {
    sourceMap: true,
    modules: true,
    localIdentName: "[local]___[hash:base64:5]"
    }
    },
    {
    loader: "less-loader",
    options: {
    sourceMap: true,
    modifyVars: theme
    }
    }
    ]
    },
    {
    test: /\.css$/,
    use: ["style-loader", "css-loader"]
    },
    {
    test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
    loader: "url-loader",
    options: {
    limit: 10000,
    mimetype: "application/font-woff"
    }
    },
    {
    test: /\.(png|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
    loader: "file-loader"
    }
    ],

    noParse: [/jszip.js$/]
    },

    node: {
    Buffer: false
    }
    };

Server.js

const send = require("koa-send"); const Router = require("koa-router"); const serve = require("koa-static"); const bodyParser = require("koa-bodyparser"); const logger = require("koa-logger"); const Koa = require("koa"); const webpack = require("webpack"); const devMiddleware = require("webpack-dev-middleware"); const hotMiddleware = require("webpack-hot-middleware"); const devConfig = require("./webpack.config"); const koa2Connect = require("koa2-connect"); const helmet = require("koa-helmet"); const RateLimit = require("koa2-ratelimit").RateLimit; const { API } = require("mobx-model"); const { dreamfactoryMiddleware } = require("./server/dreamfactory/middleware"); const { notify } = require("./server/recaptcha"); const { exportExcel, exportCsv } = require("./server/export"); const { importExcel, importCsv } = require("./server/import"); const { generateUrl, generateUrlNoAuth, verifyOtp, verifyOtpNoAuth, login, confirm } = require("./server/otp");

    const app = new Koa();

    API.config({
      urlRoot: process.env.API_ROOT,
      requestHeaders: {
        "Content-Type": "application/json; charset=utf-8"
      }
    });

    const compile = webpack(devConfig);
    const opts = {
      publicPath: "/",
      stats: {
        colors: true
      },
      aggregateTimeout: 300,
      poll: true
    };

    const loginLimit = RateLimit.middleware({
      interval: { sec: 10 },
      max: 20,
      onLimitReached: notify,
      prefixKey: "post/api/otp/login",
      message: "Too many login attempts. Please try again after 5 minutes."
    });

    const passwordLimit = RateLimit.middleware({
      interval: { sec: 15 },
      max: 20,
      onLimitReached: notify,
      prefixKey: "post/api/user/password",
      message: "Too many password reset attempts. Please try again after 15 minutes."
    });

    const expressDevMiddleware = devMiddleware(compile, opts);
    const expressHotMiddleware = hotMiddleware(compile);

    app.use(logger());
    app.use(helmet());
    app.use(bodyParser({ jsonLimit: "10mb" }));

    const router = new Router();

    app.use(router.routes());
    app.use(router.allowedMethods());

    app.use(koa2Connect(expressDevMiddleware));
    app.use(koa2Connect(expressHotMiddleware));
    app.use(dreamfactoryMiddleware);
    app.use(serve(__dirname + "/static"));

    app.use(async ctx => {
      await send(ctx, "index.html", { root: __dirname + "/static" });
    });

    app.listen(8080);
lampshaj commented 5 years ago

I just started getting the same thing on my project. I check my commits and files and it appears nothing has changed. I've even pulled an old version of my project that I know was working, and it is now showing this error.

xveganxxxedgex commented 5 years ago

I'm running into this issue as well after attempting to update from version 2.22.2. I make a change, the page refreshes and shows the success message in the console, but the actual changes in the app are not applied, so I have to force a full refresh to get them.

xveganxxxedgex commented 5 years ago

For what it's worth, this seems to be related to Babel 7 upgrades at least in my case. I haven't been able to narrow down what exactly it's having issues with, but it didn't start happening until after I made the change from v6 to v7.

This is my babel config:

{
    "plugins": [
      "styled-components",
      "@babel/plugin-proposal-class-properties",
      "@babel/plugin-transform-modules-commonjs"
    ],
    "presets": [
      [
        "@babel/preset-env",
        {
          "modules": false
        }
      ],
      "@babel/preset-react"
    ],
    "env": {
      "production": {
        "only": [
          "app",
        ],
        "plugins": [
          "transform-react-remove-prop-types",
          "@babel/plugin-transform-react-inline-elements",
          "@babel/plugin-transform-react-constant-elements"
        ]
      },
      "test": {
        "plugins": [
          "@babel/plugin-transform-modules-commonjs",
          "dynamic-import-node"
        ]
      }
    }
  }

In my app entry file, I have the babel-polyfill replacement as they suggest:

import 'core-js/stable';
import 'regenerator-runtime/runtime';

Has anyone gotten hot reloading to work properly with babel 7? Is there something special I'm missing that I need to add?

xveganxxxedgex commented 5 years ago

For anyone else hitting this issue, this solution below worked in our case. We had to change the module.hot.accept logic to reimport the top level app component and rerender it.

app.js

import App from 'containers/App';

...

const render = (messages, AppComponent = App) => {
  ReactDOM.render(
    <Provider store={store}>
      <LanguageProvider messages={messages}>
        <ConnectedRouter history={history}>
          <AppComponent />
        </ConnectedRouter>
      </LanguageProvider>
    </Provider>,
    MOUNT_NODE,
  );
};

...

if (module.hot) {
  // Hot reloadable React components and translation json files
  // modules.hot.accept does not accept dynamic dependencies,
  // have to be constants at compile-time
  module.hot.accept(['./i18n', 'containers/App'], () => {
    import('containers/App').then(({ default: NewApp }) => {
      render(translationMessages, NewApp);
    });
  });
}