我尝试使用Angular 13和React,使用Webpack 5和Module Federation插件实现Micro Frontends。我有一个远程Angular应用程序,我试图导入到我的主机React应用程序中。我已经遵循了文档和指南,但我得到一个错误ScriptExternalLoadError:Loading script failed.当尝试加载远程Angular应用程序时。
下面是我的实现细节:
- 我有两个独立的应用程序,一个Angular,一个React。
- 在我的Angular应用程序中,我已经将@module-federation/client包添加到我的依赖项中,并配置webpack.js.js文件以公开所需的模块。
webpack-config Angular Application
const path = require('path');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: './src/bootstrap.ts',
optimization: {
splitChunks: false,
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
chunkFilename: '[id].chunk.js',
scriptType: 'text/javascript'
},
resolve: {
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true,
},
},
],
},
{
test: /\.html$/,
loader: 'html-loader',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 8082,
hot: true,
historyApiFallback: true,
},
plugins : [
new ModuleFederationPlugin({
name : 'cubs',
library: { type: 'var', name: 'profile' },
filename : 'remoteEntry.js',
exposes : {
'./angular' : './src/bootstrap'
}
}),
]
};
字符串
package-json
{
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular-builders/custom-webpack": "^13.1.0",
"@angular/animations": "~13.3.0",
"@angular/common": "~13.3.0",
"@angular/compiler": "~13.3.0",
"@angular/core": "~13.3.0",
"@angular/forms": "~13.3.0",
"@angular/platform-browser": "~13.3.0",
"@angular/platform-browser-dynamic": "~13.3.0",
"@angular/router": "~13.3.0",
"clean-webpack-plugin": "^4.0.0",
"html-webpack-plugin": "^5.5.1",
"i": "^0.3.7",
"npm": "^9.6.6",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "~13.3.11",
"@angular/cli": "~13.3.11",
"@angular/compiler-cli": "~13.3.0",
"@types/jasmine": "~3.10.0",
"@types/node": "^12.11.1",
"jasmine-core": "~4.0.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.1.0",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~1.7.0",
"style-loader": "^3.3.2",
"ts-loader": "^9.4.2",
"typescript": "~4.6.2"
}
}
型
angular.json
{
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./custom-webpack.config.js"
},
型
bootstrap.ts
import 'zone.js';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { AppComponent } from './app/app.component';
export function mount(container: HTMLElement, props: any) {
const appComponent = new AppComponent();
const element = appComponent.getElement();
container.appendChild(element);
console.log("Component mounted")
}
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
型
在我的React主机应用程序webpack-dev.config中
const { merge } = require('webpack-merge')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const commonConfig = require('./webpack.common')
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')
const devConfig = {
mode : 'development',
devServer : {
port : 8080,
historyApiFallback : {
index : 'index.html'
}
},
plugins : [
new ModuleFederationPlugin({
name : 'container',
remotes : {
reactapp : 'reactapp@http://localhost:8081/remoteEntry.js',
angular : "angular@http://localhost:8082/remoteEntry.js"
}
}),
new HtmlWebpackPlugin({
template : '/public/index.html'
})
]
}
module.exports = merge(commonConfig, devConfig)
型
在App.js中导入的React组件
import React, { useRef, useEffect } from 'react';
import 'angular/angular'
const AngularAppWrapper = () => {
const appRef = useRef(null);
console.log("Making an attempt")
console.log(mount);
useEffect(() => {
if (appRef.current) {
mount(appRef.current, {});
}
}, []);
return <div ref={appRef} />;
};
export default AngularAppWrapper;
型
主机ReactBootstrap
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
reportWebVitals();
型
- 我已经验证了remoteEntry.js文件是从Angular应用程序提供的,URL是正确的(http://localhost:8082/remoteEntry.js)。
- 我已经尝试了网上建议的几种解决方案,比如清除该高速缓存,使用隐身模式,检查网络日志,检查导入模块的路径。
- 尽管如此,我仍然得到错误.我不知道还有什么可以尝试.有人可以帮助我诊断和解决这个问题?
1条答案
按热度按时间tp5buhyn1#
我在Webpack中使用模块联合时遇到了类似的ScriptExternalLoadError问题。对我有效的解决方案是在Webpack配置中将optimization.minimize设置为false。这实质上是在构建过程中禁用代码最小化步骤。
以下是如何做到这一点:
字符串
通过这样做,你可能会注意到bundle的大小会增加,因为代码没有被缩小。但是,它应该解决你遇到的ScriptExternalLoadError。请记住,理想情况下,你应该只在调试时这样做,并为生产找到一个更持久的解决方案。