人机交互爱好者的随笔

0%

2020 年初,一场新的全球大流行疫情的爆发,可能永久的改变了我们的生活。起初,我们以为它会像非典那样,仅仅是时代的一朵浪花,转瞬即逝;但随着病毒不断变异,越来越强的传染性给人类社会的未来蒙上了一层阴影,也将 08 年次贷危机隐隐揭露的让人恐慌的可能狠狠的拍在了所有人的脸上。

阅读全文 »

上文中,笔者介绍了 Monorepo 这一项目组织方式、Lerna 这个用于便捷管理 monorepo 项目的工具以及它们在开源项目中的应用。那这一次就来聊聊 Monorepo 如何在 WebApp 中落地。

阅读全文 »

2020 年 4 月 16 日,前端业内最知名的框架之一——vue——发布了大版本 3.0 的第一个 beta 版本,增加了许多新特性、新功能,并进一步对性能进行了优化,让我们来看看都有哪些激动人心的变化

阅读全文 »

上文中提到了一种基于 mobx 的 React 组件设计方案:它将状态与逻辑剥离到 mobx 中,并通过工厂函数将它们与组件进行关联、注入,通过分层解决了前端组件基于UI进行测试的脆弱性组件生命周期被自动调用影响测试结果的问题。但这种设计模式同样产生了一些新的问题,在本篇中,我们将逐一尝试解决。

阅读全文 »

About

Monorepo

Monorepo 是一种项目的组织方式,许多开源项目均采用这种组织方式,如create-react-appreact-routerbabel,基本的项目结构如下

1
2
3
4
5
6
├── packages
| ├── pkg1
| | ├── package.json
| ├── pkg2
| | ├── package.json
├── package.json

Lerna

Lerna是一个 JavaScript 下用于管理 Monorepo 项目的工具。它通过配置文件以及 cli 命令的方式使用,优化了使用 git 和 npm 管理多包存储库的工作流。

Github Action

GithubAction 是 github 内置的一种 CI/CD 工具,它不需要项目安装 TravisCI、CircleCI 等 CI 工具即可使用 CI 功能。最重要的是:它对于不论是 private 还是 public 项目都是免费的。
GithubAction 有一个非常强大的功能——官方市场,在上面你可以搜索到其他开发者提交的 action,并在自己的 ci 脚本中使用。

Setup

创建基本项目结构

1
2
3
4
5
6
7
8
mkdir my-project && cd my-project
npm init -y # 创建根package.json
mkdir packages
mkdir packages/pkg1 && cd packages/pkg1 && npm init -y # 创建pkg1子项目
cd ../../
mkdir packages/pkg2 && cd packages/pkg2 && npm init -y # 创建pkg2子项目
cd ../../
yarn add -D lerna

初始化并配置 lerna

1
2
npx lerna init # 根目录生成 lerna.json 配置文件
vim lerna.json

修改 lerna.json 内容至如下

1
2
3
4
5
6
{
"packages": ["packages/*"],
"npmClient": "yarn", // 选择使用npm工具,默认为npm
"useWorkspaces": true, // 若npmClient设置为yarn,启用yarn的workspaces机制
"version": "0.0.0"
}

修改根 package.json

1
2
3
4
5
6
7
8
{
// ...
"private": true, // 使用workspaces机制必须将private设置为true
"workspaces": {
// 设置yarn workspaces包含的子项目
"packages": ["packages/*"]
}
}

react-router这样的项目,它的多个子项目分别以react-routerreact-router-domreact-router-config等名称单独发布到了 npm。而在子项目的实现代码中,难免出现互相依赖的,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// react-router/packages/react-router-config/modules/renderRoutes.js
import { Switch, Route } from "react-router";

function renderRoutes(routes, extraProps = {}, switchProps = {}) {
return routes ? (

{routes.map((route, i) => (

key={route.key || i}
path={route.path}
exact={route.exact}
strict={route.strict}
render={props =>
route.render ? (
route.render({ ...props, ...extraProps, route: route })
) : (

)
}
/>
))}
</Switch>
) : null;
}

此时需要将子项目间的依赖关系添加到所在项目package.jsondependenciesdevDependencies中,使得 lerna 在创建symlink时候可以将本地项目与node_modules下的依赖关联起来,否则会导致执行 build、test 等操作时报错。
lerna 在创建 symlink 时是通过npm/yarn提供的lin功能实现的。这样,在本地开发时,任何子项目内的改动都会同步到设置了对应 symlink 的其他子项目 node_modules 下

使 lerna 生效

执行以下命令即可使 lerna 的基本功能正常工作:

1
2
npx lerna bootstrap # 为各个子项目安装依赖,并根据package.json中的依赖配置创建symlink
npx lerna list # 查看本项目识别到的子项目名,以确定bootstrap操作是否成功

通过 lerna 批量操作

若要对所有子项目进行打包,可以通过lerna run < script >执行各个子项目 package.json 下的 script 命令,如 build、test。
若要清除所有子项目的node_modules,可以执行lerna clean命令。

创建 CI

Github Action 的 CI 采用YAML格式的文件进行配置,并将配置文件存放在./.github/workflows下。最基本的 ci 配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
name: CI

on: [push]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Run a one-line script
run: echo Hello, world!
- name: Run a multi-line script
run: |
echo Add other actions to build,
echo test, and deploy your project.

将配置文件修改为通过 lerna 执行 build、test,以验证项目的可用性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
name: CI

on: [push]

jobs:
test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: setup
run: |
yarn
npx lerna bootstrap
- name: build
run: npx lerna run build
- name: test
run: npx lerna run test

功能完善

待续…

项目参考

Tan90Qian/leetcode:这是笔者看书时候顺手练习创建的项目,里面包含了 Monorepo、Lerna、Typescript、基于 rollup 的打包、基于 Jest 的单元测试、CI 等要素。

文章引用

  1. Monorepo——大型前端项目的代码管理方式
  2. Monorepo 是什么,为什么大家都在用?
  3. Lerna 中文教程详解
  4. 使用 lerna 管理大型前端项目
  5. Automating your workflow with GitHub Actions
  6. GitHub Actions 入门教程 - 阮一峰

React 是目前最流行的 Web 前端 UI 框架之一,借助其创造的 JSX 语法,可以将前端项目以组件为单位进行构建。而蓬勃发展的社区也对如何设计 React 下的组件进行了大量的讨论与实践,甚至还有专门的参考书。今天,笔者将列举自己接触到的 React 组件设计模式。

主流的 React 组件设计模式

在 React v16.7 之前,大多数 React 组件都是基于 Class 的。典型的 React Class 组件结构如下:

阅读全文 »