基于qiankun从零搭建微前端项⽬
微前端是⼀种多个团队通过独⽴发布功能的⽅式来共同构建现代化 web 应⽤的技术⼿段及⽅法策略。
⼀、什么是微前端
“微前端”⼀词最早在2016年提出,它将后端微服务的概念扩展到前端世界。简单来说,就是将⼤型的wen渐进式项⽬拆分成⼀个个⼩型⼯程,即微应⽤。每个微应⽤都能独⽴开发、部署、运⾏,然后由主应⽤将所有微应⽤整合在⼀起,实现所有页⾯的展⽰和交互。
⼆、为什么⽤微前端
在开发toB项⽬尤其是中后台项⽬时,以往的趋势都是搭建⼀个功能强⼤且完善的单页应⽤程序。但是中后台项⽬⽣命周期较长(⼀般3年+),这期间由于参与的⼈员、团队的增多、变迁,单页应⽤就会从⼀个普通应⽤演变成⼀个巨⽯应⽤。随之⽽来就导致项⽬⽆法维护尾⼤不掉。这类问题在企业级 Web 应⽤中尤其常见。
巨⽯应⽤往往有以下⼏个弊端:
项⽬引⽤包太多,打包上线巨慢;
⾸屏请求的接⼝越来越多,页⾯资源繁杂,导致⾸屏加载缓慢;
项⽬初期野蛮⽣长过度,代码难以维护,产品迭代举步维艰;
toB应⽤对于客户定制化需求很难满⾜;
巨⽯应⽤发展后期都逃不过重构这⼀条路,⼀旦重构导致整个项⽬功能停⽌更新迭代,对公司发展来说成本巨⼤。
微前端架构旨在解决单体应⽤长时间迭代后,导致不可维护的问题。其具备以下⼏个核⼼价值:
技术栈⽆关
主框架不限制接⼊应⽤的技术栈,微应⽤具备完全⾃主权
独⽴开发、独⽴部署
微应⽤仓库独⽴,前后端可独⽴开发,部署完成后主框架⾃动完成同步更新
增量升级
在⾯对各种复杂场景时,我们通常很难对⼀个已经存在的系统做全量的技术栈升级或重构,⽽微前端是⼀种⾮常好的实施渐进式重构的⼿段和策略
独⽴运⾏时
每个微应⽤之间状态隔离,运⾏时状态不共享
这其中的技术难点就是如何将不同技术栈的微应⽤整合在⼀起,保持微应⽤独⽴运⾏的同时⼜能实现跨应⽤通信。微前端框架提供了⼀套简单、⽆痛的微前端架构解决⽅案。下⾯我们⼀步⼀步讲解使⽤qiankun如何从零开始搭建微前端项⽬。
三、主应⽤
主应⽤与技术栈⽆关,我们可以使⽤Vue、React、Angular、JQuery甚⾄ES5语法进⾏搭建。主应⽤的⽬的如下:
1. 注册微应⽤;
2. 为每个微应⽤提供dom容器;
3. 启动主应⽤;
下⾯我们以vue为主应⽤⼀步⼀步进⾏讲解,先使⽤vue-cli3构建项⽬。
3.1 安装qiankun
$ yarn add qiankun
3.2 注册微应⽤
在⼊⼝⽂件main.js中添加如下代码:
import { registerMicroApps, start, setDefaultMountApp } from'qiankun'
/**
* step1 初始化应⽤
*/
new Vue({
render: h => h(App),
}).$mount('#mainapp-container')
/**
* step2 注册微应⽤
*/
registerMicroApps(
[
{
name: 'vue-app',
entry: '//localhost:8101',
container: '#subapp-container',
activeRule: '/vue',
},
{
name: 'react-app',
entry: '//localhost:8102',
container: '#subapp-container',
activeRule: '/react17',
},
],
{
beforeMount: [
app => {
console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
},
],
afterUnmount: [
app => {
console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
},
]
}
)前端跟后端哪个就业难
/**
* step3 设置默认进⼊微应⽤
*/
setDefaultMountApp('/vue')
/**
* step4 启动
*/
start()
注意step1中我们将主应⽤挂载到⾃⼰的dom容器#mainapp-container中,step2中微应⽤运⾏的容器#subapp-container我们定义在主应⽤的根组件App.vue中。
3.3 启动配置
所有的微应⽤都保存在根⽬录projects中,之后会讲解如何配置不同技术栈的微应⽤。等所有微应⽤都配置好后,就需要⼀键启动。$ yarn add npm-run-all
安装npm-run-all⽀持同时运⾏多个npm项⽬,然后修改package.json配置:
"scripts": {
"mainapp:install": "npm-run-all --parallel install:*",
"mainapp:start": "npm-run-all --parallel start:*",
"install:main": "yarn",
"start:main": "yarn start",
"install:vue": "cd projects/vue && yarn",
"start:vue": "cd projects/vue && yarn start",
"install:react17": "cd projects/react17 && yarn",
"start:react17": "cd projects/react17 && yarn start",
"start": "vue-cli-service serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
按照下⾯命令就能启动微前端项⽬:
$ yarn install
$ yarn mainapp:install
$ yarn mainapp:start
四、微应⽤
微应⽤不⽤额外安装qiankun即可接⼊主应⽤,⼤致分为下⾯⼏个步骤:
1. ⼊⼝js⽂件平级⽬录下增加public-path.js⽂件;
2. ⼊⼝js⽂件中引⼊public-path.js,修改并导出qiankun定义的三个钩⼦函数:bootstrap、mount、unmount;
3. 使⽤history路由,并且路由base值要和activeRule匹配规则保持⼀致;
4. 修改webpack配置,允许开发环境跨域及umd打包;
下⾯我们以react17+typescript作为技术栈构建微应⽤,⼀步⼀步进⾏讲解,⾸先使⽤create-react-app构建项⽬。
$ yarn create react-app react17 --template typescript
4.1 在src下增加public-path.js
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
注意注释掉的那⼀⾏代码必须加上,否则项⽬有eslint报错⽆法启动。
4.2 修改⼊⼝⽂件
修改src下index.tsx⽂件
import './public-path';
function render(props: any) {
const { container } = props;
}
// 单独启动
if (!(window as any).__POWERED_BY_QIANKUN__) {
render({});
}
// 修改、导出微应⽤钩⼦
export async function bootstrap() {
console.log('[react16] react app bootstraped');
}
export async function mount(props: any) {
console.log('[react16] props from main framework', props);
render(props);
}
export async function unmount(props: any) {
const { container } = props;
ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root'));
}
在组件内部配置路由时,使⽤history路由并且设置base值。
import React, { lazy, Suspense } from'react'
import { BrowserRouter as Router, Link, Route, Switch } from'react-router-dom'
const Home = lazy(() => import('../components/Home'))
const About = lazy(() => import('../components/About'))
const Layout: React.FC = () => {
return (
<Router basename={(window as any).__POWERED_BY_QIANKUN__ ? '/react17' : '/'}>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Suspense fallback={null}>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Switch>
</Suspense>
</Router>
)
}
export default Layout
4.4 配置webpack
安装插件@rescripts/cli
yarn add @rescripts/cli
在根⽬录下新增.rescriptsrc.js⽂件:
const { name } = require('./package');
webpack: config => {
config.output.library = `${name}-[name]`;
config.output.libraryTarget = 'umd';
config.output.jsonpFunction = `webpackJsonp_${name}`;
config.output.globalObject = 'window';
return config;
},
devServer: _ => {
const config = _;
config.headers = {
'Access-Control-Allow-Origin': '*',
};
config.historyApiFallback = true;
config.hot = false;
config.watchContentBase = false;
config.liveReload = false;
return config;
},
};
修改package.json启动⽂件:
-
"start": "react-scripts start",
+ "start": "rescripts start",
- "build": "react-scripts build",
+ "build": "rescripts build",
- "test": "react-scripts test",
+ "test": "rescripts test",
- "eject": "react-scripts eject"
4.5 启动端⼝配置
根⽬录下增加.env配置端⼝信息,保证微应⽤启动端⼝和主应⽤中注册的该微应⽤的⼊⼝entry保持⼀致。SKIP_PREFLIGHT_CHECK=true
BROWSER=none
PORT=8102
WDS_SOCKET_PORT=8102
到这⾥以React作为技术栈的微应⽤就配置成功了。Vue、Angular所需要的配置都⼀样,实现起来⼤同⼩异。完整微前端项⽬代码在上。
当然⼀个优秀的项⽬最终是要服务于产品,为客户提供便利为公司带来价值,不能为了炫技⽽本末倒置。微前端项⽬启动初期,需要和后端协商好如何依据业务模块进⾏拆分确定接⼝url,后期上线部署也需要运维⽀持。这样才能保证项⽬能健壮发展下去。
系列相关⽂章:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论