前言

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

创建简单的npm脚手架的更多相关文章

  1. 创建并发布npm包

    1.npm官网创建npm账户 npm网站地址:https://www.npmjs.com/ npm网站注册地址:https://www.npmjs.com/signup 2.命令行工具登录npm np ...

  2. 简单vue项目脚手架(vue+webpack2.0+vuex+vue-router)

    github地址 使用技术栈 webpack(^2.6.1) webpack-dev-server(^2.4.5) vue(^2.3.3) vuex(^2.3.1) vue-router(^2.5.3 ...

  3. 简单vue项目脚手架

    简单vue项目脚手架 github地址 使用技术栈 webpack(^2.6.1) webpack-dev-server(^2.4.5) vue(^2.3.3) vuex(^2.3.1) vue-ro ...

  4. [.NET] WebApi 生成帮助文档及顺便自动创建简单的测试工具

    ==========最终的效果图========== ==========下面开始干活:生成帮助文档========== 一.创建 WebApi 项目 二.找到 HelpPageConfig.cs 并 ...

  5. Web Service 的创建简单编码、发布和部署

    最近,老大准备将已有的C/S架构项目中的通信部分做成通用,需要将其支持WebService为以后项目向着B/S架构升级做好铺垫,为此身为屌丝的我去各种百度WebService是个什么卵玩意,然后逐渐搭 ...

  6. Azure PowerShell (5) 使用Azure PowerShell创建简单的Azure虚拟机和Linux虚拟机

    <Windows Azure Platform 系列文章目录> 本文介绍的是国外的Azure Global.如果是国内由世纪互联运维的Azure China,请参考这篇文档: Azure ...

  7. myeclipse(2015)中创建简单的Maven项目的步骤(用于生成可执行jar文件)------》myeclipse2015

    利用MyEclipse的引导,可以很方便的创建简单的.用于生成可执行jar文件的Maven项目: 1.New -> Project... 选择 Maven Project, 点击Next > ...

  8. 使用Visual Studio创建简单的自己定义Web Part 部件属性

    使用Visual Studio创建简单的自己定义Web Part 部件属性 自己定义属性使用额外的选项和设置拓展你的Web part部件.本文主要解说怎样使用Visual Studio创建简单的自己定 ...

  9. C链表之创建简单静态链表

    C代码: #include<stdio.h> #include<stdlib.h> #include<malloc.h> //创建简单静态链表 typedef st ...

随机推荐

  1. 集成支付宝SDK流程

    5.2 SDK集成流程 5.2.1 iOS 解压接口压缩文件(文件名是 WS_MOBILE_PAY_SDK_BASE.zip),找到iOS的压缩文件(文件名是支付宝移动支付SDK 标准版(iOS).z ...

  2. 实践 Network Policy - 每天5分钟玩转 Docker 容器技术(172)

    为了演示 Network Policy,我们先部署一个 httpd 应用,其配置文件 httpd.yaml 为: httpd 有三个副本,通过 NodePort 类型的 Service 对外提供服务. ...

  3. SQL Server事务 事务日志

    事务 (SQL Server) 一.事务概念    事务是一种机制.是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行.因此事务是一个不可分割的工作逻辑单元.在数据库系统 ...

  4. Netty基础系列(1) --linux网路I/O模型

    引言 我一直认为对于java的学习,掌握基础的性价比要远远高于使用框架,而基础知识中对于网络相关知识的掌握也是重中之重.对于一个java程序来说,无论是工作中还是面试,对于Netty的掌握都是及其重要 ...

  5. 安卓开发笔记(二十六):Splash实现首页快速开屏功能

    我们在进行安卓开发的时候,首页开有两种方式,一种是利用handler将一个活动进行延时,时间到达之后软件则会跳转到第二个活动当中.而另一种方法则是更加常用的方法,利用splash实现首页的快速开屏,这 ...

  6. ES 13 - Elasticsearch的元字段 (_index、_type、_source、_routing等)

    目录 1 标识元字段 1.1 _index - 文档所属的索引 1.2 _uid - 包含_type和_id的复合字段 1.3 _type - 文档的类型 1.4 _id - 文档的id 2 文档来源 ...

  7. Python调用ansible API系列(三)带有callback的执行adhoc和playbook

    在第二篇文章中虽然可以执行adhoc和playbook但是执行结果的输出并不是特别直观,虽然没有报错但是到底什么结果其实你是不知道的尤其是在执行adhoc的时候,这时候我们要利用callback来设置 ...

  8. MTCNN算法与代码理解—人脸检测和人脸对齐联合学习

    目录 写在前面 算法Pipeline详解 如何训练 损失函数 训练数据准备 多任务学习与在线困难样本挖掘 预测过程 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在前面 主 ...

  9. Netty源码—七、内存释放

    Netty本身在内存分配上支持堆内存和直接内存,我们一般选用直接内存,这也是默认的配置.所以要理解Netty内存的释放我们得先看下直接内存的释放. Java直接内存释放 我们先来看下直接内存是怎么使用 ...

  10. 03. Redis-配置文件

    redis-3.2.6配置文件 主要修改配置文件几个大方面: 端口 port 安全: bind ip 绑定监听IP 安全模式开启与否 protected-mode 一般设置yes 访问密码 requi ...