回首往昔,无趣的过往。没有任何精彩的事情发生,只有空的躯壳像NPC一样再运作。上一次写我的脚手架工具已经是一年前了,当时很多不成熟的思维也慢慢得到了改正,所以决定重新写一份了,毕竟每年都要好好的检查下自己嘛

必备项目依赖

— kolorist 控制台命令行操控颜色的脚本库 — minimist 参数解析器 类似 mw create —template 这种 — prompts 一个提示用户选择的库 — unbuild 构建工具

开始编写

安装我们所需要使用到的依赖

pnpm add kolorist minimist prompts unbuild typescript -D

初始化tsconfig.json


{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2020",
    "outDir": "lib",
    "moduleResolution": "bundler",
    "strict": true,
    "skipLibCheck": true,
    "declaration": false,
    "sourceMap": false,
    "noUnusedLocals": true,
    "esModuleInterop": true
  },
  "exclude": ["template", "lib"]
}


整理合理的项目目录 1

编写 unbuild 的配置文件

// build.config.ts

import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
  entries: [
    "./src/index",
  ],
  outDir: "lib",
  declaration: true,
});

修改package.json 修改Bin软链接指令,编写unbuild的本地打包测试指令

{
  "name": "create-mw",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "npx  unbuild --stub"
  },
  "bin": {
    "cre":"index.js"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "engines": {
    "node": "^18.0.0 || >=20.0.0"
  },
  "devDependencies": {
    "@types/minimist": "^1.2.5",
    "@types/node": "^20.14.10",
    "kolorist": "^1.8.0",
    "minimist": "^1.2.8",
    "prompts": "^2.4.2",
    "tsx": "^4.16.2",
    "typescript": "^5.5.3",
    "unbuild": "^2.0.0"
  }
}

修改index.js 入口文件代码让他指向我们打包出来的js文件

#!/usr/bin/env node

import './lib/index.mjs'

打包后,npm link 后测试下是否正常,执行命令cre 看看是否正常

2

然后我们使用minimist 来进行一个参数解析。 解析后让他成为能够获取 cre —template 获取这种在命令里的参数

// 参数解析器
const argv = minimist(process.argv.slice(2), {})

console.log(argv);

2 2

import minimist from "minimist";
import prompts from "prompts";
import {
  blue,
  cyan,
  green,
  lightBlue,
  lightGreen,
  lightRed,
  magenta,
  red,
  reset,
  yellow,
} from "kolorist";

// 参数解析器 方便解析我们需要的
const argv = minimist(process.argv.slice(2), {});

console.log(argv);

//  获取项目路径
const cwd = process.cwd();

console.log(cwd);

// prettier-ignore
const helpMessage = `\
Usage: create-vite [OPTION]... [DIRECTORY]

Create a new Vite project in JavaScript or TypeScript.
With no arguments, start the CLI in interactive mode.

Options:
  -t, --template NAME        use a specific template

Available templates:
${yellow   ('vanilla-ts     vanilla'  )}
${green    ('vue-ts         vue'      )}
${cyan     ('react-ts       react'    )}
${cyan     ('react-swc-ts   react-swc')}
${magenta  ('preact-ts      preact'   )}
${lightRed ('lit-ts         lit'      )}
${red      ('svelte-ts      svelte'   )}
${blue     ('solid-ts       solid'    )}
${lightBlue('qwik-ts        qwik'     )}`


const FRAMEWORKS = [
  {
    name: "vanilla",
    display: "Vanilla",
    color: yellow,
    variants: [
      {
        name: "vanilla-ts",
        display: "TypeScript",
        color: blue,
      },
      {
        name: "vanilla",
        display: "JavaScript",
        color: yellow,
      },
    ],
  },
  {
    name: "solid",
    display: "Solid",
    color: blue,
    variants: [
      {
        name: "solid-ts",
        display: "TypeScript",
        color: blue,
      },
      {
        name: "solid",
        display: "JavaScript",
        color: yellow,
      },
    ],
  },
];

// 将 FRAMEWORKS 中存在的variants转换成一维数组 并转换成一维数组
const TEMPLATES = FRAMEWORKS.map(
  (item) => (item.variants && item.variants.map((v) => v.name)) || [item.name]
).flat(Infinity);

// 默认文件名
const defaultTargetDir = "cre-Project";

// 初始化函数
const init = async () => {
  try {
    // prompts
    const result = await prompts([
      {
        type: "text",
        name: "projectName",
        message: "Project name:",
        initial: defaultTargetDir,
      },
      {
        type: "select",
        name: "overwrite",
        message: "Current directory",
        initial: 0,
        choices: [
          {
            title: 'Remove existing files and continue',
            value: 'yes',
          },
          {
            title: 'Cancel operation',
            value: 'no',
          },
          {
            title: 'Ignore files and continue',
            value: 'ignore',
          },
        ],
      }
    ]);

    console.log(result);
  } catch (error) {
    console.log(error);
  }
};

init();

没写完 临时有别的东西要写,下次更新。。。。