如何避免使用 webpack(和 single-spa)在相同范围内对某些项目进行外部设置

How to avoid external setting of some projects under same scope with webpack (and single-spa)

问题:

如何(是否可能)配置webpack (使用single-spa),制作一些包(项目) 在范围 (@orginazation) 外部和其他内部 (非外部) ?

项目信息:

我们正在构建 single-spa application using webpack an uses Github npm registrer (和 github 操作)。所有的微前端都是Github中的项目,其中一些是util/helper/provider个项目,用webpack编译成externals。

但是其中一些是要用微前端编译的(不能是外部的

似乎当 webpack 将组织范围内的项目之一视为外部时,它会将该范围内的所有包设置为外部!

正如我们从日志中看到的,“CompilingTool”也将被编译为外部,事件认为它不应该。

包在文件中设置为:

import auth from "@ORGANIZATION/auth"  // <- Should be external
import compilingTool from "@ORGANIZATION/compilingTool" // <- Should NOT be external

可以将 single-spa 配置中的外部更改为其他内容,例如:

import compilingTool from "ORGANIZATION-Internal/compilingTool" // Not optimal!!

但这意味着智能不再起作用,因为它现在不指向微前端中的实际包(仍然是“@ORGANIZATION/compilingTool”)

如果必须开始使用像 gulp 这样的预构建工具来进行这样的转换,那将不是最佳选择。而且我们不喜欢必须使用不同的 Github 帐户来拥有不同的范围。

所以任何让 webpack 理解它不应该将“@ORGANIZATION/compilingTool”包放在外部的帮助或想法都是非常有用的。

已经尝试过:

根据 externals 的 webpack 文档,应该可以使用 验证函数 and/or subtract但两者都不适用于带有 spa-setup 的范围包。

Compile/dependency 信息:

single-spa/webpack编译为SystemJs

Webpack 和 single-spa 包:

webpack.config.js (具体项目已替换为伪代码!)

const { merge }  = require("webpack-merge");
const singleSpaDefaults = require("webpack-config-single-spa-react-ts");
const { readFileSync } = require('fs')
const path = require('path')
const dotenv = require('dotenv').config( {
  path: path.join(__dirname, '.env')
} );

module.exports = (webpackConfigEnv, argv) => {
  const defaultConfig = singleSpaDefaults({
    orgName: "ORGANIZATION",
    projectName: "SOME-MICRO-FRONTEND",
    webpackConfigEnv,
    argv,
  });

  return merge(defaultConfig, {
    // modify the webpack config however you'd like to by adding to this object
    externals: [
      "react", 
      "react-dom",
        "@ORGANIZATION/auth",  // <- This should be external
        //"@ORGANIZATION/compilingTool" // <- This should NOT be external
      ],
    devServer: {
      port: 5400,
      https: {
        key: readFileSync( path.resolve(__dirname, path.join(process.env.CERT_PATH, process.env.CERT_KEY_FILE_NAME))),
        cert: readFileSync(path.resolve(__dirname, path.join(process.env.CERT_PATH, process.env.CERT_FILE_NAME)))
      }
    },
  });
};

运行 webpack 构建的时间控制台输出: (具体项目已替换为伪代码!)

webpack serve
<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: https://localhost:XXXX/
<i> [webpack-dev-server] On Your Network (IPv4): https://XX.X.XXX.XXX:XXXX/
<i> [webpack-dev-server] Content not from webpack is served from 'C:\path-to-PROJECT\public' directory
<i> [webpack-dev-server] 404s will fallback to '/index.html'
asset PROJECT-NAME.js 436 KiB [emitted] (name: main) 1 related asset
asset index.html 3.1 KiB [emitted]
runtime modules 26.3 KiB 14 modules
modules by path ./node_modules/ 329 KiB 58 modules
modules by path external "@ORGANIZATION/ 210 bytes
  external "@ORGANIZATION/auth" 42 bytes [built] [code generated]
  external "@ORGANIZATION/compilingTool" 42 bytes [built] [code generated]
modules by path (...OTHER LOGS... ) 
external "react" 42 bytes [built] [code generated]
external "react-dom" 42 bytes [built] [code generated]
webpack 5.48.0 compiled successfully in 17732 ms
No issues found.

这可以通过将 orgPackagesAsExternal: false 传递给 single-spa webpack 配置来实现,在您的例子中名为 singleSpaDefaults。根据 create-single-spa documentation

This changes whether package names that start with @your-org-name are treated as webpack externals or not. Defaults to true.

然后您需要:

  • 枚举要标记为外部的包
  • 提供执行此操作的函数(您已在问题中注明)

然后像往常一样将其与 single-spa 的配置合并。因为这对每个微前端来说都会变得冗长和烦人,考虑在你发布的特定于你的公司的基本配置中执行此操作,然后每个 mfe 都需要使用它。