如何使用 Webpack 创建与容器应用程序共享库的微前端包?

Posted

技术标签:

【中文标题】如何使用 Webpack 创建与容器应用程序共享库的微前端包?【英文标题】:How to create a Micro Frontend bundle with Webpack that shares libraries with the container application? 【发布时间】:2019-12-13 16:13:36 【问题描述】:

我有一个任务。

拥有单水疗框架的微前端。

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

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

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

我发现一个解决方案只是使用 SystemJ 加载体面,例如 html 中的分隔标签,但我只是想知道是否还有另一种解决方案。

谢谢。

SystemJs 方法根据需求加载依赖项,但从 CDN,我只想做同样的事情,但从“共享”webpack 包加载所有依赖项,并使用 react 和其他东西。

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)


【问题讨论】:

意识到你想开发一个微前端。更新了您的标题和我的答案,以更多地关注这个具体主题。希望,它现在有帮助。 【参考方案1】:

更新:

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


所以我的问题只有一个:我不想复制供应商库,如 react、react-dom(任何其他)。我想让它们在其他 [Micro Frontends](与 webpack 捆绑)之间共享

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

微前端的 webpack 配置:

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

以上配置将排除reactreact-dom 并期望它们在全局变量ReactReactDOM 中。然后,您可以通过将库包含在根应用程序(即拼接层)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。

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

我知道拥有一些全球性的东西是什么不好的做法(这违反了与 webpack 捆绑的整个想法)。

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

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

【讨论】:

您好,谢谢您的回复!我会尝试并回复您,以发表更多可能对其他人有所帮助的评论。干杯。 没问题,去吧。【参考方案2】:

今天实现这一目标的最佳方法是使用 Webpack 在 v5 中发布的新模块联合技术。这种方法不使用 SystemJS,而是使用 Webpack 的内部。我们尝试了几种不同的微前端方法,但是这一种比它们都更出色,并且目前在生产中为我们成功运行。设置它肯定会遇到一些挑战,但值得开发人员提高生产力。

这里是创建者 Zack Jackson 制作的信息网站,它应该提供您需要的所有资源:https://module-federation.github.io/

这里是 webpack 文档的链接,它更多地处理技术问题,而不是如何实际设置完整的微前端架构:https://webpack.js.org/concepts/module-federation/

【讨论】:

似乎他们在 react 中完成的大多数应用程序。我实际上是通过拆分为更多应用程序来查看我现有的 Angular 应用程序,即使登录页面也应视为不同的应用程序。对于 angular ,我们需要使用 YARN 而不是 NPM 。所以我想只使用 webpack 方法。如果你能给我一些样品,那就太好了 @AhammadaliPK 我们也使用纱线。如果您使用 yarn 或 npm 应该没有任何区别 :) 不过这里有一些角度示例:github.com/module-federation/module-federation-examples 是的,没有区别,但我只能使用 NPM,很难在服务器上安装 YARN

以上是关于如何使用 Webpack 创建与容器应用程序共享库的微前端包?的主要内容,如果未能解决你的问题,请参考以下文章

Webpack 模块联合不适用于急切的共享库

您如何与部署为弹性 beanstalk 上的工作人员的 docker 容器共享特权信息?

Webpack Module Federation 将共享库的名称更改为数字

Linux 静态库和共享(动态)库的创建与使用详解

由于外部库,Webpack 构建非常缓慢

如何从 docker 容器运行 webpack 构建?