前置准备
开发环境
Node 环境 (必须)
VS Code 开发工具 (非必须,你可以使用你喜欢的开发工具)注册 NPM 账号
访问 NPM 官网 ,点击 Sign up 字样,输入邮箱用户名密码就可以完成创建了,注意这里的 Username 和 Password 将用于后续登录和发布包。Public Email 用于接收推送邮件。
开发
创建 NPM 项目
新建一个空文件夹
运行命令行,切换到你想存放文件的目录,执行新建文件。如:1
2
3
4C:> cd D:/
D:> mkdir gitchat-oni
D:> cd gitchat-oni
D:\gitchat-oni>新建一个 NPM 项目
在刚刚的目录下执行 npm init ,输入项目的一下信息
配置程序入口
打开 package.json 做一点点的修改:
1
2
3
4"main": "index.js",
"bin": {
"new": "./bin/new.js"
}如果是插件的话,入口文件就是 main 所定义的;如果是工具的话,入口文件就是 bin 所定义的。
创建入口文件
在项目中新建一个bin目录,在bin目录新建一个new.js的文件
编写入口文件
安装工具所需要的依赖:
1
2
3
4
5
6D:\new>npm i commander --save
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN gitchat-oni@1.0.0 No repository field.
+ commander@2.15.1
added 1 package in 2.184scommander 是 Node.js 命令行接口的完整解决方案,打开 new.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//这里需要声明文件运行环境,特别重要!!
const program = require('commander');
program
.version(require('../package').version)
.on('--help', printHelp)
.usage('<command> [options]')
.parse(process.argv)
//process模块用来与当前进程互动,可以通过全局变量process访问,
//不必使用require命令加载。它是一个EventEmitter对象的实例。
function printHelp (){
console.log("gitchat help");
}这里其实我们的工具已经编写完毕了,它的功能就是打印出它自己的版本号,还有执行 –help 的时候,打印一段文字。
将工具上传到 NPM 上,或者使用 npm link 命令安装到本地
首先要先登录到 NPM,使用刚刚注册的账号密码,这里的邮箱是用于接收推送邮件的。
1
2
3
4
5D:\new>npm login
Username: hc
Password:
Email: (this IS public) xxxx@qq.com
Logged in as xiaohuoni on https://registry.npmjs.org/.然后执行推送 npm publish:
上传成功,同时你可以查看邮箱,有一封来自 NPM 官方的邮件。
将自己的工具安装到电脑上
1
npm i new -g
定义 new-cli
其实原理就是当你执行 new 之后,将一份脚手架代码,复制到你当前的目录下面。
先定义命令。1
2
3
4
5
6
7
8
9program
.command('new')
.description('新建一个项目')
.action(function(name,other){
console.log("执行了new")
console.log("新建一个项目")
console.log("执行拷贝")
});
program.parse(process.argv);完善 new-cli 功能
因为我们的 new 功能是执行拷贝,所以这里先安装几个插件:
npm i path vinyl-fs through2 –save
修改 new.js
1
2
3.action(function(name,other){
require('../lib/new.js').run(name,other)
});新建 new.js 文件 (注意上面的引用的是 lib 目录下,我们创建的是 src 目录下,后面会转译):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30import { join } from "path";
import vfs from "vinyl-fs";
import through from "through2";
exports.run = function(name, other) {
const cwd = join(__dirname, "../template");//从template目录下拷贝
const dest = process.cwd();//当前执行命令的目录
console.log(`新建一个项目在: ${dest}.`);
vfs
.src(["**/*", "!node_modules/**/*"], { cwd: cwd, cwdbase: true, dot: true })
.pipe(template(dest, cwd))
.pipe(vfs.dest(dest))
.on("end", function() {
console.log("新建项目完成");
})
.resume();
/**
* 执行拷贝
*/
function template(dest, cwd) {
return through.obj(function(file, enc, cb) {
if (!file.stat.isFile()) {
return cb();
}
console.log(file.path.replace(cwd + "/", ""));
this.push(file);
cb();
});
}
};使用 babel 转译代码
开发中我们可能偏向于使用 es2016、es2017,或者 react、vue 等语法。比如我们的 new.js 中使用了 import,所以我们在项目中添加 babel 来转译代码,使得所有的语法都是 es2015 的修改 package.json(在最后面增加)。
1
2
3
4
5
6
7
8
9
10
11
12"devDependencies": {
"babel-cli": "^6.10.1",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-runtime": "^6.9.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-stage-0": "~6.5.0",
"babel-runtime": "^6.9.2"
},
"babel": {
"presets": ["es2015", "stage-0"],
"plugins": ["add-module-exports", "transform-runtime"]
}修改package.json
1
2
3
4"scripts": {
"test":"xxxxxx"
"build": "rm -rf lib && babel src --out-dir lib"
},添加模板文件
新建 D:\newtemplate,并在该目录下随意放入文件,最终会全部拷贝到我们的初始化项目中。
你可以将你设计的框架脚手架什么的放到这里面。
- 编译之后上传 NPM
1 | npm run build |