core: __webpack_modules__[moduleId] is not a function

Hi everyone,

[EDIT]: Here is a minimal example

I am trying out the rather new Module Federation in Nodejs.

My host app has the following setup:

module.exports = composePlugins(withNx(), (config, context) => {
    // Update the webpack config as needed here.
    // e.g. `config.plugins.push(new MyPlugin())`
    config.plugins.push(
        new NodeFederationPlugin({
            name: 'absint-api',
            library: { type: 'commonjs-module' },
            filename: 'remoteEntry.js',
            remotes: {
                dashboards: 'dashboards@http://localhost:3203/remoteEntry.js',
            },
        })
    );
    return config;
});

And my remote:

const { composePlugins, withNx } = require('@nx/webpack');
const { NodeFederationPlugin } = require('@module-federation/node');

// Nx plugins for webpack.
module.exports = composePlugins(withNx(), (config, context) => {
    // Update the webpack config as needed here.
    // e.g. `config.plugins.push(new MyPlugin())`
    config.plugins.push(
        new NodeFederationPlugin({
            name: 'dashboards',
            filename: 'remoteEntry.js',
            library: {
                type: 'commonjs-module',
            },
            exposes: {
                './Test': 'apps/plugins/dashboards/backend/src/test.ts',
            },
        })
    );
    return config;
});

The exposed module is just a simply constant:

export const test = 123;

Then somewhere in my host app I am trying to reach for the federated code like this:

import * as test from 'dashboards/Test';

console.log(test);

No matter what I try I always get TypeError: __webpack_modules__[moduleId] is not a function

I can see that the built main.js of my host contains the result of federation plugin

module.exports = new Promise(function (resolve, reject) {
    if(!global.__remote_scope__) {
      // create a global scope for container, similar to how remotes are set on window in the browser
      global.__remote_scope__ = {
        _config: {},
      }
    }

    if (typeof global.__remote_scope__["dashboards"] !== 'undefined') return resolve(global.__remote_scope__["dashboards"]);
    global.__remote_scope__._config["dashboards"] = "http://localhost:3203/remoteEntry.js";
    var __webpack_error__ = new Error();

    __webpack_require__.l(
      "http://localhost:3203/remoteEntry.js",
      function (event) {
        if (typeof global.__remote_scope__["dashboards"] !== 'undefined') return resolve(global.__remote_scope__["dashboards"]);
         var realSrc = event && event.target && event.target.src;
        __webpack_error__.message = 'Loading script failed.\n(' + event.message + ': ' + realSrc + ')';
        __webpack_error__.name = 'ScriptExternalLoadError';
        __webpack_error__.stack = event.stack;
        reject(__webpack_error__);
      },
      "dashboards",
    );
  }).catch((e)=> {
    console.error("dashboards", 'is offline, returning fake remote');
    console.error(e);

    return {
      fake: true,
      get: (arg) => {
        console.log('faking', arg, 'module on', "dashboards");

        return Promise.resolve(() => {
          return () => null
        });
      },
      init: () => {
      }
    }
  }).then(function (remote) {
    if(remote.fake) {
      return remote;
    }
    const proxy = {
      get: (arg)=>{
        return remote.get(arg).then((f)=>{
          const m = f();
          return ()=>new Proxy(m, {
            get: (target, prop)=>{
              if(global.usedChunks) global.usedChunks.add("dashboards" + "->" + arg);
              return target[prop];
            }
          })
        })
      },
      init: function(shareScope) {
        const handler = {
          get(target, prop) {
            if (target[prop]) {
              Object.values(target[prop]).forEach(function(o) {
                if(o.from === '_N_E') {
                  o.loaded = 1
                }
              })
            }
            return target[prop]
          },
          set(target, property, value) {
            if(global.usedChunks) global.usedChunks.add("dashboards" + "->" + property);
            if (target[property]) {
              return target[property]
            }
            target[property] = value
            return true
          }
        }
        try {
          global.__remote_scope__["dashboards"].init(new Proxy(shareScope, handler))
        } catch (e) {

        }
        global.__remote_scope__["dashboards"].__initialized = true
      }
    }
    try  {
      proxy.init(__webpack_require__.S.default)
    } catch(e) {
      console.error('failed to init', "dashboards", e)
    }
    return proxy
  });

