Vue-cli 的 create 指令是如何创建项目文件的

栏目: JavaScript · 发布时间: 5年前

内容简介:Vue-cli 是创建 Vue 项目的一个好方法,之前只是使用,没有关注过内部结构是咋样的。最近在做一个组内项目的 cli 工具,参考了一下 Vue-cli 的实现方法。

Vue-cli 是创建 Vue 项目的一个好方法,之前只是使用,没有关注过内部结构是咋样的。最近在做一个组内项目的 cli 工具,参考了一下 Vue-cli 的实现方法。

Vue-cli 项目结构

Vue-cli ),是一个多 package 项目,使用 lerna 进行管理。package 内的 @vue 文件夹下有很多包:

Vue-cli 的 create 指令是如何创建项目文件的

其中与创建项目有关的包,我们主要需要关注 cli 和 cli-service。

@vue/cli

@vue/cli 包,就是我们平时执行的 bin 文件,入口是 @vue/cli/bin/vue.js。该文件会先检查用户当前使用的 node.js 版本是否符合要求。

之后使用 commander.js )来提供命令行指令接口。

program
  .command('create <app-name>')
  .description('create a new project powered by Vue-cli-service')
  .option('-p, --preset <presetName>', 'Skip prompts and use saved or remote preset')
  .option('-d, --default', 'Skip prompts and use default preset')
  .option('-i, --inlinePreset <json>', 'Skip prompts and use inline JSON string as preset')
  .option('-m, --packageManager <command>', 'Use specified npm client when installing dependencies')
  .option('-r, --registry <url>', 'Use specified npm registry when installing dependencies (only for npm)')
  .option('-g, --git [message]', 'Force git initialization with initial commit message')
  .option('-n, --no-git', 'Skip git initialization')
  .option('-f, --force', 'Overwrite target directory if it exists')
  .option('-c, --clone', 'Use git clone when fetching remote preset')
  .option('-x, --proxy', 'Use specified proxy when creating project')
  .option('-b, --bare', 'Scaffold project without beginner instructions')
  .action((name, cmd) => {
    const options = cleanArgs(cmd)

    if (minimist(process.argv.slice(3))._.length > 1) {
      console.log(chalk.yellow('\n Info: You provided more than one argument. The first one will be used as the app\'s name, the rest are ignored.'))
    }
    // --git makes commander to default git to true
    if (process.argv.includes('-g') || process.argv.includes('--git')) {
      options.forceGit = true
    }
    require('../lib/create')(name, options)
  })

commander 会帮助收集选项参数等内容,之后调用了

require('../lib/create')(name, options)

可以看到最终项目创建逻辑是在 ../lib/create 中执行的。

../lib/create

create.js 文件主要做了以下几件事:

  1. 检查项目初始化名称是否合法。
  2. 检查项目初始化目录是否存在,若存在提示用户选择覆盖、合并、取消进行操作。
  3. 初始化 Creator 类,并执行实例的 .create 方法。

Creator 类

我们直接来看一下 Creator 类的 create 方法,该方法主要做了以下事情:

  1. 初始化 preset

    preset 用于指定初始化项目的具体配置,例如是否使用 babel、typescript 等。preset 可以通过执行命令行 工具 时指定,未指定时会在命令行中提供选项让使用者选择。

    if (!preset) {
      if (cliOptions.preset) {
        // vue create foo --preset bar
        preset = await this.resolvePreset(cliOptions.preset, cliOptions.clone)
      } else if (cliOptions.default) {
        // vue create foo --default
        preset = defaults.presets.default
      } else if (cliOptions.inlinePreset) {
        // vue create foo --inlinePreset {...}
        try {
          preset = JSON.parse(cliOptions.inlinePreset)
        } catch (e) {
          error(`CLI inline preset is not valid JSON: ${cliOptions.inlinePreset}`)
          exit(1)
        }
      } else {
        preset = await this.promptAndResolvePreset()
      }
    }
    

    之后会在 preset 中添加 @vue/cli-service 插件,该插件用于创建初始化项目的基础内容。

    // inject core service
    preset.plugins['@vue/cli-service'] = Object.assign({
      projectName: name
    }, preset, {
      bare: cliOptions.bare
    })
    
  2. 根据命令行选项,初始化git。

  3. 安装所有插件。

    preset 初始化之后,就会生成 package.json 文件,所有插件作为依赖放在 package.json 中,使用 npm 或 yarn 来进行安装。

  4. 初始化 Generator 类,并执行实例的 generate 方法。

    Generator 类用于提供插件的加载机制。加载所有插件的内容,放入初始化的项目中。我们之后会说。

  5. 插件内容加载完毕后,会生成新的 package.json 依赖,此时需要再次进行安装。

  6. 生成 README.md 文件。
  7. 进行第一次 git 提交。
  8. 命令行中打印初始化完成提示信息。

Generator 类

Generator 类是 Vue-cli 提供的与插件之间交流机制,编写插件时可利用这个机制,进行文件、package.json 依赖的修改,具体可见官方文档: https://cli.vuejs.org/dev-guide/plugin-dev.html#generator

它是怎么工作的呢?Generator 类初始化时,会给每个插件初始化一个 GeneratorAPI 类,作为插件与 cli 之间的接口。

// apply generators from plugins
plugins.forEach(({ id, apply, options }) => {
  const api = new GeneratorAPI(id, this, options, rootOptions)
  apply(api, options, rootOptions, invoking)
})

之后在 .generate 方法调用时,调用了自身的 .resolveFiles 方法,来获取所有的文件内容。

// wait for file resolve
await this.resolveFiles()

文件内容获取后,进行 package.json 的写入,以及模板文件的写入:

this.files['package.json'] = JSON.stringify(this.pkg, null, 2) + '\n'
// write/update file tree to disk
await writeFileTree(this.context, this.files, initialFiles)

以上所述就是小编给大家介绍的《Vue-cli 的 create 指令是如何创建项目文件的》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript & jQuery交互式Web前端开发

JavaScript & jQuery交互式Web前端开发

[美]达克特(Duckett,J.) / 杜伟、柴晓伟、涂曙光 / 清华大学出版社 / 2015-6-9 / 79.80元

欢迎选择一种更高效的学习JavaScript和jQuery的方式。 你是一名JavaScript新手?或是您曾经向自己的Web页面上添加过一些脚本,但想以一种更好的方式来实现它们?本书非常适合您。本书不仅向您展示如何阅读和编写JavaScript代码,同时还会以一种简单且视觉化的方式,教您有关计算机编程的基础知识。阅读本书之前,您只需要对HTML和CSS有一些了解即可。 通过将编程理论......一起来看看 《JavaScript & jQuery交互式Web前端开发》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器