MDH 前端周刊第 46 期:Remixing React Router、Umi Blog Stack、Ladle、monorepo、pnpm - 图1
封面图:uyilman @ unsplash。

Hi,我是云谦,欢迎打开新一期的「MDH:前端周刊」,这是第 0046 期,发表于 2022/03/28。

本期主要内容有这些:

  • Remixing React Router
  • JSON 技巧
  • UMI Blog Stack
  • Ladle
  • typesVersions
  • monorepo 实践
  • pnpm 技巧

Remixing React Router

https://remix.run/blog/remixing-react-router

MDH 前端周刊第 46 期:Remixing React Router、Umi Blog Stack、Ladle、monorepo、pnpm - 图2

Remix 团队计划将 remix 的 loader 和 action 能力带入 react-router,在 loader 中定义初始数据,在 action 中处理 form 提交数据,通过 useLoaderData 获取数据,通过 useTransition 获取表单提交状态等。

开发者要关心的是,在 react-router 层增加两个配置项,loader 和 action,分别处理上述任务,还是非常友好的。

  1. <Route path="/" element={<App />} loader={} action={} />

带来的好处是初始请求更快(见下图),以及处理数据提交时更优雅,无需 useEffect,无需处理 error/success 状态,无需 cache,无需返回 clean 函数等等。

MDH 前端周刊第 46 期:Remixing React Router、Umi Blog Stack、Ladle、monorepo、pnpm - 图3

但真实项目中,直接把请求逻辑放在路由配置里是不合适的,这就需要框架的支持,比如 Remix 和 Umi。

React 18 带来了很多新特性,Suspense、React Server Components 和 Steaming 等,他们定义了如何在数据 ready 时渲染的 how 和 where,但没有定义如何做数据请求。react-router 的新数据请求方案正好弥补了这一点。

最后,还有个变更是 react-router 仓库会更名为 remix,同时包含 remix、react-router 和 history 等包。

JSON 技巧

https://dev.to/siddharthshyniben/5-secret-features-of-json-you-didnt-know-about-5bbg

直接上代码。

  1. // 正常用
  2. JSON.stringify(foo)
  3. JSON.stringify(foo, null, 2)
  4. // 空格用 lol 代替
  5. JSON.stringify(foo, null, 'lol')
  6. // 不输出 password
  7. JSON.stringify(foo, (key, value) => {
  8. if (key === 'password') return;
  9. return value;
  10. });
  11. // 只输出 name 和 age
  12. JSON.stringify(foo, ['name', 'age'])
  13. // class 到 str 的来回转换,比如用于持久化缓存
  14. class Foo {
  15. toJSON() { return 'foo' }
  16. static fromJSON(key, value) { return new Foo() }
  17. }
  18. JSON.stringify(new Foo())
  19. JSON.parse(str, Foo.fromJSON)
  20. // parse 也可以隐藏部分信息
  21. JSON.parse(str, (key, value) => {
  22. if (key === 'password') return;
  23. return value;
  24. });

UMI Blog Stack

https://next.umijs.org/docs/tutorials/blog

MDH 前端周刊第 46 期:Remixing React Router、Umi Blog Stack、Ladle、monorepo、pnpm - 图4

基于 Umi 4,手把手教你写一个基于 Serverless 的 Blog 应用,以下是技术栈。

  • Umi:框架
  • PlanetScale:MySQL 服务(免费版够用)
  • Prisma:MySQL 客户端
  • TailwindCSS:样式
  • Upstash:Redis 服务
  • Vercel:部署平台

Ladle

https://www.ladle.dev/blog/introducing-ladle/

MDH 前端周刊第 46 期:Remixing React Router、Umi Blog Stack、Ladle、monorepo、pnpm - 图5

Uber 工程师开发的 Storybook 竞品,支持 Component Story Format(CSF),可直接替换 Storybook。

Uber 有大量应用 Storybook,但由于构建性能、dev 性能、bundle 产物、测试等方面的不好表现,他们决定基于 Vite 重写了一份,性能提升如下。

MDH 前端周刊第 46 期:Remixing React Router、Umi Blog Stack、Ladle、monorepo、pnpm - 图6

有需要的可通过以下命令 1 分钟上手体验。

  1. $ mkdir my-ladle
  2. $ cd my-ladle
  3. $ pnpm init -y
  4. $ pnpm i @ladle/react react react-dom
  5. $ mkdir src
  6. $ echo "export const World = () => <p>Hey</p>;" > $ src/hello.stories.tsx
  7. $ pnpm ladle serve

MDH 前端周刊第 46 期:Remixing React Router、Umi Blog Stack、Ladle、monorepo、pnpm - 图7

typesVersions

https://antfu.me/notes#types-for-sub-modules

一个小 Tip。

  1. + dist
  2. - index.js
  3. - index.d.ts
  4. - foo.js
  5. - foo.d.ts
  6. + src
  7. - index.ts
  8. - foo.ts
  9. - package.json ("name": "bar")

比如上述这个 name 为 bar 的 npm 包,发布之后希望可以通过 import(‘bar’) 和 import(‘bar/foo’) 分别访问到 dist 下的两个文件,同时类型提示准确。

由于根目录下没有 foo.js 和 foo.d.ts,需要做隐射。package.json 中的 exports 属性可以做 export 的隐射,但不会覆盖类型;类型隐射可通过 typesVersions 配置实现。

最终配置如下。

  1. {
  2. "exports": {
  3. ".": "./dist/index.js",
  4. "./foo": "./dist/foo.js"
  5. },
  6. "typesVersions": {
  7. "*": {
  8. "*": [
  9. "./dist/*"
  10. ]
  11. }
  12. }
  13. }

monorepo 实践

https://www.yuque.com/docs/share/69ee97ff-42cc-46cf-a409-31967339a9cf

MDH 前端周刊第 46 期:Remixing React Router、Umi Blog Stack、Ladle、monorepo、pnpm - 图8

Umi 周会上社区同学 yingci 的分享,基于 pnpm、turborepo、mfsu、qiankun 等的大型项目 monorepo 实践,一个 repo 包含了 60+ 项目。

pnpm 技巧

https://twitter.com/jaredpalmer/status/1506634640509083649

Turborepo 作者分享了 5 个 pnpm 技巧。

1、通过 —filter 参数指定安装 workspace 下某个 package 的依赖,比如 pnpm i --filter my-app...
2、通过 package.json 中的 peerDependencyRules.allowedVersions 配置可通过 peerDependencies

  1. {
  2. "pnpm": {
  3. "peerDependencies": {
  4. "allowedVersions": { "react": "17" }
  5. }
  6. }
  7. }

3、通过 pnpm env use 可切换 pnpm 使用的 node 版本,无需 nvm、fnm 或volta,比如 pnpm env use --global 16
4、pnpm 可作为 server 运行,比如 pnpm server starthttps://glitch.com/ 就基于此
5、通过 .pnpmfile.cjs 定义 hooks,可在安装前动态修改依赖的 package.json

发布

以下是上周社区的重要发布。

周刊一锅端

小结

以上就是本期我的分享。如果需要文内资讯的链接,请点击「查看原文」进入语雀查看。持续更新不易,如果你喜欢本周刊,请转发给你的朋友,告诉他们到这里来订阅,这是对我最大的帮助。下期见!

MDH,让开发者有笑容 :)