基于SingleSPA的微前端解决方案(二)

第2部分:使用 Nx.js 建立微前端的 Nx Monorepo

Nx.js 是一个强大的单仓库管理工具,用于在开发过程中创建和运行项目。在 Nx.js 管理的单仓库中,所有依赖项都位于同一根 node_modules 中,而项目则以并行方式列出。当存在一系列小型项目具有相似技术栈和共享依赖项时,这种方式特别有优势。

Nx.js 的另一个亮点是它是开源的,你可以构建自己的扩展,甚至在必要时更改一些核心功能。感谢开发者社区,有许多用于生成、运行和部署项目的 Nx.js 扩展和插件。

让我们开始吧。要使用 Nx.js 创建一个 Nx Monorepo,请确保已安装 Node.js,并运行以下命令:

npx create-nx-workspace@latest

命令行中提供了清晰的工具,你可以根据你的业务情况创建工作空间。在我的情况下,我只创建了一个空工作空间,稍后再创建项目。我将工作空间命名为 “harper-ws”。

因为我们的工作空间是为在 Single SPA 中托管的微前端项目设计的,所以我们只需在工作空间中添加 @nx/react 作为我们的生成器:

yarn add @nx/react -W -D

请确保在命令中使用 -W,它将在同一 node_modules 中安装你的依赖项。

现在我们可以创建我们的第一个项目了:

npx nx g @nx/react:app

或者,如果你将 Nx 安装为全局模块:

npm install -g nx
nx g @nx/react:app

选择一个项目名称,例如 “dashboard”。在创建了 React 应用之后,我们需要进行一些更改,以便将其作为 Single SPA 单应用程序进行托管。

首先,让我们创建一个生命周期文件,文件名的格式必须是 orgName{orgName}-{projectName}。例如,如果组织名称是 “QuickBot”,那么文件名应该是 “QuickBot-dashboard.js”,在文件中:

import App from './app/app.tsx';

const lc = singleSpaReact({
    React,
    ReactDOMClient,
    rootComponent: App,
    renderType: "createRoot",
    errorBoundary(err, _info, _props) {
        return null
    }
});

export const { bootstrap, mount, unmount } = lc;

export default lc

也别忘了对 App.tsx 进行一些更改,以便将应用程序设为懒加载:

import styles from './app.module.scss';
import React, { Suspense } from 'react';
import { Home } from '@src/page/home/index';
import { BrowserRouter } from 'react-router-dom';

export function App() {

  return (
    <Suspense fallback={<div>Loading...</div>}>
      <BrowserRouter>
          <Home />
      </BrowserRouter>
    </Suspense>
  );
}

export default React.memo(App);

并且不要忘记 main.tsx:

import React, { StrictMode } from 'react';
import * as ReactDOM from 'react-dom/client';
const LazyApp = React.lazy(() => import('./app/app'));
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <StrictMode>
    <LazyApp />
  </StrictMode>
);

下一个需要更新的文件是 tsconfig.json 文件,这是我的 tsconfig 文件:

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "allowJs": false,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "baseUrl": "./",
    "paths": {
      "@app/*": ["src/app/*"],
      "@env/*": ["src/environments/*"],
      "@src/*": ["src/*"],
      "@components/*": ["src/components/*"],
      "@assets/*": ["src/assets/*"],
      "@store/*": ["src/store/*"],
    },
  },
  "files": [],
  // 有时你可能需要一个 declaration.d.ts 文件,然后将其添加到 include 中
  "include": [],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.spec.json"
    }
  ],
  "extends": "../tsconfig.base.json"
}

接下来我们需要做的必要的事情是编写我们的 extra-webpack.config.js。不建议更改自动生成的 webpack.config.js 文件。以下是 extra-webpack.config.js 的示例代码:

const { merge } = require('webpack-merge');
const singleSpaDefaults = require('webpack-config-single-spa-react');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const path = require('path');
module.exports = (webpackConfigEnv, argv) => {
  const defaultConfig = singleSpaDefaults({
    orgName: 'QuickBot', // 确保你的 orgName 正确
    projectName: 'dashboard', // 还有 dashboard
    webpackConfigEnv,
    argv,
  });
  return merge(defaultConfig, {
    output: {
      path: path.resolve(__dirname, '..', 'singlespa-dist', 'dashboard'),
    },
    resolve: {
      extensions: ['.js', '.ts', '.tsx', '.jsx'],
      alias: {
        fs: path.resolve(__dirname, 'node_modules/browserify-fs'),
        '@src': path.resolve(__dirname,'src'),
        '@components': path.resolve(__dirname,'src', 'components'),
        '@app': path.resolve(__dirname,'src', 'app'),
        '@env': path.resolve(__dirname,'src', 'environments'),
        '@assets': path.resolve(__dirname, 'assets'),
        '@store': path.resolve(__dirname,'src','store'),
      },
    },
    plugins: [
    ],
    module: {
      rules: [
        {
          test: /.s[ac]ss$/i,
          use: [
            'style-loader',
            'css-loader',
            {
              loader: 'sass-loader',
              options: {
                implementation: require('sass'),
                sassOptions: {
                  fiber: false,
                },
              },
            },
          ],
        },
        { parser: { System: false } },
        {
          test: /.js|.ts|.tsx|.jsx$/,
          exclude: /(node_modules|bower_components)/,
          use: {
            loader: 'babel-loader',
          },
        },
      ],
    },
  });
};

在开发应用程序时,你可以使用 “nx serve” 命令,但要作为单一的 Single SPA 微前端运行,你需要使用我们自定义的 webpack 配置运行,例如:

npx webpack serve --config extra-webpack.config.js --port 8081

因此,我在根 package.json 中添加了一个脚本:

{
	 "scripts": {
	   "dashboard:serve": "npx webpack serve --config ./dashboard/extra-webpack.config.js --   port 8081"
	 }
}

现在,运行 yarn dashboard:serve,并在浏览器中打开 http://localhost:8081。页面上的链接对应于你想要在 “root-config” 项目中托管的 JavaScript 文件。

原文链接:https://juejin.cn/post/7328317423097184294 作者:百罗

(0)
上一篇 2024年1月27日 下午4:37
下一篇 2024年1月27日 下午4:47

相关推荐

发表回复

登录后才能评论