Fun Init 自定义模板

首先介绍下在本文出现的几个比较重要的概念:

函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息 参考
Fun: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API 网关、日志服务等资源。它通过一个资源配置文件(template.yml),协助您进行开发、构建、部署操作。Fun 的更多文档 参考
2.0 版本的 Fun,在部署这一块做了很多努力,并提供了比较完善的功能,能够做到将云资源方便、平滑地部署到云端。但该版本,在本地开发上的体验,还有较多的工作要做。于是,我们决定推出 Fun Init 弥补这一处短板。
Fun Init: Fun Init 作为 Fun 的一个子命令存在,只要 Fun 的版本大于等于 2.7.0,即可以直接通过 fun init 命令使用。Fun Init 工具可以根据指定的模板快速的创建函数计算应用,快速体验和开发函数计算相关业务。官方会提供常用的模板,用户也可以自定自己的模板。

模板项目目录结构

helloworld                  ① 模板项目根目录
├── metadata.json           ② 模板项目配置文件
└── {{ projectName }}       ③ 模板根目录
    ├── index.js
    └── template.yml

说明:

  • ① 模板项目目录。如果模板项目需要上传到 github,则模板项目名称就是仓库名称
  • ② 模板项目配置文件。模板项目配置文件不是必须的,支持两种类型的文件:metadata.json 和 metadata.js
  • ③ 模板根目录。fun init 会从模板根目录开始渲染输出,该目录必须是一个模板表达式。projectName 模板变量来自 fun init --name foo--name 参数。绝大多数场景,模板根目录叫 {{ projectName }} 即可

模板项目配置文件

JSON 风格配置文件

{
    "name": "helloworld",                                   ① 模板项目名称
    "description": "Print hello world",                     ② 模板项目描述
    "userPrompt": [                                         ③ 提示输入变量(显式变量)
         {
             "type": "input",                               ④ 提示输入类型
             "name": "foo",                                 ⑤ 模板变量名
             "message": "Please input foo?",                ⑥ 提示信息
             "default": "{{ projectName }}"                 ⑦ 模板变量默认值
            
         },
         {
             "type": "list",
             "name": "bar",
             "message": "Please select bar?",
             "default": "option1",
             "choices": ["option1", "option2", "option3"]
         }
    ],
    "vars": {                                               ⑧ 隐式变量
        "baz": "{{ projectName }}"
    },
    "copyOnlyPaths": [ "test" ]                          ⑨ 设置某些目录和文件不需要渲染,只是简单的拷贝 
}

说明:

  • ① 模板项目名称。对模板项目简单介绍
  • ② 模板项目描述。对模板项目详细介绍
  • ③ 提示输入变量(显式变量)。在用户初始化模板项目的时候,会显式提示用户输入模板变量,底层用的是 Inquirer,④、⑤、⑥ 和 ⑦ 详情可以参考: Inquirer 文档。当通过 fun init --var foo=xxx 设置了 foo 变量后,则不会再提示用户输入 foo 变量的值,其他没有设置过的显式变量仍然提示输入
  • ⑧ 隐式变量。相对显式变量而言,隐式变量不提示用户输入,可以通过 fun init --var baz=xxx 覆盖配置文件的隐式变量,如果显式和隐式有相同的变量,则该变量不会再提示用户输入,但是这种方式是不推荐使用的,也不要依赖此特性,即显式变量和隐式变量不要有交叉
  • ⑨ 设置某些目录和文件不需要渲染,只是简单的拷贝。比如一些二进制文件。格式和 gitignore 是一样的,具体可以参考:gitignore 规范
  • 配置文件也可以使用变量,其中,projectName 模板变量来自 fun init --name foo--name 参数,还可以使用 fun init --var abc=xxx 中的 abc 变量,但是,如果你不通过 --varabc 变量,在渲染配置文件的时候,可能报变量未定义的错误,可以在使用的时候先判断一下,如:{{ typeof x === 'undefined' ? '' : x}}

JS 风格配置文件

module.exports = {
    name: 'helloworld',                                   ① 模板项目名称
    description: 'Print hello world',                     ② 模板项目描述
    userPrompt: [                                         ③ 提示输入变量(显式变量)
         {
             type: 'input',                               ④ 提示输入类型
             name: 'foo',                                 ⑤ 模板变量名称
             message: 'Please input foo?',                ⑥ 提示信息
             'default': '{{ projectName }}'               ⑦ 模板变量默认值
            
         },
         {
             type: 'list',
             name: 'bar',
             message: 'Please select bar?',
             'default': 'option1',
             choices: ['option1', 'option2', 'option3'],
             when: (answer) => {                          ⑩ 当前变量是否需要提示 
                 return true
             }
         }
    ],
    vars: {                                               ⑧ 隐式变量
        baz: '{{ projectName }}'
    },
    copyOnlyPaths: [ 'test' ]                          ⑨ 设置某些目录和文件不需要渲染,只是简单的拷贝 

};

说明:

  • ① ~ ⑨ 与前面 JSON 风格配置文件是一样的,但是 JSON 风格配置文件不支持配置函数类型的值,而 JS 风格配置文件是支持。
  • ⑩ 当前变量是否需要提示。可以根据用户前面输入的情况决定当前变量是否需要提示,具体可以参考: Inquirer 文档

两种风格的配置文件各有各的优缺点,JSON 风格比较简洁,但是不支持函数;JS 风格略微复杂些,但是支持函数。如果模板项目需要很复杂的提示输入,可以选择 JS 风格。

支持模板语法的位置

  • 模板项目配置文件
  • 模板根目录
  • 模板根目录下的子目录名称(支持多层嵌套)
  • 模板根目录下的文件名称(支持多层嵌套)
  • 模板根目录下的文件内容(支持多层嵌套)

模板变量设置方式

有三种种方式设置模板变量:

  • 参数设置。通过 -V,--var 参数设置模板变量
  • 显式变量。配置文件中的 userPrompt
  • 隐式变量。配置文件中的 vars

优先级:参数设置 > 隐式变量。
优先级:显式变量 > 隐式变量。

说明:参数设置和显示变量互斥出现,优先级比较没有意义。

模板语法

模板渲染底层是基于 lodash ,详情请参考:lodash 文档

主要用法:

  1. 模板表达式
     模板表达式的正则表达式规则:/{{([\s\S]+?)}}/g ,以 {{ 开头,}} 结尾,中间可以是任意字符。
# 假设 foo = 'bar'
hello {{ foo }}!             输出:hello bar!
{{ foo === 'bar' }}          输出:true
{{ _.isEmpty(foo) }}         输出:false
{{ foo ? foo :'unknown' }}   输出:bar

说明:_ 是 lodash 对象。

  1. 模板代码
    模板代码的正则表达式规则:/<%([\s\S]+?)%>/g ,以 <% 开头,%> 结尾,中间可以是任意字符。
<% if (foo === 'bar') { %> xxxxxxxxx <% } %>
<% _.forEach(users, function(user) { %><li>{{ user }}</li><% }); %>

小结

自定义模板,支持通过配置文件定义渲染规则,模板引擎根据渲染规则渲染模板项目。其中,模板引擎支持模板表达式和模板代码,我们可以通过命令行参数和提示输入方式传递模板变量。

相关文章

上一篇:比心陪练引入阿里云数据库,整体IT成本降幅达40%


下一篇:WebIDE 使用指南