Open ckken opened 4 years ago
Hi, can you please state the version of:
Providing me just the error stack trace is not helpful to say the least, because there is not much stuff for me to trace.
webpack: 5 beta 18 plugin version: "@pmmmwh/react-refresh-webpack-plugin": "^0.4.0-beta.5", "react-refresh": "^0.8.3",
update =>"@pmmmwh/react-refresh-webpack-plugin": "^0.4.0-beta.6" use module federation
Did you include the webpack.HotModuleReplacementPlugin
in your Webpack configuration? If not, this plugin won't work.
With webpack-dev-server
you can use either of the hot
/hotOnly
options, and with other development means you'll have to include it manually.
I've tested with module federation (with Webpack master, cause there' some bugs with module cache in beta.18) and everything works fine.
Did you include the
webpack.HotModuleReplacementPlugin
in your Webpack configuration? If not, this plugin won't work.With
webpack-dev-server
you can use either of thehot
/hotOnly
options, and with other development means you'll have to include it manually.I've tested with module federation (with Webpack master, cause there' some bugs with module cache in beta.18) and everything works fine.
nice
no work for me!
devServer
module.exports = {
devServer: {
host: 'localhost',
port: 8000,
disableHostCheck: true,
historyApiFallback: true,
hot: true,
stats: {
colors: true,
},
},
}
// module
scripts: {
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: {
babel: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react'],
plugins: [
//
['import', {libraryName: 'antd', style: true}],
isDev && require.resolve('react-refresh/babel'),
//
],
},
},
},
},
// plugin
if (isDev) {
conf.plugin.reacthotloader = {
plugin: ReactRefreshWebpackPlugin,
args: [{}],
}
}
when remove exposes it work!
when remove exposes it work!
The issues you're facing is due to a bug in webpack@5.0.0-beta.18. if you use webpack master, these issues goes away. If they don't, or if you have any further questions, it is most likely not due to this plugin - we plug into Webpack's HMR runtime and if the HMR runtime errors out for module federation we can do nothing.
Side note: I would suggest adding react-refresh/runtime
to shared singleton - you can also pin the version.
no work also!
go to beta 20
go to beta 20
There are the same problems
@ScriptedAlchemy it seems that on full refresh HMR will throw (but it actually does not affect modules updating ...)
I've tested with basic-host-remote
with the following changes:
package.json
for both app1
and app2
:
"@babel/preset-react": "7.10.1",
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.4.0-beta.6",
"babel-loader": "8.1.0",
"bundle-loader": "0.5.6",
"html-webpack-plugin": "git://github.com/ScriptedAlchemy/html-webpack-plugin#master",
+ "react-refresh": "^0.8.3",
"serve": "11.3.2",
webpack.config.json
for both app1
and app2
:
+ const ReactRefreshPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { ModuleFederationPlugin } = require("webpack").container;
const path = require("path");
module.exports = {
entry: "./src/index",
mode: "development",
devServer: {
contentBase: path.join(__dirname, "dist"),
+ hot: true,
port: 3001,
},
// ...
module: {
+ // Quite a bit of change in this block
rules: [
{
test: /bootstrap\.js$/,
use: [
{
loader: "bundle-loader",
options: {
lazy: true,
},
},
{
loader: 'babel-loader',
options: {
presets: ["@babel/preset-react"],
}
},
],
},
{
test: /\.jsx?$/,
loader: "babel-loader",
exclude: [/node_modules/, /bootstrap\.js$/],
options: {
+ plugins: ['react-refresh/babel'],
presets: ["@babel/preset-react"],
},
},
],
},
plugins: [
new ModuleFederationPlugin({
// app specific
shared: ["react", "react-dom"],
}),
new HtmlWebpackPlugin({
template: "./public/index.html",
}),
+ new ReactRefreshPlugin({
+ exclude: [/node_modules/, /bootstrap\.js$/],
+ }),
],
};
webpack config for development
{
mode: 'development',
devtool: 'inline-source-map',
output: {
path: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/projects/antd-base/dist',
filename: 'js/[name].[contenthash:8].js',
publicPath: 'http://localhost:8003/'
},
resolve: {
alias: {
src: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/projects/antd-base/src'
},
extensions: [
'.js',
'.jsx',
'.ts',
'.tsx',
'.css',
'.less',
'.scss',
'.sass',
'.json'
],
modules: [
'node_modules',
'/Users/ken/Desktop/develop/MicroFE/emp-workspace/projects/antd-base/node_modules',
'/Users/ken/Desktop/develop/MicroFE/emp-workspace/projects/antd-base/src'
]
},
devServer: {
host: 'localhost',
port: 8003,
disableHostCheck: true,
historyApiFallback: true,
open: false,
hot: true,
stats: {
colors: true
}
},
module: {
rules: [
/* config.module.rule('css') */
{
test: /\.css$/,
exclude: [
/\.module\.css$/
],
use: [
/* config.module.rule('css').use('style') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/style-loader/dist/cjs.js'
},
/* config.module.rule('css').use('css') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/css-loader/dist/cjs.js'
}
]
},
/* config.module.rule('cssModule') */
{
test: /\.module\.css$/,
exclude: [
/\.css$/
],
use: [
/* config.module.rule('cssModule').use('style') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/style-loader/dist/cjs.js'
},
/* config.module.rule('cssModule').use('css') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/css-loader/dist/cjs.js',
options: {
modules: true
}
}
]
},
/* config.module.rule('sassModule') */
{
test: /\.module\.(scss|sass)$/,
exclude: [
/\.(scss|sass)$/
],
use: [
/* config.module.rule('sassModule').use('style') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/style-loader/dist/cjs.js'
},
/* config.module.rule('sassModule').use('css') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/css-loader/dist/cjs.js',
options: {
modules: true
}
},
/* config.module.rule('sassModule').use('sass') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/sass-loader/dist/cjs.js',
options: {
implementation: {
render: function () {
return _call(f, Array.prototype.slice.apply(arguments));
},
renderSync: function () {
return _call(f, Array.prototype.slice.apply(arguments));
},
info: 'dart-sass\t1.26.7\t(Sass Compiler)\t[Dart]\ndart2js\t2.8.2\t(Dart Compiler)\t[Dart]',
types: {
Boolean: function () {
return _call(f, Array.prototype.slice.apply(arguments));
},
Color: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
List: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
Map: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
Null: function () {
return _call(f, Array.prototype.slice.apply(arguments));
},
Number: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
String: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
Error: function Error() { [native code] }
},
NULL: {
toString: function () {
return _call(f, Array.prototype.slice.apply(arguments));
}
},
TRUE: {
value: true
},
FALSE: {
value: false
},
cli_pkg_main_0_: function () {
return _call(f, Array.prototype.slice.apply(arguments));
}
},
sourceMap: true
}
}
]
},
/* config.module.rule('sass') */
{
test: /\.(scss|sass)$/,
exclude: [
/\.module\.(scss|sass)$/
],
use: [
/* config.module.rule('sass').use('style') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/style-loader/dist/cjs.js'
},
/* config.module.rule('sass').use('css') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/css-loader/dist/cjs.js'
},
/* config.module.rule('sass').use('sass') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/sass-loader/dist/cjs.js',
options: {
implementation: {
render: function () {
return _call(f, Array.prototype.slice.apply(arguments));
},
renderSync: function () {
return _call(f, Array.prototype.slice.apply(arguments));
},
info: 'dart-sass\t1.26.7\t(Sass Compiler)\t[Dart]\ndart2js\t2.8.2\t(Dart Compiler)\t[Dart]',
types: {
Boolean: function () {
return _call(f, Array.prototype.slice.apply(arguments));
},
Color: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
List: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
Map: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
Null: function () {
return _call(f, Array.prototype.slice.apply(arguments));
},
Number: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
String: function () {
return _call(f, this, Array.prototype.slice.apply(arguments));
},
Error: function Error() { [native code] }
},
NULL: {
toString: function () {
return _call(f, Array.prototype.slice.apply(arguments));
}
},
TRUE: {
value: true
},
FALSE: {
value: false
},
cli_pkg_main_0_: function () {
return _call(f, Array.prototype.slice.apply(arguments));
}
},
sourceMap: true
}
}
]
},
/* config.module.rule('less') */
{
test: /\.less$/,
exclude: [
/\.module\.less$/
],
use: [
/* config.module.rule('less').use('style') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/style-loader/dist/cjs.js'
},
/* config.module.rule('less').use('css') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/css-loader/dist/cjs.js'
},
/* config.module.rule('less').use('sass') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/less-loader/dist/cjs.js',
options: {
lessOptions: {
javascriptEnabled: true
}
}
}
]
},
/* config.module.rule('lessModule') */
{
test: /\.module\.less$/,
exclude: [
/\.less$/
],
use: [
/* config.module.rule('lessModule').use('style') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/style-loader/dist/cjs.js'
},
/* config.module.rule('lessModule').use('css') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/css-loader/dist/cjs.js',
options: {
modules: true
}
},
/* config.module.rule('lessModule').use('sass') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/less-loader/dist/cjs.js',
options: {
lessOptions: {
javascriptEnabled: true
}
}
}
]
},
/* config.module.rule('image') */
{
test: /\.(png|jpe?g|gif|svg)$/i,
use: [
/* config.module.rule('image').use('file') */
{
loader: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/file-loader/dist/cjs.js'
}
]
},
/* config.module.rule('scripts') */
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: [
/node_modules/
],
use: [
/* config.module.rule('scripts').use('babel') */
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-typescript',
'@babel/preset-react'
],
plugins: [
[
'import',
{
libraryName: 'antd',
style: true
}
],
'/Users/ken/Desktop/develop/MicroFE/emp-workspace/node_modules/react-refresh/babel.js'
]
}
}
]
}
]
},
optimization: {
chunkIds: 'named',
usedExports: true
},
plugins: [
/* config.plugin('env') */
new EnvironmentPlugin(
{
MODE_ENV: 'development',
EMP_ENV: 'dev'
}
),
/* config.plugin('clean') */
new CleanWebpackPlugin(ndefine),
/* config.plugin('html') */
new HtmlWebpackPlugin(
{
title: 'EMP BASE',
template: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/packages/emp-cli/template/public/index.html',
favicon: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/packages/emp-cli/template/public/favicon.ico',
files: {},
minify: false
}
),
/* config.plugin('progress') */
new ProgressPlugin(
{
handler: function () { /* omitted long function */ }
}
),
/* config.plugin('mf') */
new ModuleFederationPlugin(
{
name: 'empBase',
library: {
type: 'var',
name: 'empBase'
},
filename: 'emp.js',
remotes: {},
exposes: {
'./App': 'src/App',
'./stores/index': 'src/stores/index',
'./components/common/crud/index': 'src/components/common/crud/index',
'./components/common/RouterComp': 'src/components/common/RouterComp'
},
shared: {
react: {
eager: true,
singleton: true,
requiredVersion: '^16.13.1'
},
'react-dom': {
eager: true,
singleton: true,
requiredVersion: '^16.13.1'
},
'react-router-dom': {
requiredVersion: '^5.1.2'
},
'mobx-react-lite': {
requiredVersion: '^1.5.2'
},
mobx: {
requiredVersion: '^5.15.4'
},
axios: {
requiredVersion: '^0.19.2'
}
}
}
),
/* config.plugin('ts') */
new ForkTsCheckerWebpackPlugin(
{
tsconfig: '/Users/ken/Desktop/develop/MicroFE/emp-workspace/projects/antd-base/tsconfig.json'
}
),
/* config.plugin('reacthotloader') */
new ReactRefreshPlugin(
{}
)
],
entry: {
index: [
'/Users/ken/Desktop/develop/MicroFE/emp-workspace/projects/antd-base/src/index.ts'
]
}
}
"@pmmmwh/react-refresh-webpack-plugin": "https://github.com/pmmmwh/react-refresh-webpack-plugin#main",
it no work for me https://github.com/module-federation/module-federation-examples/issues/138#issuecomment-654614565
I won't have time to test module federation this week most likely, but from what I see in the screenshot it is some sort of error within Webpack's JSONP HMR runtime - which is way out of scope of this plugin.
@ckken I would suggest you redirect your troubleshooting to webpack/webpack#10352 (I will join the discussion if I see anything related), with a minimal reproducible example (like how I did upstairs, strip away all unrelated stuff e.g. CSS and focus on MF) so that Tobias/Zack can have a failing baseline to build on (think of TDD - the example acts as a test where we implement code to make it pass). While screenshots shows traces of where the error originates without the whole picture it is difficult for anyone to track down issues, especially when it is tech like this that orchestrates stuff.
(Also - I'm not an expert on Webpack 5, so maybe the current implementation for Webpack 5 is somewhat flawed for an app running with MF, but so far I haven't seen any ...)
mark
From #195, reported by @shaodahong
Report: shaodahong/module-federation-react-refresh-demo
if change some text trigger refresh, console log some error
@pmmmwh @ScriptedAlchemy
Now webpack-dev-server
release v4.0.0-beta.0, it's resolved multiple entrypoint hot refresh, and if still has an error, can report to webpack-dev-server
git clone https://github.com/efoxTeam/emp
lerna bootstrap
cd projects && yarn dev:hot
https://github.com/efoxTeam/emp/blob/main/projects/demo1/src/bootstrap.tsx
& throw errorFixed cross domain issues, but page changed from hot to refresh
I found that there would be problems when project a was import into project B
like hot replace
and liveReload
both active, liveReload
it's fallback
liveReload
is disabled
I found possible problems
@pmmmwh not sure if this is related, but as @shaodahong mentioned webpack-dev-server
just released v4.0.0-beta.0; and as I just tried it out, I found that fast-refresh
no-longer works.
I have a reproducible repo, please take a look at this PR. After upgrading to webpack-dev-server@4.0.0-beta.0
. If you run the app using yarn start
and try to hit the +
button a few time to increase the age, then you try to make some trivial change in App.tsx
the page is reloaded, and the age is reset to 10
.
@pmmmwh if you would like me to file a separate issue, please let me know.
@pmmmwh not sure if this is related, but as @shaodahong mentioned
webpack-dev-server
just released v4.0.0-beta.0; and as I just tried it out, I found thatfast-refresh
no-longer works.I have a reproducible repo, please take a look at this PR. After upgrading to
webpack-dev-server@4.0.0-beta.0
. If you run the app usingyarn start
and try to hit the+
button a few time to increase the age, then you try to make some trivial change inApp.tsx
the page is reloaded, and the age is reset to10
.@pmmmwh if you would like me to file a separate issue, please let me know.
@akphi can you set webpack-dev-server
liveReload: false
?
@shaodahong Yes, that seems to work just fine. Thank you! @pmmmwh should we consider this just as a workaround for now, or this can be the documented solution?
looks like rather a matter of disabling liveReload
explicitly, it could be due to some change to the default value set for watchContentBase
in their v4.beta
, I did a bit of digging and filed an issue https://github.com/webpack/webpack-dev-server/issues/2893
@akphi yep, but this PR talk about use ModuleFederationPlugin
, crash when multiple entrypoint
it work for esbuild https://github.com/efoxTeam/emp/tree/main/projects/esbuild-react-demo
it work for swc https://github.com/efoxTeam/emp/tree/main/projects/swc-react-demo too
I'm not sure what we're looking for here now - it seems to me most of the errors tracked within this thread is not our issue but rather from upstream (webpack-dev-server
)? I'm not sure what you mean by working for esbuild
or swc
to be honest.
(node:50522) UnhandledPromiseRejectionWarning: Error: Cannot find module 'webpack/lib/ParserHelpers' Require stack: