4
votes

I have a webpack configuration that generates the react bundle when i call webpack directly. Since i would like to incorporate hot reloading i need to run the webpack dev server alongside my development express server (serving API endpoints) that runs on port 3000

webpack.dev.config.js

const webpack = require('webpack');
const merge = require('webpack-merge');
const Jarvis = require('webpack-jarvis');
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = merge({}, {
  mode: 'development',
  devtool: 'cheap-module-eval-source-map',
  output: {
    chunkFilename: '[name]-[hash].js',
    publicPath: "http://localhost:3000/build/",
    crossOriginLoading: 'anonymous'
  },
  optimization: {
    noEmitOnErrors: true,
    namedModules: true,
  },
  plugins: [
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    new HtmlWebpackPlugin({
      inlineSource: '.(js|css)$',
      inject: 'head',
      filename: path.join(__dirname, "/dist/index.html"),
      template: path.join(__dirname, "/public/index.html"),
      chunks: ['common', 'main']
    }),
    new Jarvis({port: 7003}),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.DefinePlugin({
      _DEVELOPMENT_: true,
    })
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: { presets: ["es2015", "react", "stage-0"] }
        }
      },
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: { presets: ["es2015", "react", "stage-0"] }
        }
      },
      {
        test: /\.scss$/,
        use: [
          "style-loader", // creates style nodes from JS strings
          "css-loader", // translates CSS into CommonJS
          "sass-loader" // compiles Sass to CSS, using Node Sass by default
        ]
      },
      {
        test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
        use: ["file-loader"]
      },
      {
        test: /\.svg$/,
        use: {
          loader: "svg-inline-loader"
        }
      },
      {
        test: /\.ts$/,
        use: [
          {
            loader: "ts-loader",
            options: {
              compilerOptions: {
                declaration: false,
                target: "es5",
                module: "commonjs"
              },
              transpileOnly: true
            }
          }
        ]
      }
    ]
  },
  resolve: {
    alias: {
      'react-dom': '@hot-loader/react-dom'
    }
  },
  entry: {
    main: [
      'babel-polyfill',
      'react-hot-loader/patch',
      'webpack/hot/only-dev-server',
      'webpack-dev-server/client?https://0.0.0.0:7001',
      './src/index.jsx',
    ],
  }
});

dev-server.js

const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const config = require('./webpack.dev.config');

new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  headers: {'Access-Control-Allow-Origin': '*'},
  hot: true,
  https: true,
  clientLogLevel: 'error',
  overlay: true,
  historyApiFallback: true,
  disableHostCheck: true,
  watchOptions: {
    ignored: /\/node_modules\/.*/,
  },
  stats: {
    assets: false,
    cached: false,
    cachedAssets: false,
    children: false,
    chunks: false,
    chunkModules: false,
    chunkOrigins: false,
    colors: true,
    depth: false,
    entrypoints: true,
    excludeAssets: /app\/assets/,
    hash: false,
    maxModules: 15,
    modules: false,
    performance: true,
    reasons: false,
    source: false,
    timings: true,
    version: false,
    warnings: true,
  },
}).listen(7001, '0.0.0.0', function(err, result) {
  console.log(`Serving chunks at path ${config.output.publicPath}`);
});

package.json scripts

 "scripts": {
    "build": "webpack --config webpack.dev.config.js --progress --profile --colors",
    "start-dev": "node dev-server.js",
    "build-prod": "webpack --config webpack.prod.js --progress --profile --colors",
    "start": "node server.js"
  },

If i run

npm run build

The result is a new js bundle and html: dist/main.js dist/index.html

however the ideal situation is to run

npm run start-dev

which will start the dev server, this outputs that is has successfully built the bundles, but they never appear in my filesystem so there must be an output config that i have not setup correctly in the dev server?

EDIT

Issue turned out to be as described by the post below. To access the live bundle reloads i edited the bundle public path from the "production server" back to just the build location, and then accessed the page from the devserver instead of the page being served by the "production server"

output: {
    chunkFilename: '[name]-[hash].js',
    publicPath: "/build/",
    crossOriginLoading: 'anonymous',
    path: path.join(__dirname, "/dist"),
  },
1

1 Answers

4
votes

Webpack dev-server don't write your changes to the disk every time you change your source code. Instead, it watches your files change, process it and serve from memory. Check out here as it explains in detail.