编写vue-cli远程Preset

Posted LiuJun2Son

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写vue-cli远程Preset相关的知识,希望对你有一定的参考价值。

1.什么是 vue-cli 插件?

Vue CLI 使用了一套基于插件的架构。如果你查阅一个新创建项目的 package.json,就会发现依赖都是以 @vue/cli-plugin- 开头的。插件可以修改 webpack 的内部配置,也可以向 vue-cli-service 注入命令。在项目创建的过程中,绝大部分列出的特性都是通过插件来实现的。

基于插件的架构使得 Vue CLI 灵活且可扩展。如果你对开发一个插件感兴趣,请翻阅插件开发指南

提示

你可以通过 vue ui 命令使用 GUI 安装和管理插件。

下面plugins里面就是常用的vue-cli 插件:


  "useConfigFiles": true,
  "plugins": 
    "@vue/cli-plugin-babel": ,
    "@vue/cli-plugin-eslint": 
      "config": "standard",
      "lintOn": [
        "save"
      ]
    ,
    "@vue/cli-plugin-unit-mocha": 
  ,
  ....
  ....
  ....  

@vue/cli-plugin-babel : 给项目添加babel的配置、 依赖 和 对应的代码

@vue/cli-plugin-router: 给项目添加router的配置、依赖 和 集成到项目的案例代码

编写一个独立的vue-cli插件:

https://cli.vuejs.org/zh/dev-guide/plugin-dev.html#cli-%E6%8F%92%E4%BB%B6

CLI 插件是一个可以为 @vue/cli 项目添加额外特性的 npm 包。它应该始终包含一个 Service 插件作为其主要导出,且可选的包含一个 Generator 和一个 Prompt 文件

一个典型的 CLI 插件的目录结构看起来是这样的:

├── README.md
├── generator.js  # generator (可选)
├── prompts.js    # prompt 文件 (可选)
├── index.js      # service 插件
└── package.json

2. 什么是vue-cli 的Preset?

vue create新建项目时保存的Preset :

一个 Vue CLI preset 是一个包含创建新项目所需预定义选项和插件的 JSON 对象,让用户无需在命令提示中选择它们( 一个preset选项可以自定义 vue create 新建项目的目录结构,项目的依赖,项目的配置等等 )

vue create 过程中保存的 preset 会被放在你的 home 目录下的一个配置文件中 (~/.vuerc)。你可以通过直接编辑这个文件来调整、添加、删除保存好的 preset。

window 系统电脑的 .vuerc文件 在 C:\\Users\\电脑名称\\ .vuerc

这里有一个本地 preset 的示例:


  "useConfigFiles": true,
  "cssPreprocessor": "sass",
  "plugins": 
    "@vue/cli-plugin-babel": ,
    "@vue/cli-plugin-eslint": 
      "config": "airbnb",
      "lintOn": ["save", "commit"]
    ,
    "@vue/cli-plugin-router": ,
    "@vue/cli-plugin-vuex": 
  

Preset 的数据会被插件生成器(generator)用来生成相应的项目文件。除了上述这些字段,你也可以为集成工具添加配置:


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

这些额外的配置将会根据 useConfigFiles 的值被合并到 package.json 或相应的配置文件中。例如,当 "useConfigFiles": true 的时候,configs 的值将会被合并到 vue.config.js 中。

远程的Preset :

你可以通过发布 git repo 将一个 preset 分享给其他开发者。这个 repo 应该包含以下文件:

  • preset.json: 包含 preset 数据的主要文件(必需)。
  • generator.js: 一个可以注入或是修改项目中文件的 Generator
  • prompts.js 一个可以通过命令行对话为 generator 收集选项的 prompts 文件

发布 repo 后,你就可以在创建项目的时候通过 --preset 选项使用这个远程的 preset 了:

# 从 GitHub repo 使用 preset
vue create --preset username/repo my-project

GitLab 和 BitBucket 也是支持的。如果要从私有 repo 获取,请确保使用 --clone 选项:

