webpack-contrib / webpack-hot-middleware

Webpack hot reloading you can attach to your own server

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Advanced examples of properly use webpack-hot-middleware with hot reload without using webpack-dev-server allso without full page reload

CouturierDeA opened this issue · comments

Could you please provide some examples for next use "case":

The "case" is:
I do use the "server" = https://localhost:2041, provided by tomcat apache that serves java.spring app). I want to provide hot module replacement on my "server" for my js code, builded with webpack without using webpack-dev-server allso without proxying requests from webpack-dev-server to "server".

Allso it would be greath if documentation contains next descriptions about how things work without webpack dev server:

  1. what code do i need to include on my html page served from "server"?
  2. what part of that (client-side) code is responsible for hot modules replacement?
  3. what part of that (client-side) code is responsible for hot modules accepting?
  4. in what cases whm needs full page reload?
  5. in what cases whm provides hot-modules-replacement and in what cases its not?
  6. how to use hot module replacement on "server", or what part of webpack functionality can cover the "case"

I do not have any proposal for providing examples, because i do fail setting up webpack hot module replacement for the "case".

Thank you.

Ok, my problem can be solved in tho ways:

  1. By using webpack dev-server with next webpack.config

const path = require("path");
const protocol = "https";
const webpack = require("webpack");

const resolve = (dir, relativePath = '') => {
return path.join(__dirname, relativePath, dir)
};
const outputPath = resolve("my-spring-project/src/main/resources/META-INF/resources/webpack/", "../");

const nodeModulesPath = resolve("node_modules");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const VueLoaderPlugin = require("vue-loader/lib/plugin");
const WriteFilePlugin = require("write-file-webpack-plugin");

const argv = require("yargs").argv;

const mode = (argv.mode === "production")
? "production"
: "development";
const isDev = mode === "development";

const componentHotLoader = require.resolve('./loaders/component-loader');
const serviceHotLoader = require.resolve('./loaders/service-loader');
const jadeHotLoader = require.resolve('./loaders/jade-loader');

let entry = [(argv.entry || './src/index')];
var htmlLoaders = ['html-loader'];

if (mode === 'development') {
htmlLoaders = [jadeHotLoader, 'html-loader'];
entry = [
webpack-dev-server/client?https://localhost:8080,
webpack/hot/only-dev-server?client?https://localhost:8080,
webpack/hot/dev-server?client?https://localhost:8080
].concat(entry);
}

const optimization = {
minimize: false,
// runtimeChunk: 'multiple', // multiple, single
splitChunks: {
chunks: 'initial', // initial async all
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendors: false,
ngComponents: {
test: /[\/]angular-components[\/]/,
name(module) {
const packageName = module.context.match(/[\/]angular-components\/([\/]|$)/)[1];
return ${packageName.replace('@', '')};
},
},
},
}
};

module.exports = {
// devtool: 'eval',
mode, entry, optimization,
output: {
path: outputPath,
filename: webpack-main.js,
chunkFilename: '[name]/[name].js',
publicPath: isDev ? ${protocol}://localhost:8080/ : './webpack/',
},
resolve: {
extensions: ['.js', '.vue', '.json', '.scss', '.sass'],
alias: {
'vue$': 'vue/dist/vue.common.js',
'src': resolve('src'),
'@': resolve('src'),
'~assets': resolve('src/assets'),
'views': resolve('src/views'),
'assets': resolve('src/assets'),
'vue-components': resolve('src/vue-components'),
'ng-components': resolve('src/angular-components'),
'root': nodeModulesPath,
}
},
plugins: [
new CleanWebpackPlugin(),
new VueLoaderPlugin(),
new WriteFilePlugin(), // Using for output dev build files into my-spring-project/src/main/resources/META-INF/resources/webpack/ folder in dev mode
new webpack.HotModuleReplacementPlugin(),
new webpack.HashedModuleIdsPlugin(),
new webpack.DefinePlugin({
IS_DEV: JSON.stringify(isDev)
})
],
module: {
rules: [
{
test: /.component.js$/,
loader: isDev ? [componentHotLoader, 'babel-loader'] : 'babel-loader',
exclude: [/client/lib/, /node_modules/, /.spec.js/]
},
{
test: /.service.js$/,
loader: isDev ? [serviceHotLoader, 'babel-loader'] : 'babel-loader',
exclude: [/client/lib/, /node_modules/, /.spec.js/]
},
{
test: /.html$/,
loader: htmlLoaders,
include: [resolve('src'), resolve('test')]
},
{
test: /.vue$/,
loader: 'vue-loader',
options: {
loaders: {
js: 'babel-loader!eslint-loader'
}
},
},
{
test: /.js$/,
loader: 'babel-loader',

            include: [
                resolve('src'),
                resolve('node_modules/webpack-dev-server/client'),
            ],
        },
        {
            test: /\.css$/,
            use: [
                {
                    loader: 'vue-style-loader'
                },
                {
                    loader: 'css-loader',
                    options: {
                        modules: false,
                        localIdentName: '[local]_[hash:base64:8]'
                    }
                }
            ]
        },
        {
            test: /\.scss$/,
            use: [
                'vue-style-loader',
                'css-loader',
                'sass-loader'
            ]
        },
        {
            test: /\.sass$/,
            use: [
                'vue-style-loader',
                'css-loader',
                'sass-loader'
            ]
        },
    ],
},

};',

and a server.js configuration

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');

var config = require('./webpack.config.js');

let port = 8080;
let protocol = 'https';
let hostname = 'localhost';

const compiler = webpack(config);
let path = require('path');

new WebpackDevServer(compiler, {
host: hostname,
// port: port,
// compress: true,
open: false,
watchOptions: {
ignored: /node_modules/,
poll: true,
},
watchContentBase: true,
contentBase:path.join(__dirname, 'src'),
publicPath: '/',
https: protocol === 'https',
historyApiFallback: true,
hot: true,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
},

}).listen(port, hostname, function (err, result) {
if (err) {
// console.log(err);
}

console.log(`Listening at ${protocol}://${hostname}:${port}`);

});

Run commands (package.json).scripts {
"dev": "node server.js --mode development",
"build": "webpack --mode production"
}
yarn dev for development
yarn build for development

in my main.jsp file that served from "server" (https://localhost:2041/):
add angular 1.6 component scripts

<script type="text/javascript" src="${pageContext.request.contextPath}/webpack/webpack-main.js?v${version}"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/webpack/counter/counter.js?v${version}"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/webpack/emoji/emoji.js?v${version}"></script>

webpack-main contains contains code, that responsible for module registration, invocation, allso hot reloading (for development mode) and accepting the ws signal from webpack dev server, that contains the hash of hot-update.json file that creates when you actually change the source code of component (for example), and then webpack-main.js code send request to the webpack-dev-server (https://localhost:8080/) to retrieve hot-update.json and hot swap updated code.

  1. By adding <script type="text/javascript" src="https://localhost:8080/bundle.js"></script>
    to my main.jsp file and allso change configuration of webpack.config.output to

output: {
path: outputPath,
filename: bundle.js,
// chunkFilename: '[name]/[name].js',
publicPath: ${protocol}://localhost:8080/,
},

I think a better way to support old angular@1.6 (or vue.js, react or whatewer) and java spring mvc projects (without total project js-code refactor with webpack) probably exist.