17

0x01 契机

Vue CLI3 出来已经很长时间了,一直想研究它的插件系统却没有时间(其实是懒),刚好最近需要统一一下项目组的规范(借口),于是就有了契机。

先瞅一眼文档: CLI3插件和Preset

然后就教你怎么完全定制化一套 前端项目模板,妈妈再也不用担心我每次复制粘贴啦~

特别说明:这种 preset 不需要发布到 npm,支持 github,gitlab 及任何 git repo,甚至可以直接本地引入哦~

0x02 两个名词

插件

顾名思义,就是插件啦

  1. Vue CLI 使用了一套基于插件的架构
  2. 基于插件的架构使得 Vue CLI 灵活且可扩展

Preset

可以翻译为 预设

  • 一个包含创建新项目所需预定义选项和插件的 JSON 对象
  • 还可以理解为一套预置的项目模板,也就是本文要讲的。

使用vue create 创建过项目的小伙伴应该都记得,在创建完成后 CLI 会提示是否保存为一个 preset,这里第一条指的就是要保存的那个对象。如果你保存过,下面的命令就能看到之前保存的 preset。

cat ~/.vuerc

每个 preset.json 大概是这么个格式:

{
  "useConfigFiles": true,
  "plugins": {...},
  "configs": {
    "vue": {...},
    "postcss": {...},
    "eslintConfig": {...},
    "jest": {...}
  }
}

0x03 两者区别

插件

一个插件包含以下三个部分:

  1. Service 插件
  2. generator 文件 (可选)
  3. prompts 文件 (可选)

Preset

一个 Preset 项目包含以下三个部分

  1. preset.json
  2. generator 文件 (可选)
  3. prompts 文件 (可选)

可以看到他们两个的区别就是插件必须有一个 Service 插件(这个东西比本文讲的插件范畴要窄),而 Preset 必须包含一个 preset.json

0x04 核心概念

由于本文主要讲的是 Preset,所以剩下的核心概念看文档就好哈: 核心概念

Prompts

本质上是一个对话配置文件,vue 内置插件第三方插件 的这个文件的写法是不一样的。我们只要记得:

它是一个 Inquirer.js 的 问题 的数组

示例如下:

// 注意这段代码下面会提到
module.exports = [
  {
    type: 'list', // 即类型为 选择项
    name: 'module', // 名称,作为下面 generator 函数 options 的键
    message: '请选择你要生成的模块', // 提示语
    choices: [
      { name: 'Module1', value: 'module1' },
      { name: 'Module2', value: 'module2' },
      { name: 'Module3', value: 'module3' }
    ],
    default: 'module0',
  },
  {
    type: 'input', // 类型为 输入项
    name: 'moduleName',
    message: '请输入模块名称',
    default: 'myModule'
  }
]

当然用不到的话直接给空数组就行哈。

执行的效果大概就是这样:

20190421213756.jpg

Generator

可以叫它生成器,它导出一个函数,该函数接收三个参数

  1. api : 一个 GeneratorAPI 实例
  2. options: 可以先简单理解为 prompts 问题数组的用户输入 组合成的选项对象
  3. rootOptions: 整个 preset.json 对象
// 这些代码本质上跑在 node 上,所以都是 node 的语法
module.exports = (api, options, rootOptions) => {
  // 修改 `package.json` 里的字段
  api.extendPackage({
    scripts: {
      test: 'vue-cli-service  command'
    }
  })

  // 复制并用 ejs 渲染 `./template` 内所有的文件
  api.render('../template')

  if (options.module === 'module1') { 
    // options.module 可以访问上面问题数组的第一个对象的值,默认为: 'module0'
    console.log(`Your choice is ${options.module}`)
  }

  if (options.moduleName === 'myModule') {
    // options.moduleName 可以访问到用户从控制台输入的文字
    console.log(`Your input is ${options.moduleName}`)
  }
}

0x05 实战

上面的代码笔者准备了一个空架子:

vue-preset-template

大家可以先 clone 下来,然后跑一下感受一下效果。

直接跑笔者的仓库

vue create --preset savokiss/vue-preset-template <project-name>

clone 下来跑本地代码

vue create --preset ./vue-preset-template <project-name>

跑 git 仓库的 preset

vue create --preset direct:<git-clone-url> <project-name>

好啦,距离发布自己的 项目模板只有一步之遥啦~
那就是: 填充 template 文件夹的内容

其实直接把项目中用到的文件放进去就可以了,需要注意的是以. 开头的文件以及 scss 文件写法不太一样,具体可以看下面的参考项目

0x06 参考项目

笔者整理了两个 preset,欢迎 star 哈

  1. PC端项目模板:vue-preset-pc
  2. 移动端项目模板:vue-preset-mobile

0xFF 文档

公众号:码力全开

图片描述


savokiss
6.2k 声望4.5k 粉丝

You know nothing, SpongeBob.