为啥能用 npm create vite 创建项目

541 阅读5分钟

前言

如今,Vite 已经成为前端项目的主流构建工具,尤其是在开发 Vue3 项目时,大多数开发者已经转向使用 Vite。在初始化项目时,官方文档推荐使用 npm create vite <project-name> 命令来创建项目。与以往需要全局安装命令行工具再通过工具初始化项目的方式不同,npm create vite 提供了一种更简洁、更轻量化的项目创建方式。那么,你有没有想过,为什么可以通过 npm create vite 来快速创建一个 Vite 项目?这个命令的原理是什么?它是如何实现的?本篇文章将深入探讨这个问题,解释 npm create vite 背后的原理与实现方法。

npm create 命令的背景

首先,我们需要了解 npm create 命令。npm 是 Node.js 的包管理工具,而 npm create 实际上是 npm init 的别名。也就是说,npm create vitenpm init vite 是等价的。

npm create 命令的核心功能是根据指定的脚手架工具来创建新项目。通过 npm create <tool>,你可以使用指定的工具来创建一个新的项目结构。

npm create 的原理

npm create 命令的工作原理非常简单:它实际上会执行 npm init <tool> 命令,后者会查找并运行一个名为 create-<tool> 的包,执行该包的默认操作。因此,npm create 会根据 <tool> 的不同,去寻找相应的工具包并运行。

如果省略 <tool> 参数(仅调用 npm create),init 将回退到旧版 init 行为。它会问你一堆问题,然后为你生成一个 package.json 文件。

npm create vite 背后的工具

当我们使用 npm create vite 命令时,NPM 会查找名为 create-vite 的工具包。如果存在这个工具包,NPM 就会通过 npm exec 命令执行该包,并用它来生成一个新的 Vite 项目。create-vite 实际上是 Vite 官方提供的一个脚手架工具,它负责初始化一个新的 Vite 项目,并为开发者提供选项。

npm create vite 命令的实现原理

为了深入理解 npm create vite 命令的实现,我们可以从 Vite 项目的结构和 NPM 的工作方式来分析。

create-vite 工具包

create-vite 是一个 NPM 包,它的作用是创建一个新的 Vite 项目。在 Vite 官方的 GitHub 仓库中,你可以看到 create-vite 工具包的实现。它的主要功能包括:

  1. 引导用户输入:通过命令行提示,帮助用户选择项目模板(例如 Vue、React 等)。
  2. 下载模板:根据用户选择的模板,自动下载相应的项目结构。
  3. 初始化项目:生成 Vite 项目的配置文件,安装所需的依赖,并初始化一个基本的开发环境。

npm create 实现流程

  • 运行 npm create 命令:当我们在命令行中输入 npm create vite 时,NPM 会尝试查找名为 create-vite 的包。
  • 执行 create-vite:一旦找到该包,NPM 就会执行它。在执行过程中,create-vite 会根据用户的输入,选择不同的模板,并自动配置 Vite 项目的结构。
  • 初始化项目:最后,create-vite 会根据所选模板生成一个新的 Vite 项目

通过这种方式,开发者只需要运行一个命令,就可以自动创建并配置好一个新的 Vite 项目。

实现一个工具包

为了进一步理解 npm create <tool> 的实现,我们可以自己动手实现一个简单的工具包。

创建一个项目

首先,我们需要创建一个项目:

mkdir create-zycode
cd create-zycode
npm init -y

修改 package.json,新增 bin 配置。注意,bin 配置中必须有一个 key 和包名一致:

{
  "name": "create-zycode",
  "version": "1.0.0",
  "description": "A CLI tool to initialize template projects",
  "main": "index.js",
+  "bin": {
+    "create-zycode": "index.js"
+  },
  "scripts": {
    "start": "node index.js"
  },
  "author": "zi.yang",
  "license": "MIT",
  "dependencies": {}
}

复制一个模板

为了方便,我们可以直接从 Vite 仓库复制一个 template-vue 的模板,放到项目的根目录。

添加命令行实现

在根目录创建一个 index.js 文件,文件头部一定要加上 #!/usr/bin/env node 声明,否则执行时会报错。

下面的代码逻辑很简单:通过 process.cwd() 获取命令执行时的路径,然后通过 __dirname 获取脚本目录的位置。接着判断目标文件夹是否存在,如果不存在则创建一个,如果存在则提示并退出。

创建好目录之后,通过递归的方式读取模板文件,并通过 fs.copyFileSync 拷贝文件。

#!/usr/bin/env node

/*
 * @Author: zi.yang
 * @Date: 2025-01-07 11:09:12
 * @LastEditors: zi.yang
 * @LastEditTime: 2025-01-07 11:11:03
 * @Description: npm create 演示脚本
 * @FilePath: /create-zycode/index.js
 */
const fs = require('fs');
const path = require('path');

// 获取命令行参数
const args = process.argv.slice(2);
const projectName = args[0] || 'my-project';

const cwd = process.cwd();
// 获取命令执行的目录
const projectPath = path.join(cwd, projectName);
// 获取模板路径
const templatePath = path.join(__dirname, 'template-vue');

// 创建项目目录
if (!fs.existsSync(projectPath)) {
    fs.mkdirSync(projectPath);
    console.log(`Project directory ${projectName} created.`);
} else {
    console.error(`Directory ${projectName} already exists.`);
    process.exit(1);
}

// 复制模板文件到项目目录
function copyTemplateFiles(srcDir, destDir) {
    const files = fs.readdirSync(srcDir);

    files.forEach(file => {
        const srcFile = path.join(srcDir, file);
        const destFile = path.join(destDir, file);

        if (fs.lstatSync(srcFile).isDirectory()) {
            fs.mkdirSync(destFile);
            copyTemplateFiles(srcFile, destFile);
        } else {
            fs.copyFileSync(srcFile, destFile);
        }
    });
}

copyTemplateFiles(templatePath, projectPath);

console.log('Template project initialized.');

测试命令

实现完成后,将这个包发布到 npm,然后执行以下命令:

npm create zycode@latest my-template

这里有一个小细节:为什么在执行时要加 latest 版本号?其实这是因为每次执行 npm create <tool> 时,会首先将这个包下载到本地。如果你没有加 latest,下次执行时会直接使用本地的包,而不会重新下载。如果想要使用最新版本,就必须添加版本号。

结语

npm create vite 命令的实现依赖于 NPM 的 create 命令,它会自动执行 create-vite 工具包来初始化项目。这个工具包通过命令行交互和模板下载,帮助开发者快速搭建一个新的 Vite 项目。

通过了解这一原理,我们能更清楚地理解为什么可以使用 npm create vite 来创建 Vite 项目,并掌握如何使用 NPM 的 create 命令实现自己的模板工具包。

相关链接