0
点赞
收藏
分享

微信扫一扫

脚手架开发【实战教程】prompts + fs-extra


创建项目

  • 新建文件夹 mycli_demo
  • 在文件夹 mycli_demo 内新建文件 package.json

{
  "name": "mycli_demo",
  "version": "1.0.0",
  "bin": {
    "mycli": "index.js"
  },
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "fs-extra": "^11.3.0",
    "prompts": "^2.4.2"
  }
}

  • 新建文件 templates\react\package.json

{
    "name": "your-project-name",
    "version": "1.0.0",
    "description": "react + ts + vite 项目模板",
    "main": "index.js",
    "scripts": {
        "dev": "vite"
    },
    "keywords": [],
    "author": "",
    "license": "ISC"
}

  • 新建文件 templates\vue\package.json

{
    "name": "your-project-name",
    "version": "1.0.0",
    "description": "vue + ts + vite 项目模板",
    "main": "index.js",
    "scripts": {
        "dev": "vite"
    },
    "keywords": [],
    "author": "",
    "license": "ISC"
}

  • 新建文件 index.js

#!/usr/bin/env node

// prompts 用于与用户进行交互
const prompts = require("prompts");

// fs-extra 用于文件操作
const fse = require("fs-extra");

// path 用于处理文件路径
const path = require("path");

// 定义项目模板路径
const templateDir = path.join(__dirname, "templates");

// 定义交互问题
const questions = [
  {
    type: "select",
    name: "projectType",
    message: "请选择项目类型:",
    choices: [
      { title: "vue", value: "vue" },
      { title: "react", value: "react" },
    ],
    initial: 0,
  },
  {
    type: "text",
    name: "projectName",
    message: "请输入项目名称:",
    validate: (value) => (value.trim() === "" ? "项目名称不能为空" : true),
  },
  {
    type: "select",
    name: "packageManager",
    message: "请选择包管理器:",
    choices: [
      { title: "npm", value: "npm" },
      { title: "yarn", value: "yarn" },
    ],
    initial: 0,
  },
];

async function createProject() {
  try {
    // 发起交互,并获取用户输入
    const answers = await prompts(questions);

    // 解析用户输入的项目信息
    const { projectType, projectName, packageManager } = answers;

    // 根据用户输入的项目名称,生成新项目目录。  process.cwd() 用于获取当前工作目录的路径
    const projectDir = path.join(process.cwd(), projectName);
    // 检查新项目目录是否已存在
    if (fse.existsSync(projectDir)) {
      console.error(`项目目录 ${projectDir} 已存在,请选择其他名称。`);
      return;
    }
    // 创建项目目录
    fse.ensureDirSync(projectDir);

    // 根据用户选择,获取目标模板路径
    const templatePath = path.join(templateDir, projectType);
    // 复制模板目录到目标目录
    fse.copySync(templatePath, projectDir);

    // 根据用户选择更新项目配置
    const packageJsonPath = path.join(projectDir, "package.json");
    // 读取 package.json 文件
    const packageJson = fse.readJsonSync(packageJsonPath);
    // 更新 package.json 中的项目名称
    packageJson.name = projectName;

    // 保存更新后的 package.json
    fse.writeJsonSync(packageJsonPath, packageJson, { spaces: 2 });

    console.log(`项目 ${projectName} 创建成功!`);
    console.log(`请进入项目目录:cd ${projectName}`);
    console.log(`使用 ${packageManager} 安装依赖:${packageManager} install`);
  } catch (error) {
    if (error.name === "AbortError") {
      console.log("用户取消了项目创建。");
    } else {
      console.error("创建项目时发生错误:", error);
    }
  }
}

// 执行创建项目函数
createProject();

安装依赖

pnpm i

或更新到最新版依赖

pnpm i prompts fs-extra

将本地包链接到全局

主要是为了方便本地调试包

npm link --force

此命令会强制将 mycli 链接到全局 node_modules 目录中,同时在全局 bin 目录中根据 package.json 中定义的 bin 字段创建对应的可执行文件
( --force 会强制覆盖已存在的 mycli 链接和可执行文件)

效果预览

命令行中输入 mycli 回车,便会开启交互,最终根据既定模板完成项目的创建。

脚手架开发【实战教程】prompts + fs-extra_脚手架开发


脚手架开发【实战教程】prompts + fs-extra_json_02

{
  "name": "reactDemo",
  "version": "1.0.0",
  "description": "react + ts + vite 项目模板",
  "main": "index.js",
  "scripts": {
    "dev": "vite"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

更多交互命令

参考 prompts 官网 https://www.npmjs.com/package/prompts

脚手架开发的意义和原理

脚手架的系统管理和发布



举报

相关推荐

0 条评论