建立簡單的npm腳手架

前言

vue-cli, webpack-cli 等腳手架是否是用起來愛不釋手?本身寫了個模版每次來回複製粘貼代碼是否是很難維護?若是你是對前端、Node操做有必定的瞭解,同時也存在以上疑問,那就請盡情閱讀嘗試吧!前端

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

依賴

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

根據上方的依賴插件便可以看出,其實腳手架就是一個利用終端命令將倉庫中的代碼拉取到本地的工具因此尚未模版代碼的同窗趕忙去建立個node

項目準備

初始化

$ npm init

根據提示完成初始化搭建,若是不清楚如何配置能夠直接回車webpack

安裝依賴

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

構建結構

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

最終目錄結構

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

編寫代碼

配置文件

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

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

入口文件

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

#! /usr/bin/env node

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

#!/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文件表示命令initnpm

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')}
          `);
        }
      });
    });
  })
});

測試發佈

測試

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

$ 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
相關文章
相關標籤/搜索