femi v0.13.0
Femi
集运行时和构建时于一体的微前端脚手架
Feature
独立开发、独立部署
- 每个 App 可以单独启动,单独构建
- 提供优化的 dockerfile, 一键生成 Docker 镜像
动态加载
- 主工程与子应用解耦
- System.js 协议动态加载 App
- 便捷的封装 Parcel Api,以技术无关的形式加载 App 或者组件
集成加载
- 可选,将独立的 App 放在一个工程内进行构建打包
快速上手
安装 Femi
npm install femi -gyarn global add femi初始化主工程
femi init myFemiProject进入目录,安装依赖
cd myFemiProject && yarn启动主工程开发环境
yarn start主工程
主工程目录结构
-
|--- public // 可选,存放静态资源,此目录下的文件构建时仅复制
|--- src
|--- main.less // 可选,全局样式
|--- main.ts // 入口文件Buildin App
Buildin App 是随主工程一起编译的,使用主工程统一的 femi-scripts 进行构建,这种类型的 App 具有以下特点:
- 集成度高,环境统一,复用率高
- 不灵活,需要随主工程一起发布
推荐用于主工程的公共页面,例如登陆页、首页等
快速上手
启动某个 buildin App 的开发环境
yarn start appKey构建某个 buildin App
yarn build appKeyRuntime App
Runtime App 为独立开发、独立部署的 App,当主工程匹配到相对应的路由后,通过 System.jS 加载对应 App 的静态资源,找到 App 静态资源中提供的生命周期方法来完成对应的挂载和之后的卸载。
创建 App
femi create-app <type> <name>type 可选 react 和 vue
例如,我想创建一个使用 React App,名字为 Intro
femi create-app react Intro然后在当前运行目录下就多了 Intro App 目录啦
React App 推荐目录
|--- src
|--- common // 可选,app 内公共库
|--- history.ts // 可选,app 内的跳转
|--- components // 可选,app 内公共组件
|--- constants // 可选,app 内常量
|--- routes // app 内路由
|-- Home // 目录与嵌套路由结构相似
|-- Intro Page
|-- User
|-- Add Page
|-- Edit Page
|--- stores // 可选,app 内状态库
|--- styles // 可选,app 内公共样式
|--- types // 可选,app 内类型
|--- index.tsx // 根组件
|--- app.tsx // 入口,提供接入主工程的生命周期方法和独立启动方法Vue App 推荐目录
待补配置主工程路由
src/app.js
export default [
...
{
name: "React应用", // 名字, 随意取
key: "app-runtime-react", // key,唯一,也是 App 挂载的 dom 节点 id
path: APP_PARCEL_REACT, // 路由匹配前缀,匹配到就会分配到此 App
},
...
]子应用 dev 环境
yarn start子应用独立构建
yarn build子应用 dev 环境中以 system.js 格式输出
// Parcel 为入口名称,子应用默认已经配好
// devServer输出静态资源: localhost: [端口号]/Parcel/js/main.js
yarn build Parcel --system子应用以 system.js 格式输出
// 生成 dist 目录
yarn build Parcel --system主工程接入子应用
public/index.html
...
<head>
...
<script type="systemjs-importmap">
{
"imports": {
...
// 这个 key 即为 system 模块名字
"reactApp": "http://localhost:3001/Parcel/js/main.js"
}
}
</script>
</head>
<body>
... // 新增 dom 容器
<div id="app-parcel-react"></div>
</body>
...apps/appRuntimeReact 新建
import { bootstrapFac, mountFac, unmountFac } from "@common/appFac"
const bootstrap = bootstrapFac(() => {})
const mount = mountFac(props => {
System.import("reactApp").then((res: any) => {
res.mount(props)
})
})
const unmount = unmountFac(props => {
System.import("reactApp").then((res: any) => {
res.unmount(props)
})
})
export { bootstrap, mount, unmount }femi.json
在项目根目录中添加,主要用于指定入口和提供一些个性化配置 | 字段 | 用途 |是否必须 | 默认值 | | ----- | ----| -------: | -----: | | hash | 入口配置 |false | true | | output |出口配置 | false | true | | port | 开发环境端口 | false | 4000 | | public | 公共 | false | | | html | html 模板 | false | | | alias | 引入路径的别名 | false | "@/": ["src/"] | | proxy | 开发环境代理 | false | | | externals| 构建排除项 | false | |
entry
/* 方式一 */
{
"entry": "src/main.ts"
}
/* 方式二 */
{
"entry": {
"default": "src/main.ts",
"react": "src/apps/appReact/index.tsx"
}
}output
{
"output": {
"hash": false
}
}port
{
"port": 3001 // 非必填,指定开发环境端口
}public
{
imports: {
[key: string]: string
} // 公用模块
headTags: string // 在 html 的 head 标签内,排序在构建产物之后
bodyTags: string // 在 html 的 body 标签内,排序在构建产物之后
}html
{
title: string // 页面标签标题
favicon: string // favicon 图标
headTags: string // 在 html 的 head 标签内,排序在构建产物之后
bodyTags: string // 在 html 的 body 标签内,排序在构建产物之后
}alias
引入路径的别名
import { history } from "@/common/history"
// => import { history } from "./src/common/history"proxy
开发环境代理
{
"proxy": {
"/api": {
"target": "http://xxxxx.com/",
"changeOrigin": true
}
}
}externals
构建排除项
{
"externals": ["vue", "vue-router"]
}Parcel 使用
待补
Commitlint
目前只在主工程中默认开启
规范
git commit -m '\<type\>(\<scope\>): \<message\>.'git commit -m '\<type\>(\<scope\>): \<message\>. \<type2\>(\<scope2\>): \<message2\>.'示例
git commit -m 'fix(scale): fix something.'type
feat 功能 fix 修复 docs 文档 build 构建 style 样式 refactor 重构 test 测试 chore 构建、工具 revert 回退 ciscope: 作用范围
message: 描述,必须以英文句号.结尾
ESLint
如何配合 TypeScript: typescript-eslint
覆盖冲突规则: plugin:@typescript-eslint/recommended
Docker
大名鼎鼎的 docker 带来的好处自然无需赘述,以 docker 封装,前端可以作为一个服务进行发布,并且隔离外部运行环境。在做版本回滚时非常方便,只需要以安全的镜像起一个容器,保住研发的最后一条生命线。配合容器的概念,通过控制流量导向,可以实现灰度发布。
安装 docker
mac
brew install dockerhello world
docker run hello-world搜索镜像
docker search nginx下载镜像
docker pull nginx展示所有的镜像
docker images通过 dockerfile 构建镜像
- -t 指定镜像名
- -f 指定 dockerfile 路径
docker build ./ -f ./path/to/dockerfile -t yourImageName使用镜像 运行容器
docker run -p 80:80 -it ImageName /bin/sh连接到正在运行的容器
docker attach --sig-proxy=false ContainerNameOrIddocker exec -it ContainerNameOrId /bin/bashDockerfile
FROM: 指定基础镜像
FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>RUN: 运行指定的命令
RUN <command>COPY: 复制命令
COPY <src>... <dest>* src 为本地文件
CDN
<script src="https://cdn.jsdelivr.net/npm/systemjs/dist/system.js"></script>2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago