“Webpack Module Federation error ‘TypeError: __webpack_modules__[moduleId] is not a function'”

huangapple go评论56阅读模式
英文:

Webpack Module Federation error "TypeError: __webpack_modules__[moduleId] is not a function"

问题

以下是你要翻译的代码部分:

I try to implement a simple example about Module Federation with vanilla js functions.

Directory structure:
  ── packages
    ├── home
    │    ├── index.html
    │    ├── package.json
    │    ├── src
    │    │       └── index.js
    │    └── webpack.config.js
    └── nav
        ├── index.html
        ├── package.json
        ├── src
        │    ├── Header.js
        │    ├── index.js
        └── webpack.config.js

期望的结果是 home 应用程序渲染 navHeader

nav 的 Webpack 配置:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

const deps = require("./package.json").dependencies;
module.exports = {
    mode: 'development',
    entry: './src/index.js',
    optimization: {
        minimize: false
    },
    resolve: {
        extensions: [".js"],
    },
    output: {
        publicPath: "http://localhost:4001/",
    },
    plugins: [
        new ModuleFederationPlugin({
            name: "nav",
            filename: "remoteEntry.js",
            library: {type: 'var', name: 'nav'},
            exposes: {
                "./Header": "./src/Header"
            },
            shared: {
                ...deps
            }
        }),
        new HtmlWebpackPlugin({
            title: 'Module Federation Example',
        }),
    ],
}

home 的 Webpack 配置:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')

const deps = require("./package.json").dependencies;
module.exports = {
    mode: 'development',
    entry: './src/index.js',
    optimization: {
        minimize: false,
    },
    resolve: {
        extensions: [".js"],
    },
    output: {
        publicPath: "http://localhost:4000/",
    },
    plugins: [
        new ModuleFederationPlugin({
            name: "home",
            filename: "remoteEntry.js",
            remotes: {
                nav: "nav@http://localhost:4001/remoteEntry.js"
            },
            shared: {
                ...deps
            }
        }),
        new HtmlWebpackPlugin({
            title: 'Module Federation Example',
        }),
    ],
}

这是 Header 部分:

export default () => {
    const node = document.createElement('div');
    node.innerHTML = 'Header';
    node.style = 'padding: 1em; box-sizing: border-box;display: flex;background: aquamarine;font-family:sans-serif;';
    return node;
}

home 中的 index.js 文件中,我导入了 Header

import Header from 'nav/Header';

const Greetings = () => {
    const node = document.createElement('h1');
    node.innerHTML = 'App Shell';
    return node;
}

document.addEventListener("DOMContentLoaded", () => {
    document.body.appendChild(Greetings());
    document.body.appendChild(Header());
});

构建并在 home 应用程序的 URL 上提供服务后,我收到以下错误:

Uncaught TypeError: __webpack_modules__[moduleId] is not a function
    at __webpack_require__ (main.js:66:41)
    at eval (index.js:2:68)
    at ./src/index.js (main.js:19:1)
    at __webpack_require__ (main.js:66:41)
    at main.js:217:37
    at main.js:219:12

你可以在 StackBlitz 上重现这个问题。

我尝试在 ModuleFederationPlugin 中添加一个库选项 library: {type: 'var', name: 'nav'},但我不明白为什么它不起作用。

我期望看到 nav/Header 渲染在 home 应用程序中。

英文:

I try to implement a simple example about Module Federation with vanilla js functions.

Directory structure:

  ── packages
    ├── home
    │   ├── index.html
    │   ├── package.json
    │   ├── src
    │   │   └── index.js
    │   └── webpack.config.js
    └── nav
        ├── index.html
        ├── package.json
        ├── src
        │   ├── Header.js
        │   ├── index.js
        └── webpack.config.js

The expecting result is that home app render the Header of the nav.

Webpack config of nav

const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

const deps = require("./package.json").dependencies;
module.exports = {
    mode: 'development',
    entry: './src/index.js',
    optimization: {
        minimize: false
    },
    resolve: {
        extensions: [".js"],
    },
    output: {
        publicPath: "http://localhost:4001/",
    },
    plugins: [
        new ModuleFederationPlugin({
            name: "nav",
            filename: "remoteEntry.js",
            library: {type: 'var', name: 'nav'},
            exposes: {
                "./Header": "./src/Header"
            },
            shared: {
                ...deps
            }
        }),
        new HtmlWebpackPlugin({
            title: 'Module Federation Example',
        }),
    ],
}

Webpack config of home

const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')

const deps = require("./package.json").dependencies;
module.exports = {
    mode: 'development',
    entry: './src/index.js',
    optimization: {
        minimize: false,
    },
    resolve: {
        extensions: [".js"],
    },
    output: {
        publicPath: "http://localhost:4000/",
    },
    plugins: [
        new ModuleFederationPlugin({
            name: "home",
            filename: "remoteEntry.js",
            remotes: {
                nav: "nav@http://localhost:4001/remoteEntry.js"
            },
            shared: {
                ...deps
            }
        }),
        new HtmlWebpackPlugin({
            title: 'Module Federation Example',
        }),
    ],
}

This is the Header:

export default () => {
    const node = document.createElement('div');
    node.innerHTML = 'Header';
    node.style = 'padding: 1em; box-sizing: border-box;display: flex;background: aquamarine;font-family:sans-serif;'
    return node;
}

In index.js file in home is where i import the Header:

import Header from 'nav/Header';

const Greetings = () => {
    const node = document.createElement('h1');
    node.innerHTML = 'App Shell';
    return node;
}

document.addEventListener("DOMContentLoaded", () => {
    document.body.appendChild(Greetings());
    document.body.appendChild(Header());
});

After build and serve on the url of the home app i retrieve this error:

Uncaught TypeError: __webpack_modules__[moduleId] is not a function
    at __webpack_require__ (main.js:66:41)
    at eval (index.js:2:68)
    at ./src/index.js (main.js:19:1)
    at __webpack_require__ (main.js:66:41)
    at main.js:217:37
    at main.js:219:12

You can reproduce here in StackBlitz.

I tried to add a library option library: {type: 'var', name: 'nav'}, in the ModuleFederationPlugin but i don't understand why is not working.

I expected to see the nav/Header rendered inside home app.

答案1

得分: 0

I found the solution.

The error arises because I was importing the remote module directly into the index.js.
The remote module is loaded asynchronously so it was not yet available for import and hence the error.

The fastest solution is to import the remote modules into a bootstrap.js file to make sure they are available and import it in index.js

index.js

import("./bootstrap");

bootstrap.js

import Header from 'nav/Header';
// other logics ...
英文:

I found the solution.

The error arises because I was importing the remote module directly into the index.js.
The remote module is loaded asynchronously so it was not yet available for import and hence the error.

The fastest solution is to import the remote modules into a bootstrap.js file to make sure they are available and import it in index.js

index.js

    import("./bootstrap");

bootstrap.js

    import Header from 'nav/Header';
    // other logics ...

huangapple
  • 本文由 发表于 2023年3月31日 18:38:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75897573.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定