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

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

内容简介: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 指令是如何创建项目文件的》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Computational Geometry

Computational Geometry

Mark de Berg、Otfried Cheong、Marc van Kreveld、Mark Overmars / Springer / 2008-4-16 / USD 49.95

This well-accepted introduction to computational geometry is a textbook for high-level undergraduate and low-level graduate courses. The focus is on algorithms and hence the book is well suited for st......一起来看看 《Computational Geometry》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试