006 使用 Umi 的微生成器快速助力业务交付

本文涉及的产品
简介: 006 使用 Umi 的微生成器快速助力业务交付

image.png


在项目中的最好的提效方案就是复用,比如将常用模块封装,给到其他页面复用,就是我们经常提到的组件(复制使用的情况)。将项目中的方案进行封装,给到不同的项目中使用,就是我们说到的脚手架。而这些好的组件或者脚手架,要快速的被其他人员使用,就要用到生成器。简单的理解就是使用脚本帮你复制了一份,像很多项目中经常会执行的新建项目就是生成器的一种能力体现。

npx create-xxx appName
复制代码


Umi 中将生成器的目标定的更加细化,不是提供一整个脚手架,而是提供脚手架中的某一个方案,所以取名微生成器,其实灵感来源是 modern.js 的微生成器。

Umi 的微生成器有统一的命令入口调用:

umi generate (alias: umi g) [type]
复制代码



内置微生成器列表

页面生成器

比如快速生成一个初始的简单页面,可以使用一下方法方式。

交互式输入页面名称和文件生成方式:

$ umi g page
? What is the name of page? › mypage
? How dou you want page files to be created? › - Use arrow-keys. Return to submit.
❯   mypage/index.{tsx,less}
    mypage.{tsx,less}
复制代码


或者直接指明页面名称直接生成:

$ umi g page foo
Write: src/pages/foo.tsx
Write: src/pages/foo.less
复制代码


如果你的项目风格是使用目录方式,比如基于 Umi 构建的前端框架 alita 中,就只有目录下的 index 文件才会被识别成路由,所以就可以采用以目录方式生成页面,目录下为页面的组件和样式文件:

$ umi g page bar --dir
Write: src/pages/bar/index.less
Write: src/pages/bar/index.tsx
复制代码


批量生成多个页面:

$ umi g page  page1  page2   a/nested/page3
info  - @local
Write: src/pages/page1.tsx
Write: src/pages/page1.less
Write: src/pages/page2.tsx
Write: src/pages/page2.less
Write: src/pages/a/nested/page3.tsx
Write: src/pages/a/nested/page3.less
复制代码

剩余内置微生成器清单



自定义微生成器

当然官方提供的基本的微生成器,肯定无法满足我们特定的项目需求,我们可以通过简单的调用和约定来自定义微生成器。 比如官方提供的 g page 只生成了简单的页面。

import React from 'react';
import styles from './abc.less';
export default function Page() {
  return (
    <div>
      <h1 className={styles.title}>Page abc</h1>
    </div>
  );
}
复制代码


而我们的项目中需要的初始化页面内容可能会更加复杂,要带有请求等页面模版:

import React from 'react';
import type { FC } from 'react';
import { useRequest } from 'umi';
import { query } from './service';
import styles from './index.less';
interface HomePageProps {}
const HomePage: FC<HomePageProps> = () => {
  const { data } = useRequest(query);
  return <div className={styles.center}>Hello {data?.text}</div>;
};
export default HomePage;
复制代码

以上模版中提到的能力和内容会在后续的文章中体现,这里仅仅作为一个展示


要自定义微生成器,只需要调用 generateFile 指定模版存放的路径,指定需要替换的模版中的变量,既可。

generateFile({
  path: join(__dirname, '../../../templates/generate/page'),
  target: join(api.paths.absPagesPath, name),
  data: {
    color: randomColor(),
    name: lodash.upperFirst(name),
  },
});
复制代码


generateFile 的目的是让开发人员在编写微生成器的时候,将精力更加聚焦于目标文件生成时的模版维护工作中。 不许花费而外的心力,去学习微生成器的功能开发。

比如我们生成上面的页面,用到的模版如下:

import React from 'react';
import type { FC } from 'react';
import { useRequest } from 'alita';
import { query } from './service';
import styles from './index.less';
interface {{{ name }}}PageProps {}
const {{{ name }}}Page: FC<{{{ name }}}PageProps> = () => {
  const { data } = useRequest(query);
  return <div className={styles.center}>Hello {data?.text}</div>;
};
export default {{{ name }}}Page;
复制代码


在为用户提供微生成器时,有一些数据需要用户提供给我们,会有一些交互式的问答功能需要实现,在微生成器中,我们只需要关注问题本身。


Umi 中提供了两种问答的手段,(底层是同一套方案)第一种就是在插件中使用的,配合上面提到的 generateFile 使用

import { prompts } from '@umijs/utils'; 
if (!name) {
  const response = await prompts({
    type: 'text',
    name: 'name',
    message: 'What is the name of page?',
  });
  name = response.name;
}
复制代码



使用 Umi 的基础微生成器工具

