Skip to content

Module Federation with Webpacker/Rails host resulting in ScriptLoadError #1116

Closed
@olivierlacan

Description

@olivierlacan

We've been successfully testing Module Federation with apps that use React and Webpack directly but recently ran into the need to integrate an app that uses Webpack through Webpacker and for some reason we're running into ScriptLoadError issues anytime we try to load the remote-entry that comes from the Rails/Webpacker side.

On the Rails/Webpacker remote the remote-entry.js returns 200 but the issue appears to occur at evaluation time:

image

We've also noticed that the remote-entry.js output from Webpacker/Rails-side is significantly smaller (in code) than the one we get from our

The Rails Webpacker remote side is using Webpack 5.51.1.
Our host is using Webpack 5.50.0.

Remote Webpack/Rails app

Compile Webpack config output

{
  mode: 'development',
  output: {
    filename: 'js/[name].js',
    chunkFilename: 'js/[name].chunk.js',
    hotUpdateChunkFilename: 'js/[id].[fullhash].hot-update.js',
    path: '<removed>/webpacker-module-federation/public/packs',
    publicPath: '/packs/'
  },
  entry: {
    application: '<removed>/webpacker-module-federation/app/javascript/packs/application.js',
    hello_react: '<removed>/webpacker-module-federation/app/javascript/packs/hello_react.jsx'
  },
  resolve: {
    extensions: [ '.js', '.jsx', '.mjs', '.ts', '.tsx', '.coffee' ],
    modules: [
      '<removed>/webpacker-module-federation/app/javascript',
      'node_modules'
    ],
    plugins: [ [Object] ]
  },
  plugins: [
    EnvironmentPlugin { keys: [Array], defaultValues: [Object] },
    WebpackAssetsManifest {
      hooks: [Object],
      options: [Object],
      assets: [Object: null prototype] {},
      assetNames: Map(0) {},
      currentAsset: null,
      compiler: null,
      [Symbol(isMerging)]: false
    },
    ModuleFederationPlugin { _options: [Object] }
  ],
  resolveLoader: { modules: [ 'node_modules' ], plugins: [ [Object] ] },
  optimization: { splitChunks: { chunks: 'all' }, runtimeChunk: 'single' },
  module: {
    strictExportPresence: true,
    rules: [ [Object], [Object], [Object] ]
  },
  devtool: 'cheap-module-source-map',
  stats: {
    colors: true,
    entrypoints: false,
    errorDetails: true,
    modules: false,
    moduleTrace: false
  },
  devServer: {
    devMiddleware: { publicPath: '/packs/' },
    compress: true,
    allowedHosts: 'all',
    host: 'localhost',
    port: 3035,
    https: false,
    hot: false,
    liveReload: true,
    historyApiFallback: { disableDotRule: true },
    headers: { 'Access-Control-Allow-Origin': '*' },
    static: {
      publicPath: '<removed>/webpacker-module-federation/public/packs',
      watch: [Object]
    },
    client: { overlay: true }
  }
}

Here's the generated remote-entry.js from that same remote:

"use strict";
var demo;
(self["webpackChunkwebpacker_module_federation"] = self["webpackChunkwebpacker_module_federation"] || []).push([["demo"],{

/***/ "webpack/container/entry/demo":
/*!***********************!*\
  !*** container entry ***!
  \***********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {

var moduleMap = {
	"./app": function() {
		return Promise.all([__webpack_require__.e("vendors-node_modules_prop-types_index_js"), __webpack_require__.e("webpack_sharing_consume_default_react-dom_react-dom-webpack_sharing_consume_default_react_react"), __webpack_require__.e("app_javascript_packs_hello_react_jsx")]).then(function() { return function() { return (__webpack_require__(/*! ./app/javascript/packs/hello_react */ "./app/javascript/packs/hello_react.jsx")); }; });
	}
};
var get = function(module, getScope) {
	__webpack_require__.R = getScope;
	getScope = (
		__webpack_require__.o(moduleMap, module)
			? moduleMap[module]()
			: Promise.resolve().then(function() {
				throw new Error('Module "' + module + '" does not exist in container.');
			})
	);
	__webpack_require__.R = undefined;
	return getScope;
};
var init = function(shareScope, initScope) {
	if (!__webpack_require__.S) return;
	var oldScope = __webpack_require__.S["default"];
	var name = "default"
	if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");
	__webpack_require__.S[name] = shareScope;
	return __webpack_require__.I(name, initScope);
};

// This exports getters to disallow modifications
__webpack_require__.d(exports, {
	get: function() { return get; },
	init: function() { return init; }
});

/***/ })

},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId); }
/******/ __webpack_require__.O(0, ["vendors-node_modules_react-dom_index_js-node_modules_react_index_js-node_modules_webpack-dev--3a93d3","webpack_sharing_consume_default_react_react-webpack_sharing_provide_default_react-dom-webpack-f6baa5"], function() { return __webpack_exec__("./node_modules/webpack-dev-server/client/index.js?protocol=ws%3A&hostname=localhost&port=3035&pathname=%2Fws&logging=info"), __webpack_exec__("webpack/container/entry/demo"); });
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ demo = __webpack_exports__;
/******/ }
]);
//# sourceMappingURL=remote-entry.js.map

Host

Module config

new ModuleFederationPlugin({
        name: "ilx",
        remotes: {
          demo: `demo@http://localhost:3035/packs/remote-entry.js`,
        },
        shared: {
          react: {
            eager: true,
            singleton: true,
          },
          "react-dom": {
            eager: true,
            singleton: true,
          },
        },
      }),

We're aware that it's strange that everything from the webpack-dev-server compiled via Webpacker is hosted at /packs/ but that's the convention. We're obviously fairly confused by these issues and could use any guidance you might have. Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions