e.b*_*kov 9 architecture reactjs webpack microservices micro-frontend
我有一个任务。
拥有带有单spa框架的微前端。
所以我的问题只有一个:我不想复制像 react、react-dom(任何其他)这样的供应商库。我想让它们在其他微前端(与 webpack 捆绑在一起)之间共享
我知道拥有一些全局内容是什么不好的做法(这违反了与 webpack 捆绑的整个想法)。但是如何解决厂商库重复的问题呢?
我发现一个解决方案只是使用 SystemJs 加载规范,例如 html 中的分隔标签,但我只是想知道也许还有另一种解决方案。
谢谢你。
SystemJs 根据需求加载依赖项但从 CDN 加载依赖项的方法,我只想做同样的事情,但是从带有 react 和其他东西的“共享”webpack 包加载所有依赖项。
window.SystemJS = window.System
function insertNewImportMap(newMapJSON) {
const newScript = document.createElement('script')
newScript.type = 'systemjs-importmap'
newScript.text = JSON.stringify(newMapJSON)
const allMaps = document.querySelectorAll('script[type="systemjs-importmap"]')
allMaps[allMaps.length - 1].insertAdjacentElement(
'afterEnd',
newScript
)
}
const devDependencies = {
imports: {
react: 'https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.development.js',
'react-dom': 'https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.development.js',
'react-dom/server': 'https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom-server.browser.development.js',
'single-spa': 'https://unpkg.com/single-spa@4.3.2/lib/umd/single-spa.min.js',
lodash: 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js',
rxjs: 'https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.js',
}
}
const prodDependencies = {
imports: {
react: 'https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js',
'react-dom': 'https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js',
'react-dom/server': 'https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom-server.browser.production.min.js',
'single-spa': 'https://unpkg.com/single-spa@4.3.2/lib/umd/single-spa.min.js',
lodash: 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js',
rxjs: 'https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.min.js',
}
}
const devMode = true // you will need to figure out a way to use a set of production dependencies instead
if (devMode) {
insertNewImportMap(devDependencies)
} else {
insertNewImportMap(prodDependencies)
}
Run Code Online (Sandbox Code Playgroud)
更新:
刚刚意识到,您的问题是针对Micro?Frontends(不仅是微服务),因此通常与与 Webpack 共享库无关。将微前端添加到您的标签/标题并更新了答案以更加关注此主题。
所以我的问题只有一个:我不想复制像 react、react-dom(任何其他)这样的供应商库。我想让它们在其他 [Micro Frontends](与 webpack 捆绑在一起)之间共享
您可以做的是通过将Webpack externals属性添加到配置中来从微前端的输出包中排除依赖项。
微前端的 webpack 配置:
module.exports = {
...
externals = {
react: 'React',
'react-dom': 'ReactDOM'
}
}
Run Code Online (Sandbox Code Playgroud)
以上配置将排除react
和react-dom
期望他们在全局变量React
和ReactDOM
。然后,您可以通过将库包含在index.html
根应用程序(又名拼接层)内的脚本中来共享这些依赖项:
<html>
...
<body>
...
<script src="<your-host>/react.prod-16.9.0.min.js"></script>
<script src="<your-host>/react-dom.prod-16.9.0.min.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
如果您有其他通用组件要共享,也可以将库脚本集成到组件库中。
包含 as 脚本的原因是:我们不希望我们的容器必须在构建时要求/导入微前端,以避免所有应用程序之间的构建/发布/版本管理耦合。相反,微前端的一个目的是实现部件的完全独立部署,其中包括从构建、测试到发布的持续交付步骤。
我知道拥有一些全局内容是什么不好的做法(这违反了与 webpack 捆绑的整个想法)。
当然,您会在应用程序之间创建某种形式的耦合。但是如果你有一个成熟的、稳定的、通用的库,所有部分共享,这是一个合理的决定。
希望,它有帮助(现在)!