![](/img/trans.png)
[英]How to make webpack bundle js directly in script tag, not via src
[英]Loading webpack bundle via script tag for microfrontend approach
我正在關注幾篇關於如何使用 React 實現簡單微前端方法的文章( 此處和此處,請參閱問題底部的示例存儲庫)。
當兩個應用程序(根應用程序和子應用程序)在各自的開發服務器中運行時,它可以完美運行。 但是,當我將構建工件部署到真正的 Web 服務器時,它不起作用。 這是根應用程序中的重要代碼:
function MicroFrontend({name, host, history}) {
useEffect(() => {
const scriptId = `micro-frontend-script-${name}`;
const renderMicroFrontend = () => {
window["render" + name](name + "-container", history);
};
if (document.getElementById(scriptId)) {
renderMicroFrontend();
return;
}
fetch(`${host}/asset-manifest.json`)
.then((res) => res.json())
.then((manifest) => {
const script = document.createElement("script");
script.id = scriptId;
script.crossOrigin = "";
script.src = `${host}${manifest.files["main.js"]}`;
script.onload = () => {
renderMicroFrontend();
};
document.head.appendChild(script);
});
return () => {
window[`unmount${name}`] && window[`unmount${name}`](`${name}-container`);
};
});
return <main id={`${name}-container`}/>;
}
MicroFrontend.defaultProps = {
document,
window,
};
當我點擊為微應用加載 main.js 的按鈕時,它工作正常,直到它調用上面的renderMicroFrontend
。 然后我在瀏覽器中收到此錯誤: Uncaught TypeError: window[("render" + t)] is not a function
這是因為它找不到加載應該在window
上的微前端的函數。 當我在開發服務器中運行這兩個應用程序時,我在window
上具有正確的功能並且可以正常工作。 當我對部署到真實服務器的兩個應用程序執行相同的步驟時(在運行npm run build
),而不是在我的window
上使用renderMicroApp
函數,我有一個名為webpackJsonpmicro-app
的不同變量。
我發現這是由於 webpack 文檔中的 output.library 選項(和/或相關選項)造成的:
output.jsonp 函數。 string = 'webpackJsonp' 僅在 target 設置為 'web' 時使用,它使用 JSONP 加載按需塊。 如果使用 output.library 選項,庫名稱會自動與 output.jsonpFunction 的值連接。
我基本上希望加載和評估包/腳本,以便renderMicroApp
函數在窗口上可用,但是我不知道我需要哪些 webpack 設置才能使其工作,因為有很多不同的選項排列。
作為參考,我在微應用程序中使用了以下配置覆蓋(在react-app-rewired
之上):
module.exports = {
webpack: (config, env) => {
config.optimization.runtimeChunk = false;
config.optimization.splitChunks = {
cacheGroups: {
default: false,
},
};
config.output.filename = "static/js/[name].js";
config.plugins[5].options.filename = "static/css/[name].css";
config.plugins[5].options.moduleFilename = () => "static/css/main.css";
return config;
},
};
在我的 index.tsx(在微型應用程序中)中,我將函數暴露在窗口上:
window.renderMicroApp = (containerId, history) => {
ReactDOM.render(<AppRoot />, document.getElementById(containerId));
serviceWorker.unregister();
};
一些示例回購:
您可以嘗試使用terser-webpack-plugin 。
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
webpack: (config, env) => {
config.optimization.minimize = true;
config.optimization.minimizer = [new TerserPlugin({
terserOptions: { keep_fnames: true }
})];
config.optimization.runtimeChunk = false;
config.optimization.splitChunks = {
cacheGroups: {
default: false,
},
};
config.output.filename = "static/js/[name].js";
config.plugins[5].options.filename = "static/css/[name].css";
config.plugins[5].options.moduleFilename = () => "static/css/main.css";
return config;
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.