vue create --preset gitlab:username/repo --clone my-project
vue create --preset bitbucket:username/repo --clone my-project

加载文件系统(本地)的 Preset :

当开发一个远程 preset 的时候,你必须不厌其烦的向远程 repo 发出 push 进行反复测试。为了简化这个流程,你也可以直接在本地测试 preset。如果 --preset 选项的值是一个相对或绝对文件路径,或是以 .json 结尾,则 Vue CLI 会加载本地的 preset:

# ./my-preset 应当是一个包含 preset.json 的文件夹
vue create --preset ./my-preset my-project

# 或者,直接使用当前工作目录下的 json 文件:
vue create --preset my-preset.json my-project

4.如何编写远程/本地的Preset?

1.新建 vue-cli-plugin-vbpm 项目:

vue-cli-plugin-vbpm
.
|-- generator.js
|-- preset.json
|-- prompts.js
`-- template
    |-- base-web2
    |-- mob-web4
    |-- pc-web3
    `-- vue-web1

|-- preset.json Vue CLI preset 是一个包含创建新项目所需预定义选项和插件的 JSON 对象, 默认自动安装里面的插件,依赖,配置等。
|-- prompts.js 内建插件对话,进行安装时提示用户的操作流程
|-- generator.js 允许一个向 package.json 注入额外的依赖或字段,并向项目中添加 template 中的文件。
`-- template 模板文件,里面的文件会直接被拷贝到项目中(其中有使用 ejs 模板引擎)

2.编写 Preset,prompts 和 generator

1.preset.json 文件

一个 Vue CLI preset 是一个包含创建新项目所需预定义选项和插件的 JSON 对象,让用户无需在命令提示中选择它们。当执行vue create默认会自动安装里面的插件,依赖,配置 和 vue项目的基本目录等。

preset 的示例:


  "useConfigFiles": true,
  "plugins": 
    "@vue/cli-plugin-babel": ,
    "@vue/cli-plugin-eslint": 
      "config": "standard",
      "lintOn": [
        "save"
      ]
    ,
    "@vue/cli-plugin-unit-mocha": 
  ,
  "router": true,
  "routerHistoryMode": true,
  "vuex": true,
  "cssPreprocessor": "node-sass"

plugins 是指在执行vue create新建项目的时候默认执行的vue-cli的哪些插件。

router 是指在执行vue create新建项目的时候默认是否集成router

Preset 的数据会被插件生成器(generator)用来生成相应的项目文件。例如:router:true 最终会被cli-plugin-router插件的生成器生成相应的Home.vue,About.vue,router/index.js等文件。

Preset 除了上述这些字段,你也可以为集成工具添加配置:
例如:configs 配置


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

这些额外的配置将会根据 useConfigFiles 的值被合并到 package.json 或相应的配置文件中。例如,当 "useConfigFiles": true 的时候,configs 的值将会被合并到 vue.config.js 中。

2.prompts.js 文件

是一个内建对话配置文件,进行安装时提示用户的操作流程。

type 的类型有: list checkbox input confirm

// let chalk = require('chalk')
/**
 * 本质上是一个对话配置文件
 */
module.exports = [
  
    type: 'list', // 即类型为 选择项
    name: 'project', // 名称,作为下面 generator.js导出 函数 options 的键
    message: '请选择你要生成的项目类型', // 提示语
    choices: [
       name: 'vue-web', value: 'vue-web' ,
       name: 'base-web', value: 'base-web' ,
       name: 'pc-web', value: 'pc-web' ,
       name: 'mo-web', value: 'mo-web' 
    ],
    default: 'vue-web',
  ,
  
    type: 'input', // 类型为 输入项
    name: 'projectName', // 名称,作为下面 generator.js导出 函数 options 的键
    message: '请输入项目的名称', // 提示语
    default: 'vue-web'
  ,
  // 
  //   type: 'confirm',
  //   name: 'testConfirm',
  //   // 该项目唯一安装的依赖 chalk; 目的是使用控制台输出 chalk.yellow('xxx') xxx 文字有颜色
  //   // ? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)
  //   message: `Use history mode for router? $chalk.yellow(`(Requires proper server setup for index fallback in production)`)`,
  //   description: `Using History API, the URLs don't need  '#' character.`
  // 
]

可通过安装 npm install chalk ,使用 chalk.yellow( xxx )修改控制台输出字体的颜色

3.generator.js 文件

允许一个向 package.json 注入额外的依赖或字段,并向项目中添加 template中的文件。template下的文件默认拷贝到vue项目中,拷贝时如果文件的路径和文件名相同则覆盖,否则是叠加。template下的模板文件可以定义变量,底层使用ejs模板引擎进行渲染。

/**
 * api : 一个 GeneratorAPI 实例
 * options: 可以先简单理解为 prompts 问题数组的用户输入 组合成的选项对象
 * rootOptions: 整个 preset.json 对象
 */
module.exports = (api, options, rootOptions) => 
  // options.project 可以访问上面问题数组的第一个对象的值,默认为: 'vue-web'
  console.log(`Your choice is $options.project`)
  console.log(`Your input is $options.projectName`)

  // 1.判断控制台用户的输入
  if (options.project === 'vue-web')   
    // render函数把该路径下的 ./template/vue-web1 文件拷贝到默认的vue项目中。
    // 如果文件的路径和文件名称相同的则覆盖,否则是叠加
    api.render('./template/vue-web1',  InputOptions: ...options )
  

  if (options.project === 'base-web')  
    // 2.拷贝文件并传递变量。例如:InputOptions对象中的属性/变量会覆盖掉该./template/base-web2路劲下html,js,json等文件对应的属性/变量
    api.render('./template/base-web2',  InputOptions: ...options )
  

  if (options.project === 'pc-web')  
    // 3.如果该./template/pc-web3 路径下的内容为空,会使用vue-cli中提供的默认的模板 
    api.render('./template/pc-web3',  InputOptions: ...options )
  

  if (options.project === 'mob-web')  
    // 4.如果该 render 没有执行,会使用 vue-cli 中提供的默认的模板 
    // api.render('./template/mob-web4',  InputOptions: ...options )
  

  // 3.修改 `package.json` 里的字段
  api.extendPackage(
    // 4.添加第三库的依赖
    dependencies: 
      // 'normalize.css': '^8.0.1'
    ,
    // 4.添加第三库的依赖
    devDependencies: 
      // 'normalize.css': '^8.0.1'
    ,
    // 5.添加自定义的脚本
    scripts: 
      // 'dev': 'vue-cli-service serve'
    ,
    config: 
      
    
  )


参考模板引擎的写法

https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-plugin-router/generator/template/src/App.vue

// 1.语法1: if else
<%_ if (InputOptions.project)  _%>
<script>
    // 2.语法2: 插值
console.log('<%= InputOptions.projectName %>')
    // 3.语法3: 插值
console.log('<%%= InputOptions.projectName %%>')
export default 
  name: 'App',
  components: 
    
  

</script>
<%_  else  _%>
<script>
  console.log('false')
</script>
<%_  _%>

3.使用该 preset 新建vue项目

当开发一个远程 preset 的时候,你必须不厌其烦的向远程 repo 发出 push 进行反复测试。为了简化这个流程,你也可以直接在本地测试 preset。如果 --preset 选项的值是一个相对或绝对文件路径,或是以 .json 结尾,则 Vue CLI 会加载本地的 preset:

# ./vue-cli-plugin-vbpm 应当是一个包含 preset.json 的文件夹, my-vue-project是vue项目名称
vue create --preset ./vue-cli-plugin-vbpm my-vue-project

以上是关于编写vue-cli远程Preset的主要内容,如果未能解决你的问题,请参考以下文章

vue-cli3.0 脚手架搭建项目的过程详解

源码vue-cli-dev

vue-cli 3.0脚手架搭建项目

vue-cli脚手架每行注释

vue-cli3学习整理----browserslist

vue-cli脚手架每行注释