I also inspected the line where it is trying to load the module in the built main.js file

console.log(__webpack_modules__); // contains "<1 empty item>" at moduleid 71
const test = __webpack_require__(71);

The exposed entry point at http://localhost:3203/remoteEntry.js is accessible.

What am I doing wrong?

Thank you in advance :]

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 20 (8 by maintainers)

Most upvoted comments

I’m also seeing this error with the latest plugin (6.5.2-rc6.0). I have a host and 3 remotes (all NextJS apps) and none of the remoteEntry files will load in the host. It looks like the error is thrown in the __webpack_require__ function defined in remoteEntry.js and it’s always the same module. I logged { __webpack_modules__, moduleId, value: __webpack_modules__[moduleId] } in one of the remote’s remoteEntry.js:

{
   __webpack_modules__: {
     'webpack/container/entry/search': [Function: webpack/container/entry/search],
     './amp-context': [Function: ./amp-context],
     './amp-mode': [Function: ./amp-mode],
     '../shared/lib/app-router-context': [Function: ../shared/lib/app-router-context],
     './head-manager-context': [Function: ./head-manager-context],
     '../shared/lib/image-blur-svg': [Function: ../shared/lib/image-blur-svg],
     '../shared/lib/image-config-context': [Function: ../shared/lib/image-config-context],
     '../shared/lib/image-config': [Function: ../shared/lib/image-config],
     'next/dist/shared/lib/image-loader': [Function: next/dist/shared/lib/image-loader],
     '../shared/lib/router-context': [Function: ../shared/lib/router-context],
     '../shared/lib/router/utils/add-path-prefix': [Function: ../shared/lib/router/utils/add-path-prefix],
     '../shared/lib/router/utils/format-url': [Function: ../shared/lib/router/utils/format-url],
     '../shared/lib/router/utils/is-local-url': [Function: ../shared/lib/router/utils/is-local-url],
     '../shared/lib/router/utils/parse-path': [Function: ../shared/lib/router/utils/parse-path],
     '../shared/lib/router/utils/remove-trailing-slash': [Function: ../shared/lib/router/utils/remove-trailing-slash],
     '../shared/lib/router/utils/resolve-href': [Function: ../shared/lib/router/utils/resolve-href],
     './side-effect': [Function: ./side-effect],
     '../shared/lib/utils': [Function: ../shared/lib/utils],
     '../shared/lib/utils/warn-once': [Function: ../shared/lib/utils/warn-once],
     'next/router': [Function: next/router],
     react: [Function: react],
     'webpack/sharing/consume/default/next/link/next/link': [Function (anonymous)],
     'webpack/sharing/consume/default/react/jsx-dev-runtime/react/jsx-dev-runtime': [Function (anonymous)],
     './src/components/SearchButton.module.scss': [Function: ./src/components/SearchButton.module.scss],
     '../../packages/design-system/components/Modal/Modal.module.scss': [Function: ../../packages/design-system/components/Modal/Modal.module.scss],
     './src/components/SearchButton.tsx': [Function: ./src/components/SearchButton.tsx],
     '../../node_modules/next/dist/client/image.js': [Function: ../../node_modules/next/dist/client/image.js],
     '../../node_modules/next/dist/shared/lib/head.js': [Function: ../../node_modules/next/dist/shared/lib/head.js],
     '../../packages/design-system/components/Modal/Modal.tsx': [Function: ../../packages/design-system/components/Modal/Modal.tsx],
     '../../node_modules/next/image.js': [Function: ../../node_modules/next/image.js],
     '../../node_modules/next/node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs': [Function: ../../node_modules/next/node_modules/@swc/helpers/cjs/_interop_require_wildcard.cjs]
   },
   moduleId: '../../node_modules/next/node_modules/@swc/helpers/cjs/_interop_require_default.cjs',
   value: undefined
 }

Not sure if this helps, but I’m happy to provide more information if needed.