個人博客: https://alili.tech/
前端微服務化之后,我們會面臨一個問題: 模塊之間重復代碼不能復用的問題.
如果使用npm管理我們的重復代碼,我們會多出維護npm包的成本.
在子模塊更新npm包版本,也是一件很麻煩的事情.
在js文件體積上也沒有任何的優(yōu)化.
組件共享
今天我們就來聊一聊如何在多個模塊中同時使用一個組件.
思路
在base模塊管理公共組件,將組件封裝成動態(tài)組件,這樣在打包的時候我們就可以將該組件切割成單獨文件了.
當其他的子模塊需要這個組件的時候,向Base模塊動態(tài)獲取.
實踐
動態(tài)組件的封裝
為了讓其他模塊可以按需加載我們的公共組件,我們需要對已有的組件封裝成動態(tài)組件.
我這里使用的是 umi/dynamic
,
他是基于https://github.com/jamiebuilds/react-loadable 封裝了一層.
有興趣的小伙伴可以自行了解.
import React from 'react';
import dynamic from 'umi/dynamic';
import PageLoading from '@/components/PageLoading'
export const Demo = dynamic(import( `../Demo`), {loading: () => <PageLoading />})
export default Demo;
對外提供獲取動態(tài)組件的方法
在加載Base模塊的時候,我們可以在window下暴露一個調用該模塊動態(tài)組件的方法
window.getDynamicComponent = async function(name) {
let component = null;
component = await import(`@/components/dynamic/${name}`);
return component[name];
};
子模塊調用公共組件
因為base模塊提供了一個獲取公共組件的全局方法,
我們就可以在任何模塊任何需要調用公共組件的地方去是使用它了.
// 獲取組件
let component = await window.getDynamicComponent('Demo')
為了方便這種公共組件的使用,我們可以將這一方法封裝成一個組件.
在調用公共組件,我們只需要聲明就好了.
import React, { Component } from 'react';
// Matrix 在黑客帝國中是母體的意思
export default class Matrix extends Component {
state = {
DynamicComponent: null
}
static defaultProps = {
$name: ""
}
async componentWillMount() {
this.renderComponent()
}
componentWillReceiveProps(nextProps) {
this.props = nextProps
this.renderComponent()
}
async renderComponent() {
const { $name } = this.props;
try {
if ($name) {
const component = await window.getDynamicComponent($name)
this.setState({
DynamicComponent: component
})
}
} catch (error) {
this.setState({
DynamicComponent: null
})
console.error(error)
}
}
render() {
const { DynamicComponent } = this.state;
// 繼承所有props
return DynamicComponent && <DynamicComponent {...this.props} />;
}
}
在實際頁面中調用我們的公共組件
import React, { Component } from 'react';
import Matrix from '@/components/Matrix'
export default class Page extends Component {
render() {
return (
<div>
<Matrix name="Demo" />
</div>
);
}
}
尾巴
實現(xiàn)這樣的功能,其實非常簡單.
但是因為如此,我們需要對公共組件的顆粒度要有一些把控.
不然我們可能會遇到一個頁面會加載文件過多的問題,隨之會影響頁面加載速度.
當然我們也可以通過現(xiàn)有的網絡技術去改善這種狀況.
有了這一思路,我們或許可以在我們的子模塊中不引用任何的其他組件,
依賴我們的base模塊提供的公共組件.我們就可以完成頁面的開發(fā).
前端微服務化的可玩性非常的高.而且還有更多的玩法沒有挖掘出來.