英文:
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 应用程序渲染 nav 的 Header。
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 ...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论