我怎样才能“引导”?当 webpack 输出类型为“library”时是否支持 webpack 模块联合?
我有一个带有webpack配置的WebPack“库”项目,看起来像这样:
module.exports = ({ mode }) => {
const isProd = mode === 'production';
return {
mode,
entry: './src/index.tsx',
output: {
library: 'MyLibraryComponents',
path: path.resolve(__dirname, 'build'),
filename: getOutputFileName(isProd),
},
devServer: { ... },
optimization: { ... },
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
},
{
test: /\.less$/i,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{
loader: 'less-loader',
},
],
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
scriptLoading: 'blocking',
template: resolveAppPath('public/index.html'),
}),
],
};
};
此WebPack构建创建一个名为“ mylibraryComponents”的全局变量,该变量的方法具有使用React> React> Reactdom.render()给定htmlelement的React React组件的方法
。我的项目之所以以这种方式设置,是因为我正在旧版应用程序中工作,但是想在React中重新编写UI的某些部分。
这是库的输入文件的样子。条目文件在.ts
中,但我在这里对其进行了一些简化:
// src/index.tsx
import ReactDOM from 'react-dom';
export Examples = {
FooComponent: {
async render(htmlElement, props) {
const { default: Foo } = await import("./components/Foo");
ReactDOM.render(<Foo {...props} />, htmlElement);
}
},
BarComponent: {
async render(htmlElement, props) {
const { default: Bar } = await import("./components/Bar");
ReactDOM.render(<Bar {...props} />, htmlElement);
}
}
};
当WebPack MAIN
Bundle使用&lt; script src ='''''' &gt;
,它在window
上创建一个对象, mylibraryComponents
。然后,我可以将React组件渲染到这样的旧应用程序中:mylibrarycomponents.examples.fooocomponent.render(...)
,
随着添加了更多组件,我有兴趣使用模块Federation使用模块联盟。作为一种独立部署组件并隔离依赖项等的手段。
但是,在所有模块联合项目示例中,我看到的示例有必要拥有一个“ bootstrap”文件并让您的WebPack输入文件执行此操作。然后,您的应用程序的“真实”输入文件应重命名为bootstrap.js
:
import("./bootstrap")
显然,这确保了项目的共享模块首先由浏览器加载或类似的东西。原因对我来说还不清楚100%。
我看到的问题是,我的项目的输入文件实际上具有我的WebPack库取决于的“导出”,而如果这是传统的React应用程序,则只会执行类似的操作:
import ReactDOM from "react-dom";
import App from "./App;
ReactDOM.render(<App />, document.getElementById("root"));
如果我将输入点文件更新为import('./ bootstrap')
,然后在我在控制台中检查它时,我的库最终是一个空对象。
有没有一种方法可以编写“ Bootstrap”条目文件,以便我可以支持该项目中的模块联合会?
感谢您的帮助。
I have a webpack 'library' project with a webpack config that looks like this:
module.exports = ({ mode }) => {
const isProd = mode === 'production';
return {
mode,
entry: './src/index.tsx',
output: {
library: 'MyLibraryComponents',
path: path.resolve(__dirname, 'build'),
filename: getOutputFileName(isProd),
},
devServer: { ... },
optimization: { ... },
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
},
{
test: /\.less$/i,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{
loader: 'less-loader',
},
],
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
scriptLoading: 'blocking',
template: resolveAppPath('public/index.html'),
}),
],
};
};
This webpack build creates a global variable called "MyLibraryComponents", which has methods on it that render react components given an HTMLElement using ReactDOM.render()
. My project is set up this way because I'm working in a legacy application, but want to re-write certain parts of the UI in react.
Here is what the entry file for the library looks like. The entry file is in .ts
but I've simplified it a bit here:
// src/index.tsx
import ReactDOM from 'react-dom';
export Examples = {
FooComponent: {
async render(htmlElement, props) {
const { default: Foo } = await import("./components/Foo");
ReactDOM.render(<Foo {...props} />, htmlElement);
}
},
BarComponent: {
async render(htmlElement, props) {
const { default: Bar } = await import("./components/Bar");
ReactDOM.render(<Bar {...props} />, htmlElement);
}
}
};
When the webpack main
bundle is downloaded using a <script src=''>
, it creates an object on window
called MyLibraryComponents
. I can then render react components into the legacy app like this: MyLibraryComponents.Examples.FooComponent.render(...)
As more components are added to this library, I'm interested in potentially using Module Federation as a means to independently deploy components, and to isolate dependencies, etc.
However, in all the module federation project examples I've seen it is necessary to have a "bootstrap" file and have your webpack entry file do this. And then your "real" entry file to your app should be renamed to bootstrap.js
:
import("./bootstrap")
Apparently, this ensures that the project's shared modules are loaded by the browser first, or something like that. The reason isn't 100% clear to me yet.
The issue I'm seeing is that my project's entry file actually has "exports" that my webpack library depends on, whereas if this was a traditional react app, it would just do something like this:
import ReactDOM from "react-dom";
import App from "./App;
ReactDOM.render(<App />, document.getElementById("root"));
If I update my entry point file to just import('./bootstrap')
, then my library just ends up being an empty object when I inspect it in the console.
Is there a way I can write the 'bootstrap' entry file so that I can support module federation in this project?
Thank you for the help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我需要更新我的新索引文件以执行这样的操作:
使用引用窗口的任何代码。麦基里components需要确保现在存在,因为现在它被“加载”了异步。或者您可以做这样的事情:
I needed to update my new index file to do something like this:
Any code using referencing window.MyLibraryComponents needs to ensure this exists now though since it's now being "loaded" asynchronously. Or you can do something like this: