創建簡單的npm腳手架


前言

vue-cli, webpack-cli 等腳手架是不是用起來愛不釋手?自己寫了個模版每次來回復制粘貼代碼是不是很難維護?如果你是對前端、Node操作有一定的了解,同時也存在以上疑問,那就請盡情閱讀嘗試吧!

本篇文章按照al-block-cli舉例, al-block-cli是一個基於vueelementUI而集成的一個開發模版,可安裝進行使用

依賴

  1. Commander.js 命令行工具
  2. download-git-repo git倉庫代碼下載
  3. chalk 命令行輸出樣式美化
  4. Inquirer.js 命令行交互
  5. ora命令行加載中效果

根據上方的依賴插件即可以看出,其實腳手架就是一個利用終端命令將倉庫中的代碼拉取到本地的工具所以還沒有模版代碼的同學趕緊去創建個

項目准備

初始化

$ npm init

根據提示完成初始化搭建,如果不清楚如何配置可以直接回車

安裝依賴

$ npm install commander download-git-repo chalk inquirer ora --save

構建結構

創建bincommands文件夾以及配置文件templates.json。bin文件夾為可執行命令入口目錄,commands則負責編寫一些命令交互

最終目錄結構

- al-block-cli
| - bin
| - commands
| - node_modules
| - package.json
| - templates.json

編寫代碼

配置文件

輸入默認需要的配置,如這里需要github 的倉庫地址和命令行的名稱

{
  "init": {
    "name": "init",
    "path": "Alisdon/al-block-template"
  }
}

入口文件

新建al-block-cli文件,並在其第一行加入

#! /usr/bin/env node

此行為了防止操作系統用戶沒有將node裝在默認的/usr/bin路徑里。當系統看到這一行的時候,首先會到env設置里查找node的安裝路徑,再調用對應路徑下的解釋器程序完成操作。

#!/usr/bin/env node

process.env.NODE_PATH = __dirname + '/../node_modules/';

const program = require('commander');

program
  .version(require('../package').version);

program
  .usage('<command>');

program.command('init')
  .description('create a new project')
  .alias('i')
  .action(() => {
    require('../commands/init')
  });

program.parse(process.argv);

if(!program.args.length){
  program.help()
}

命令交互

新建init.js文件表示命令init

const { prompt } = require('inquirer');
const program = require('commander');
const chalk = require('chalk');
const download = require('download-git-repo');
const ora = require('ora');
const fs = require('fs');

const option =  program.parse(process.argv).args[0];
const question = [
  {
    type: 'input',
    name: 'name',
    message: 'Project name',
    default: typeof option === 'string' ? option : 'al-block-template',
    filter (val) {
      return val.trim()
    },
    validate (val) {
      const validate = (val.trim().split(" ")).length === 1;
      return validate || 'Project name is not allowed to have spaces ';
    },
    transformer (val) {
      return val;
    }
  },
  {
    type: 'input',
    name: 'description',
    message: 'Project description',
    default: 'Vue project',
    validate () {
      return true;
    },
    transformer(val) {
      return val;
    }
  },
  {
    type: 'input',
    name: 'author',
    message: 'Author',
    default: '',
    validate () {
      return true;
    },
    transformer(val) {
      return val;
    }
  }
];

module.exports = prompt(question).then(({name, description, author}) => {
  const gitPlace = require('../templates').init.path;
  const projectName = name;
  const spinner = ora('Downloading please wait...');

  spinner.start();
  download(`${gitPlace}`, `./${projectName}`, (err) => {
    if (err) {
      console.log(chalk.red(err));
      process.exit()
    }

    fs.readFile(`./${projectName}/package.json`, 'utf8', function (err, data) {
      if(err) {
        spinner.stop();
        console.error(err);
        return;
      }

      const packageJson = JSON.parse(data);
      packageJson.name = name;
      packageJson.description = description;
      packageJson.author = author;

      fs.writeFile(`./${projectName}/package.json`, JSON.stringify(packageJson, null, 2), 'utf8', function (err) {
        if(err) {
          spinner.stop();
          console.error(err);
        } else {
          spinner.stop();
          console.log(chalk.green('project init successfully!'))
          console.log(`
            ${chalk.yellow(`cd ${name}`)}
            ${chalk.yellow('npm install')}
            ${chalk.yellow('npm run dev')}
          `);
        }
      });
    });
  })
});

測試發布

測試

至此,一個簡單的腳手架(殼)就已經完成了,為了查看在編寫過程中是否出錯,我們現在本地進行測試

$ node bin/al-block-cli

如果沒有報錯,出現了熟悉的命令行,那就說明成功了

發布

發布之前我們需要做個小調整,觀察其他腳手架工具他們都是以自己獨特的key值進行搭建,對此我們可以在package.json里面配置bin對象

"bin": {
	"al-block-cli": "bin/al-block-cli"
}

這里需要注意bin/后面的al-block-cli,這個路徑是由入口文件的路徑確定,如果你是建的al-block-cli.js則此處應該配置bin/al-block-cli.js,本篇是創建的沒有后綴名的文件

修改后生成的最終package.json

{
  "name": "al-block-cli",
  "version": "1.0.0",
  "description": "al-block-cli",
  "keywords": [
    "vue",
    "al-block",
    "al-block-cli"
  ],
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "bin": {
    "al-block-cli": "bin/al-block-cli"
  },
  "preferGlobal": true,
  "author": "Alisdon [920124512@qq.com]",
  "license": "MIT",
  "dependencies": {
    "chalk": "^2.4.1",
    "commander": "^2.19.0",
    "download-git-repo": "^1.1.0",
    "inquirer": "^6.2.1",
    "ora": "^3.0.0"
  }
}

對比文件內容,如果沒有問題我們就開始發布了

$ npm login
$ npm publish


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM