(Translated by https://www.hiragana.jp/)
微前端(singleSpa + React )试玩 · Issue #20 · Vibing/blog · GitHub
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ほろ前端ぜんたん(singleSpa + React )试玩 #20

Open
Vibing opened this issue Nov 18, 2019 · 0 comments
Open

ほろ前端ぜんたん(singleSpa + React )试玩 #20

Vibing opened this issue Nov 18, 2019 · 0 comments

Comments

@Vibing
Copy link
Owner

Vibing commented Nov 18, 2019

前言ぜんげん

わが们团队正ざい做一个XXけい统,わざ术栈React目前もくぜん该系统日渐庞だい,开发及维护成ほんだい,且每必须せい个项いちおこりつつめ,费时费力。经考虑后决定はた其拆ぶんなり个项ゆかり它们组合成ごうせい一个完整系统,ほろ前端ぜんたん构是非常ひじょうこのみてき选择。

ほろ前端ぜんたんゆう以下いか几个こう处:

  1. 单项维护:如将商品しょうひん单拉出来でき形成けいせいいち个项,它可以由一个小组单独维护,实现良好りょうこうかい
  2. 复杂くだてい需要じゅようざいせい集成しゅうせいしきてき庞大けい统内开发,避免巨大きょだいてきだい码量,开发时编译速度そくどかいひさげだか开发效率こうりつ
  3. よう错性:单独项目发生错误かいかげ响整个系统
  4. わざ术栈灵活:vue、react、angular とう包括ほうかつ其他ぜんはしわざ术栈使用しようかい vue てき需要じゅようさいがく react

对我们来说最大さいだいてきこう处是单项维护

展示てんじ

UIしめせれい

わが们将せい个微ぜんはしぶん为两个部ぶん

  1. しゅ项目(Main):红色かまち部分ぶぶんさく为整个项目的もくてきちち级,负责展示てんじさい单模块、头部
  2. 项目(Sub-apps):蓝色かまち部分ぶぶん目的もくてき作用さよう具体ぐたいてき业务展示てんじ

动图展示てんじ

注意ちゅうい栏变,其中包含ほうがん /app1/xxx/app2/xxx,乍一看这是一个项目中两个页面的切换,实际じょう两个独立どくりつてき项目,app1 app2 らい不同ふどうてき git 仓库。

ほろ前端ぜんたん构图

せい个流ほど大概たいがい为:よう户访问 index.html, 此时运行块加载器Js,载器かいすえせい个系统的配置はいちぶんけん(project.config) ちゅうさつかく个项けい统会さき载主项目(Main),しかきさきかいすえゆかりぜん缀动态加载对应的项目

わが们这个架构也参考さんこうりょう网上很多このみてき文章ぶんしょう,其中核心かくしん文章ぶんしょう参考さんこう https://alili.tech/archive/11052bf4/

关于 project.config

大概たいがい如下

[
 {
    isBase: false,
    name: 'app1',
    version: '1.0.0',
    //つう过该ゆかりぜん缀匹はい载当ぜん入口いりくちぶんけん
    hashPrefix: '/app1',
    //入口いりくちぶんけん
    entry: 'http://www.xxxx.com/app1/dist/singleSpaEntry.js',
    //顶级Store
    store: 'http://www.xxxx.com/main/dist/store.js'
  }
  ......
]

わざ术细节

single-spa

わが们找りょう些实现微ぜんはしてき仓库,对比きさき决定使用しようsingle-spa

わが们技术栈 react,ざい项目入口いりくちちゅう需要じゅよう使用しよう single-spa-react らい构建,关键だい码如

import singleSpaReact from 'single-spa-react';

const reactLifecycles = singleSpaReact({
  React,
  ReactDOM,
  rootComponent: Root,
  domElementGetter
});

export function bootstrap(props) {
  return reactLifecycles.bootstrap(props);
}

export function mount(props) {
  return reactLifecycles.mount(props);
}

export function unmount(props) {
  return reactLifecycles.unmount(props);
}

如果你使用しよう vue,使用しよう single-spa-vue

しかきさきざいけい统入こうぶんけんちゅう所有しょゆうてき项目ちゅうさつ进来:

import * as singleSpa from 'single-spa';

singleSpa.registerApplication(
    'app1',
    () => SystemJS.import('app1-entry.js'),
    () => location.hash.startsWith(`#/app1`),
    props
  );

具体ぐたい参考さんこう single-spa かんhttps://single-spa.js.org 这里ゆう很多れい

Webpack あずか SystemJs

わが使用しようてき lerna 统一管理所有项目的依赖包,所有しょゆう赖包てき版本はんぽん统一,这样非常ひじょう方便ほうべん维护。

使用しよう webpack てき dll こうのうはた所有しょゆう目的もくてき公用こうよう赖包抽离,如 react、react-dom、react-router、mobxとう

为了方便ほうべん项目动态载,わが们也参考さんこう网上だい佬的そうほう使用しようりょうsystemjsただ过我们使用しようてき 0.20.19 版本はんぽん配合はいごう systemjs ,ざい Webpack ちゅう需要じゅようあらためいち libraryTarget:

output: {
    publicPath: 'http://www.xxxxx.com/',
    filename: '[name].js',
    chunkFilename: '[name].[chunkhash:8].js',
    path: path.resolve(__dirname, 'release'),
    libraryTarget: 'amd', //注意ちゅうい 这里使用しよう amd てき规范
    library: 'app1'
  },

わが们没ゆう使用しよう umd 规范,也没ゆう使用しよう systemjs さとてき Import Maps
こうのう,而是直接ちょくせつどおり过 project.config らい动态载模块入こう

app通信つうしん

关于这个也看りょう一些大佬的方案,大概たいがい就是所有しょゆうてき项目さとゆう个 store,ざいちゅうさつ入口いりくち时将所有しょゆう store 进队れつ需要じゅよう更新こうしん store さとてきじょう态时,调用 dispatch しょう所有しょゆう store どう

てき做法传统单页应用いち样,一个系统应该只有一个顶级 Store,ゆかり于顶级 Store さとそんてき一般是整个系统的公用状态 如菜单、よう户信いきとう它放ざい Main项目さとただしつつみ时这个Store单独抽离てき

entry: {
    singleSpaEntry: './src/singleSpaEntry.js',
    store: './src/store' //单独いち个入こう
  },

ざいちゅうさつ时,はた这个 Store 传入ごと个项ちゅう

//顶级Store
const mainStore = await SystemJS.import(storeURL);

singleSpa.registerApplication(
    'app1',
    () => SystemJS.import('http://www.x.com/app1/entry.js'),
    hashPrefix('/app1'),
    { mainStore }
);
singleSpa.registerApplication(
    'app2',
    () => SystemJS.import('http://www.x.com/app2/entry.js'),
    hashPrefix('/app1'),
    { mainStore }
);

这样就可以达到ただ管理かんり这一个 Store 就可以,非常ひじょう方便ほうべん
注意ちゅういわが使用しようてき Mobx さく为状态管理かんり

ぜんはし部署ぶしょ

わが们部しょてき方式ほうしき非常ひじょう简单,わが自己じこうつしりょういち个 webpack 插件よう于把つつみきさきてき dist 传到 OSS しかきさきはた项目しんいき传给ふく务端,ふく务端すえわが传入てき项目しんいき组织なり project.config,しかきさきよう户在访问 index.html 时会获取 project.config,此时 single-spa すえ配置はいちちゅうさつ所有しょゆう项目,しかきさきすえ由来ゆらいひしげ对应てき项目入口いりくちぶんけんjsぶんけん

目的もくてき挂载 DOM ざい Main 项目さと

わが们的需求 Main さく为整个项目的もくてき Layout,其中子なかご目的もくてき挂载 Dom 也在 Main项目さと,这就必须とういた Main 项目完全かんぜん渲染完成かんせいきさき才能さいのう挂载项目。わが参考さんこうりょう网上ゆう些微ぜんはしてき实现, domElementGetter 方法ほうほう鉴了过来:

function domElementGetter() {
  let el = document.getElementById('sub-module-wrap');
  if (!el) {
    el = document.createElement('div');
    el.id = 'sub-module-wrap';
  }
  let timer = null;
  timer = setInterval(() => {
    if (document.querySelector('#content-wrap')) {
      document.querySelector('#content-wrap').appendChild(el);
      clearInterval(timer);
    }
  }, 100);

  return el;
}

demo

demohttps://github.com/Vibing/micro-frontend

结束语

这是わが们第いち玩微ぜんはし可能かのうゆう很多地方ちほうかん,还望各位かくいだい佬多つつみ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant