vue-cli模板项目

988 阅读5分钟

想必我们大家在开展一个新项目时,大都采用两种方式,一是直接使用对应脚手架提供的创建方式,比如vue create这样的命令创建vue项目,根据需求,分别安装依赖;二是拿着之前类似项目文件,进行删减、调整。繁琐的过程使开发者直喊奥里给。

现在,光来了!vue-cli 提供了一套模板创建机制,一条命令就可直接复用我们已配置好的初始化项目及依赖,下文我们将详细介绍。

使用方式

git地址: 将模板项目上传仓库使用

本地使用如下命令以远程仓库的为配置创建模板项目

vue create --preset 仓库地址 --clone <project-name>

通过脚手架安装会自动安装好node_modules,所以安装时间可能比较长。

项目介绍

官网地址:cli.vuejs.org/zh/guide/pl…

cli插件开发指南:cli.vuejs.org/zh/dev-guid…

核心文件:preset.jsonprompts.js,generator.js

Vue cli preset介绍

preset.json

一个 Vue CLI preset 是一个包含创建新项目所需预定义选项和插件的 JSON 对象,让用户无需在命令提示中选择它们。

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

这里有一个 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": {}
  }
}

prompts.js

使用方法见npm官网 prompts

Vue cli 需要在prompts.js导出一个包含问题的对象或数组

module.exports = [
    {
        name: 'selectTemplate',
        type: 'list',
        message: '请选择模板?',
        choices: [
            { name: 'uni-template', value: 'uni-template' },
            { name: 'fant-pc', value: 'fant-pc' },
            { name: 'uni-test', value: 'uni-test', description: "测试和调试脚手架用" },
        ],
        default: 'uni-template'
    }
]

**注意:**prompts对象的使用官方提供了很多案列,然而这个prompts的对话过程中只能是线性结构,不能是树状结构。比如我们希望根据用户选择的PC端模板还是app模板在接下来提供不同的选项,这在单次prompts中是做不到的,需要在二次封装。

generator

插件的 Generator 部分通常在你想要为项目扩展包依赖,创建新的文件或者编辑已经存在的文件时需要。

在 CLI 插件内部,generator 应该放在 generator.js 或者 generator/index.js 文件中。它将在以下两个场景被调用:

  • 项目初始创建期间,CLI 插件被作为项目创建 preset 的一部分被安装时。
  • 当插件在项目创建完成和通过 vue add 或者 vue invoke 单独调用被安装时。

一个 generator 应该导出一个接收三个参数的函数:

  1. 一个 GeneratorAPI 实例;
  2. 插件的 generator 选项。
  3. 整个preset将会作为第三个参数传入。
const prompt = require('prompts');
let public = require('./public/public')//导入公共package
module.exports = async (api, options, rootOptions) => {
  // 修改 `package.json` 里的字段
  let response,publicResponse
  // 公共配置问话
  publicResponse = await prompt(require('./public/prompts'))
  // 移动端项目模板
  if (options.selectTemplate == 'uniapp') {
    response = await prompt(require('./uniapp/prompts'));
    // 加载项目模板,生成src
    api.render('../template/uniapp')
    // 加载项目配置文件,生成package.json,根据配置文件加载依赖
    api.extendPackage(require('./uniapp/uniapp'))
    api.postProcessFiles((files) => {
        // rename only main file to main.ts
        delete files[api.entryFile]
    })
  }
  // pc项目模板
  if (options.selectTemplate == 'fant-pc') {
    // 获取配置问话
    response = await prompt(require('./fant-pc/prompts'));
    if (response.elementUI == '是') {
      api.extendPackage({
        devDependencies: {
          "element-ui": "^2.13.0"
        }
      })
    }
    // 加载项目模板
    api.render('../template/fant-pc')
    // 加载项目配置文件,生成package.json,根据配置文件加载依赖
    api.extendPackage(require('./fant-pc/fant-pc'))
  }
 
  // end all if
  options.response = response //template里只能拿到options,所以要把response挂载到options
  api.extendPackage(public)//导入公共package
}

项目结构

generator

​ index.js (generator入口文件)

​ public(公共文件)

​ prompts.js(公共对话模式)

​ public.js(公共依赖包)

​ [templateName]

​ prompts.js

​ [templateName].js

template

​ [templateName]

preset.json

prompts.js

generator文件夹

generator文件中,不同的模板会使用不同的对话模式,比如PC端会询问是否使用ElementUI,在app端则不用。不同的模板加载的package包也不同,所以项目将不同模板的内容放到了[templaName]文件夹中,prompts.js为这个模板的对话模式,[templateName].js为这个模板需要加载的包,public文件夹中为公共使用的模板和对话模式。

template文件夹

存放模板项目,项目中的package.json文件中的dependencies依赖和devDependencies依赖可以直接复制到generator中,由generator来注入。当对话执行完最终渲染时,在generator文件中调用api.render(src)完成最终渲染。

注意: 如果要渲染一个以点 .开头的文件,则需要改为以下划线 _ 开头,如果要渲染一个以 _开头的文件,则需要改为以双下划线开头 __

vue-cli拷贝文件是通过EJS模板实现的。EJS文档

html文件中 <%= BASE_URL %>时,需要转义成 <%%= BASE_URL %%>

条件渲染

template文件可以根据用户选择来进行条件渲染,例如:

有如下用户选择

let prompts = [{
    type: 'select',
    name: 'textView',
    message: '首页文字内容显示',
    choices: [
        { title: '欢迎使用uni-cli', description: 'recommend', value: 'cli' },
        { title: '欢迎使用uni模板', value: 'template' },
    ]
}, {
    type: 'select',
    name: 'colorSelect',
    message: '首页文字颜色选择',
    choices: [
        { title: '蓝色', description: 'recommend', value: 'blue' },
        { title: '绿色', value: 'green' },
        { title: '红色', value: 'red' },
    ]
}
]

Vue页面条件渲染如下

<template>
  <view class="index">
<%_ if (options.response.textView == 'cli') { _%>
    欢迎使用uni-cli
<%_ } _%>
 <%_ if (options.response.textView == 'template') { _%>
    欢迎使用uni模板
<%_ } _%>
  </view>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
})
</script>
<style>
.index{
<%_ if (options.response.colorSelect == 'blue') { _%>
    color:blue
<%_ } _%>
<%_ if (options.response.colorSelect == 'green') { _%>
    color:green
<%_ } _%>
<%_ if (options.response.colorSelect == 'red') { _%>
    color:red
<%_ } _%>
}
</style>

开发流程

  1. 在根目录的prompts.js中添加新的对话选项,供用户选择你添加的新的模板,可由generator函数的options参数拿到选择结果,选择使用哪个模板的目录。
  2. 将你的项目模板复制到template文件夹中,如果要引入变量和条件渲染注意用ejs语法。
  3. 在generator文件夹中创建你的模板文件夹,添加prompts.js对话选项和[templateName].js依赖包
  4. 将模板的package.json中的依赖复制或者剪切到generator的[templateName].js中,由genenrator控制注入
  5. generator入口文件中根据用户的选择response,使用api.extendPackage()控制包的注入,并调用api.render()渲染模板
  6. 在template文件夹你的项目模板里根据options.response.[options]控制条件渲染