如何使用Webpack创建与容器应用程序共享库的Micro Frontend捆绑软件? [英] How to create a Micro Frontend bundle with Webpack that shares libraries with the container application?

查看:169
本文介绍了如何使用Webpack创建与容器应用程序共享库的Micro Frontend捆绑软件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有任务.

具有带有单spa框架的Micro Frontends.

To have Micro Frontends with single-spa framework.

  1. 门户/主应用程序(通过网址加载所有其他js代码)
  2. Micro Frontend 1(基于反应)
  3. Micro Frontend 2(基于反应)

所以我的问题只有一个:我不想复制供应商库,例如react,react-dom(其他任何库).而且我想让它们在其他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捆绑的整个想法).但是,如何解决供应商库重复的问题呢?

I know what is the bad practice to have some global stuff (it's violate the whole idea of bundeling with webpack). But how to solve the problem of duplication of vendor libraries?

我发现一个解决方案只是像使用html中的分隔标签那样使用SystemJs加载变量,但是我只是想知道也许还有另一种解决方案.

I found one solution just load decencies with SystemJs like separated tags in html, but I just wonder maybe there is another solutuion for that.

谢谢.

SystemJs按需加载依赖项的方法,但是从CDN,我只想做同样的事情,但是从React和其他东西中加载来自共享" webpack捆绑包的所有依赖项.

SystemJs approach to load dependencies by demand but from CDN, I just want do the same but load all dependencies from "shared" webpack bundle with react and other stuff.

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共享库的一般信息.在您的标签/标题中添加了Micro Frontend,并更新了答案,使其更加专注于该主题.

Just realized, that your question is directed at Micro Frontends (not only micro services) and therefore is not about sharing libraries with Webpack in general. Added Micro Frontend to your tags/title and updated the answer to be more focused on this topic.

所以我的问题只有一个:我不想复制供应商库,例如react,react-dom(其他任何库).我想让它们在[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外部组件<>从Micro Frontends的输出包中排除依赖项. /a>属性添加到配置.

What you can do is exclude dependencies from the output bundle of your Micro Frontends by adding a Webpack externals property to the config.

webpack配置:

webpack config of your Micro Frontends:

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

以上配置将排除reactreact-dom,并期望它们出现在全局变量ReactReactDOM中.然后,您可以通过将库包含在根应用程序的index.html(也称为拼接层)内的脚本中来共享这些依赖项:

Above config would exclude react and react-dom and expect them in the global variables React and ReactDOM. You can then share those dependencies by including the libraries in a script inside index.html of your root applicationn aka stitching layer:

<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>

如果您要共享其他通用组件,也可以将库脚本集成到组件库.

If you have other common components to share, you can also integrate the library scripts in a component library.

包含为脚本的原因是:我们不希望我们的容器必须独立部署包括从构建,测试到发布的连续交付步骤.

The reason for the include as script is: We do not want that our container has to require/import the Micro Frontends at build time in order to avoid a coupling of build/release/version management between all apps. Instead one purpose of Micro Frontends is to achieve fully independent deployment of the parts, which include continuous delivery steps from build, test to release.

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

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

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

Of course, you create some form of coupling between the apps. But if you have a mature, stable and common library shared by all parts, it is a reasonable decision.

希望,(现在)有帮助!

Hope, it helps (now)!

这篇关于如何使用Webpack创建与容器应用程序共享库的Micro Frontend捆绑软件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