第二种方式就是可以脱离 Umi 的声明周期使用的,是一个基础的生成模块,你可以将它用在任意的项目中,比如我们实现一个脚手架的生成器。

const appPrompts = [
  {
    name: 'name',
    type: 'text',
    message: `What's the app name?`,
    default: name,
  },
  {
    name: 'author',
    type: 'text',
    message: `What's your name?`,
  },
];
const generator = new BaseGenerator({
  path: join(__dirname, '..', 'templates', args.plugin ? 'plugin' : 'app'),
  target: name ? join(cwd, name) : cwd,
  data:{
        version: require('../package').version,
        npmClient,
        registry,
      },
  questions: appPrompts,
});
await generator.run();
复制代码


我们的关注点就只在模版文件(templates)和问题(questions)这两点上,如果模版有修改或者问题有变更,我们也只需修改这两个地方,不用耗费大量的心力去处理当前复制和写入的是文件还是文件夹,目标文件夹是否为空等文件写入边界问题。

以上提供的只是基本的模块使用方式,后续的课程中我们会展示以上代码的完整场景和实现。


感谢阅读,今天教程仓库中没写一行代码,就不放源码归档链接了。今天更多的是微生成器的介绍,实际应用场景涉及整个最佳实践方案,我们会在后续的文章中一一体现。

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
5天前
|
监控 前端开发 测试技术
前端研发流程的深入解析:从构思到交付
前端研发流程的深入解析:从构思到交付
72 0
|
5天前
|
前端开发 JavaScript API
微前端:一种新型的前端架构方法
微前端:一种新型的前端架构方法
99 0
|
前端开发 JavaScript 数据可视化
标准微前端架构在蚂蚁的落地实践
蚂蚁金服前端技术专家有知在 D2 带来以“标准微前端架构在蚂蚁的落地实践”为题的演讲。首先提出了微前端的场景域在蚂蚁落地时常遇到的问题,然后详细介绍了微前端的定义,最后通过实施一个标准的微前端架构,提出面临的技术决策以及需要处理的技术细节,经过在蚂蚁的实践证明,微前端是一个具有优势的方案。
14869 0
标准微前端架构在蚂蚁的落地实践
|
5天前
|
监控 前端开发 Serverless
微前端解决方案
微前端解决方案
58 1
|
12月前
|
存储 前端开发 JavaScript
【微前端架构】AWS 上的微前端架构
【微前端架构】AWS 上的微前端架构
|
Kubernetes 安全 机器人
Lyft 微服务研发效能提升实践 | 3. 利用覆盖机制在预发环境中扩展服务网格
Lyft 微服务研发效能提升实践 | 3. 利用覆盖机制在预发环境中扩展服务网格
1202 0
Lyft 微服务研发效能提升实践 | 3. 利用覆盖机制在预发环境中扩展服务网格
|
存储 IDE 测试技术
Lyft 微服务研发效能提升实践 | 2. 优化快速本地开发
Lyft 微服务研发效能提升实践 | 2. 优化快速本地开发
117 0
Lyft 微服务研发效能提升实践 | 2. 优化快速本地开发
|
前端开发 JavaScript 容器
微前端x重构实践落地总结(下)
大家好,我是海怪。最近换到了新部门,在做智能平台相关的内容。我接到的第一个任务就是把以前前端的项目重构一次。 说是重构,不如说是重写一遍。因为原来的项目是 ant-design-vue + vue 全家桶,要切换成 ant-design + ant-design-pro + react 全家桶。 更让人头疼的是,产品经理并不会让我们有大把大把时间专门搞重构,我们要边重构边做需求。在这样的挑战下,我想到了微前端解决方案,下面就跟大家分享这次 微前端在重构上的落地实践吧。
微前端x重构实践落地总结(下)
|
前端开发 JavaScript 容器
微前端x重构实践落地总结(上)
大家好,我是海怪。最近换到了新部门,在做智能平台相关的内容。我接到的第一个任务就是把以前前端的项目重构一次。 说是重构,不如说是重写一遍。因为原来的项目是 ant-design-vue + vue 全家桶,要切换成 ant-design + ant-design-pro + react 全家桶。 更让人头疼的是,产品经理并不会让我们有大把大把时间专门搞重构,我们要边重构边做需求。在这样的挑战下,我想到了微前端解决方案,下面就跟大家分享这次 微前端在重构上的落地实践吧。
微前端x重构实践落地总结(上)
|
移动开发 前端开发 数据可视化
开源|优酷动态模板研发体系为分发提效30%
动态模板技术方案将客户端研发链路实现了串联,通过完备的工具化支撑体系,让开发者可以高效完成组件由原始设计稿到可运行代码的最短通路,本文将对研发体系中涉及到的核心模块就行介绍,希望对技术社区及广大开发者有一定帮助。
开源|优酷动态模板研发体系为分发提效30%