我有一个任务。

拥有具有单 Spa 框架的微前端。

  1. 门户/主应用程序(通过 url 加载所有其他 js 代码)
  2. 微前端 1(基于 React)
  3. 微前端 2(基于 React)

所以我的问题只有一个:我不想复制像react、react-dom(任何其他)这样的 vendor 库。我想让它们在其他微前端(与 webpack 捆绑在一起)之间共享

我知道拥有一些全局的东西是什么不好的做法(它违反了与 webpack 捆绑的整个想法)。但是如何解决 vendor 库重复的问题呢?

我发现一个解决方案只是使用 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) 
} 
 

请您参考如下方法:

更新:

刚刚意识到,您的问题是针对 Micro Frontends (不仅是微服务),因此一般来说并不是与 Webpack 共享库。将微前端添加到您的标签/标题中,并更新了答案以更加关注此主题。

<小时 />

So my problem just one: I don't want to duplicate vendor libraries like react, react-dom (any others). And I want to make them shared among other [Micro Frontends] (which is bundled with webpack)

您可以做的是通过添加 Webpack externals 从微前端的输出包中排除依赖项属性到配置。

微前端的 webpack 配置:

module.exports = { 
  ... 
  externals = { 
    react: 'React', 
    'react-dom': 'ReactDOM' 
  } 
} 

以上配置将排除 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> 

如果您有其他常用组件要共享,您还可以将库脚本集成到component library中.

包含为脚本的原因是:我们不希望我们的容器必须 require/import the Micro Frontends at build time为了避免所有应用程序之间的构建/发布/版本管理的耦合。相反,微前端的目的之一是完全实现 independent deployment各个部分,其中包括从构建、测试到发布的持续交付步骤。

I know what is the bad practice to have some global stuff (it's violate the whole idea of bundeling with webpack).

当然,您可以在应用程序之间创建某种形式的耦合。但如果你有一个成熟、稳定、所有部分共享的通用库,那么这是一个合理的决定。

希望,它有帮助(现在)!


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!