Node实现类似vue脚手架功能并发布到npm

265 阅读2分钟

目的:主要是为了学习一下node, 及发布npm的一些知识

1. 新建一个文件夹,在这里打开命令行终端执行npm init, 然后一直敲回车,会生成一个package.json文件(包括名字,主入口文件等)

2. 新建主入口文件index.js

  1. index.js 下面声明
#!/usr/bin/env node 第一行声明命令行脚本是node.js写的

  1. package.json里面添加bin

  2. 终端输入npm link 将juejin命令链接到全局

  3. 这个时候在任意目录下终端输入juejin, 会去全局根据之前注册的找到这个index.js并执行

我们来用nodeJs写一个简单的CLI功能吧

  1. 安装我们需要的依赖
yarn add commander download-git-repo inquirer handlebars ora chalk log-symbols
    //  命令行参数库、github下载模板、命令行答询、修改package、加载状态、输出样式
  1. index.js 代码如下
#!/usr/bin/env node
// console.log("hello", process.argv);

const program = require("commander");
const download = require("download-git-repo");
const inquirer = require("inquirer"); //命令行答询
const handlebars = require("handlebars"); //修改字符
const ora = require("ora"); //命令行中加载状态标识
const chalk = require("chalk"); //命令行输出字符颜色
const logSymbols = require("log-symbols"); //命令行输出符号
const fs = require("fs");
program.version("1.0.0");

const templates = {
  vue: {
    url: "https://github.com:promotion-xu/tsx-component",
    downloadUrl: "https://github.com:promotion-xu/tsx-component#master",
    description: "xuzhen脚手架测试模板a",
  },
  react: {
    url: "https://github.com:promotion-xu/react-app",
    downloadUrl: "https://github.com:promotion-xu/react-app#msater",
    description: "xuzhen脚手架测试模板b",
  },
};

program
  .command("init <template> <project>")
  .description("初始化项目模板")
  .action((templateName, projectName) => {
    console.log(templateName, projectName);
    let { downloadUrl } = templates[templateName];
    const spinner = ora("正在下载模板...").start();
    //第一个参数是github仓库地址,第二个参数是创建的项目目录名,第三个参数是clone
    download(downloadUrl, projectName, { clone: true }, (err) => {
      if (err) {
        spinner.fail("项目模板下载失败");
      } else {
        spinner.succeed("项目模板下载成功");
        inquirer
          .prompt([
            {
              type: "input",
              name: "name",
              message: "请输入项目名称",
              default: projectName,
            },
            {
              type: "input",
              name: "description",
              message: "请输入项目简介",
              default: "",
            },
            {
              type: "input",
              name: "author",
              message: "请输入作者名称",
              default: "",
            },
          ])
          .then((answers) => {
            //根据命令行答询结果修改package.json文件
            let packsgeContent = fs.readFileSync(
              `${projectName}/package.json`,
              "utf8"
            );
            let packageResult = handlebars.compile(packsgeContent)(answers);
            fs.writeFileSync(`${projectName}/package.json`, packageResult);
            //用chalk和log-symbols改变命令行输出样式
            console.log(
              logSymbols.success,
              chalk.green("模板项目文件准备成功")
            );
          });
      }
    });
  });

program
  .command("list")
  .description("查看所有可用模板")
  .action(() => {
    console.log(`
            a   a模板
            b   b模板
            c   c模板
        `);
  });

program.parse(process.argv);
  1. 终端输入,就可以实现命令行下载通用模板了
juejin init vue vue-demo 
juejin init react react-demo
  1. 最后我们发布到npm包管理工具上
npm login
npm publish