vue-cli, webpack-cli 等腳手架是否是用起來愛不釋手?本身寫了個模版每次來回複製粘貼代碼是否是很難維護?若是你是對前端、Node操做有必定的瞭解,同時也存在以上疑問,那就請盡情閱讀嘗試吧!前端
本篇文章按照al-block-cli
舉例, al-block-cli
是一個基於vue
和elementUI
而集成的一個開發模版,可安裝進行使用vue
根據上方的依賴插件便可以看出,其實腳手架就是一個利用終端命令將倉庫中的代碼拉取到本地的工具。因此尚未模版代碼的同窗趕忙去建立個node
$ npm init
根據提示完成初始化搭建,若是不清楚如何配置能夠直接回車webpack
$ npm install commander download-git-repo chalk inquirer ora --save
建立bin
和commands
文件夾以及配置文件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
文件表示命令init
npm
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