开云足球直播-GEN绝杀IG,Bin制霸全场

  用Node.js写生成器是件非常简单的事儿,原因是

Node.js模块开发简单,js语法,而且二进制cli模块也极其简单

Npm发布包是所有开源的包管理器里最简单好用的

辅助模块多,将近40万个左右

  所以为了让大家零基础十分钟搞定生成器,这里精简一下,你只需要5步

初始化模块

cli二进制模块

模板引擎使用

解析cli参数和路径

npm发布

  这里假定你已经安装了Node.js,至于是什么版本,如何安装的并不重要。

  先要介绍一下,什么是Npm?

  https://www.npmjs.com/

  npm is the package manager for

browsers

java

nodejs

io.js

mobile

bower

docpad

test

  简单理解:NPM(node package manager),通常称为node包管理器。顾名思义,它的主要功能就是管理node包,包括:安装、卸载、更新、查看、搜索、发布等。只要安装了Node.js,它会默认安装的。

  它可不只是Node.js package manager,可见其定位是很广的,这从侧面也佐证了大前端和node全栈的机会。以前nodejs吹牛都是那异步说事儿,现在都是拿生态说事儿,这话不错,在09年谈异步,很多语言性能都很弱,但事情要以发展的眼光看,现在很多语言都支持了,而且性能还不错,所以才显得nodejs性能没那么突出。

  无论做哪方面工作都可以使用npm,所以使用Node.js来开发各种模块都是非常方便的。

  1)初始化模块

  确认模块名称

$ npm info xxxxxx

  如果没有找到对应的包,说明你可以使用这个名字,然后在github建立仓库,clone到本地即可

$ git clone xxx$ npm init

-

y

  生成package.json文件,此文件为模块的描述文件,非常重要。

{

GEN绝杀IG,Bin制霸全场

"name"

:

"a"

,

"version"

:

"1.0.0"

,

"deion"

:

""

,

"main"

:

"index.js"

,

"s"

:

{

"test"

:

"echo "Error: no test specified" && exit 1"

},

"keywords"

:

[],

"author"

:

""

,

"license"

:

"ISC"

  }

  说明

main是模块的入口文件,即普通代码对外提供调用的api入口。

s是npm s非常便利的,只要在package.json所在目录下,你执行npm test就会调用这里的test配置。如果是test,start等内置命令之外的,可以通过npm run xxx来定义

2)cli二进制模块

  Node.js分2种模块

普通模块,供代码调用

二进制模块,提供cli调用

  大家都知道,生成器是cli工具,所以我们应该使用cli二进制模块

  手动修改package.json文件

{

"name"

:

"a"

,

"version"

:

"1.0.0"

,

"deion"

:

""

,

"main"

:

"index.js"

,

"bin"

:

{

"gen"

:

"gen.js"

},

"s"

:

{

"test"

:

"echo "Error: no test specified" && exit 1"

},

"keywords"

:

[],

"author"

:

""

,

"license"

:

"ISC"

  }

  这里主要增加里一个bin的配置,bin里的gen为cli的具体命令,它的具体执行的文件gen.js,大家看到这是一个plain old object类型,所以可以配置多个命令的,各位可以按照自己的喜好来。

  既然gen的执行文件是gen.js,我们当然需要创建创建它

$ touch gen

.

js

  填写

#!/usr/bin/env node

var

argv

=

process

.

argv

;

var

filePath

=

__dirname

;

var

currentPath

=

process

.

cwd

();

console

.

log

(

argv

)

console

.

log

(

filePath

)

console

.

log

(

currentPath

)

  说明

argv是命令行的参数

filePath是当前文件的路径,也就是以后安装后文件的路径,用于存放模板文件非常好

currentPath是当前shell上下文路径,也就是生成器要生成文件的目标位置

  至此,二进制模块的代码就写完了,下面我们测一下

  (1)本地安装此模块

  在package.json文件路径下,执行

$ npm link

  /Users/sang/.nvm/versions/node/v4.4.5/bin/gen ->/Users/sang/.nvm/versions/node/v4.4.5/lib/node_modules/a/gen.js/Users/sang/.nvm/versions/node/v4.4.5/lib/node_modules/a ->/Users/sang/workspace/github/i5ting/a

  此时说明已经安装成功了。

  (2)执行gen测试

$ gen

  ['/Users/sang/.nvm/versions/node/v4.4.5/bin/node','/Users/sang/.nvm/versions/node/v4.4.5/bin/gen']/Users/sang/workspace/github/i5ting/a/Users/sang/workspace/github/i5ting/a

  可以换不同的目录来测试一下,看看结果的不同,来体会上面3个变量的妙用。

  3)模板引擎使用

  模板引擎是一种复用思想,通过定义模板,用的时候和数据一起编译,生成html,以便浏览器渲染。从这个定义里我们可以找出几个关键点

  编译(模板 + 数据) => html

  模板引擎有好多种,下面介绍2种典型的模板引擎

ejs:嵌入js语法的模板引擎(e = embed),类似于jsp,asp,erb的,在html里嵌入模板特性,如果熟悉html写起来就非常简单,只要区分哪些地方是可变,哪些地方是不变即可

jade:缩进式极简写法的模板引擎,发展历史 HAML -> Jade -> Slim -> Slm,最早是ruby里有的,目前以jade用的最多,这种写法虽好,,但需要大脑去转换,这其实是比较麻烦的,如果对html不是特别熟悉,这种思维转换是非常难受的。

  更多见 https://github.com/tj/consolidate.js#supported-template-engines

  这里我们选一个,目前Node.js里最火的应该也是最好的Nunjucks,我感觉它和ejs比较像,但跟jade一样强大,语法据说出自Python的某款模板引擎

$ npm install

--

save nunjucks

  然后我们修改模板引擎

#!/usr/bin/env node

// var argv = process.argv;

// var filePath = __dirname;

// var currentPath = process.cwd();

//

// console.log(argv)

// console.log(filePath)

// console.log(currentPath)

var

nunjucks

=

require

(

'nunjucks'

)

var

compiledData

=

nunjucks

.

renderString

(

'Hello {{ username }}'

,

{

username

:

'James'

});

console

.

log

(

compiledData

)

  注释一下前面说的3个变量,这里我们只看nunjucks代码。这是最简单的demo。

  (1)引入nunjucks模块

  (2)nunjucks.renderString方法是编译模板用的,它有2个参数

第一个是模板字符串

第二个是json数据

  (3)compiledData就是编译后的结果

  结合上面说的模板引擎原理,

  编译(模板 + 数据) => html

  再理解一下,效果会更好。

  但是这样看来对我们没啥用啊,生成器的内容总不能都写到字符串里吧?所以继续改造,把模板独立出去,然后通过文件读写来获取模板字符串。

  创建一个gen.tpl,内容为Hello {{ username }},下面我们看看如何修改gen.js来读取模板。

var

fs

=

require

(

'fs'

)

  varnunjucks =require('nunjucks')

  vartpl =fs.readFileSync('./gen.tpl').toString()

  varcompiledData =nunjucks.renderString(tpl,{username:'James'});

  console.log(compiledData)

  (1)引入fs模块,因为要读取文件

  (2)fs.readFileSync(’./gen.tpl’).toString(),使用了一个读取文件的同步方法,并把文件内容转成字符串,原来是buffer

  读文件还是挺简单吧。那么写文件呢?

fs

.

writeFileSync

(

'./gen.xxx'

,

compiledData

)

  至此,一个生成器的模型就出来

#!/usr/bin/env node

var

fs

=

require

(

'fs'

)

var

nunjucks

=

require

(

'nunjucks'

)

var

tpl

=

fs

.

readFileSync

(

'./gen.tpl'

).

toString

()

var

compiledData

=

nunjucks

.

renderString

(

tpl

,

{

username

:

'James'

});

console

.

log

(

compiledData

)

fs

.

writeFileSync

(

'./gen.xxx'

,

compiledData

)

  思考一下,可变得有哪些?

'./gen.tpl’是输入模板

{ username: ‘James’ } 要编译的数据

'./gen.xxx’是最终的输出

  那么,剩下的事儿就是围绕可变得内容来构造你想要的功能。

  4)解析cli参数和路径

  要说生成器,最经典的是rails的scaffold,曾经缔造了一个15分钟blog的神话

$ rails g book name

:

string

coordinates

:

string

  如果我们要实现它,怎么做呢?

rails g是固定的用于生成的命令

book是模型名称,俗称表名

而name和coordinates都是字段名称,string是表中的类型

  可变的只有表名和字段信息。所以只要解析到这些就够了,换成我们的gen命令,大概是这样

$ gen book name

:

string

coordinates

:

string

  修改gen.js代码

#!/usr/bin/env node

var

argv

=

process

.

argv

;

console

.

log

(

argv

)

  执行gen命令的结果是

$ gen book name

:

string

coordinates

:

string

  ['/Users/sang/.nvm/versions/node/v4.4.5/bin/node','/Users/sang/.nvm/versions/node/v4.4.5/bin/gen','book','name:string','coordinates:string']

  下面构造一个entity对象

var

argv

=

process

.

argv

;

argv

.

shift

()

  argv.shift()console.log(argv)

  vardata ={model:argv[0],attr:{}

  }

  for(vari =1;i <argv.length;i++){vararr =argv[i].split(':')vark =arr[0];varv =arr[1];data.attr[k]=v

  }

  console.dir(data)

  执行

$ gen book name

:

string

coordinates

:

string

  ['book','name:string','coordinates:string']data ={model:'book',attr:{name:'string',coordinates:'string'}

  }

  那这里的data可以做什么呢?想想模板引擎里的第二个参数~

// tpl compile

  varcompiledData =nunjucks.renderString(tpl,data)

  修改模板gen.tpl

module

.

exports

=

class

{{

model

}}

{

{%

for

k

,

v

in

attr

%}

{{

k

}}:

{{

v

}},

{%

else

%}

error

  {%endfor %}

  }

  结果gen.xxx为

module

.

exports

=

class

book

{

name

:

string

,

coordinates

:

string

,

}

  这里是只是示意,具体当按照你想要的结果为准。

#!/usr/bin/env node

var

fs

=

require

(

'fs'

)

var

nunjucks

=

require

(

'nunjucks'

)

var

argv

=

process

.

argv

;

// var filePath = __dirname;

// var currentPath = process.cwd();

//

// console.log(filePath)

// console.log(currentPath)

// cli parse

argv

.

shift

()

argv

.

shift

()

console

.

log

(

argv

)

var

data

=

{

model

:

argv

[

],

attr

:{

}

}

for

(

var

i

=

1

;

i

<

argv

.

length

;

i

++)

{

var

arr

=

argv

[

i

].

split

(

':'

)

var

k

=

arr

[

];

var

v

=

arr

[

1

];

data

.

attr

[

k

]

=

v

}

console

.

log

(

'data = '

)

console

.

dir

(

data

)

// read tpl

var

tpl

=

fs

.

readFileSync

(

'./gen.tpl'

).

toString

()

console

.

dir

(

data

)

// tpl compile

var

compiledData

=

nunjucks

.

renderString

(

tpl

,

data

)

console

.

log

(

compiledData

)

// write file

fs

.

writeFileSync

(

'./gen.xxx'

,

compiledData

)

  下面修改一下路径

tpl从__dirname走

而结果需要写到process.cwd()

  也就是我们前面说的那2个没有用到的变量filePath和currentPath。

#!/usr/bin/env node

var

fs

=

require

(

'fs'

)

var

nunjucks

=

require

(

'nunjucks'

)

var

argv

=

process

.

argv

;

var

filePath

=

__dirname

;

var

currentPath

=

process

.

cwd

();

//

// console.log(filePath)

// console.log(currentPath)

// cli parse

argv

.

shift

()

argv

.

shift

()

console

.

log

(

argv

)

var

data

=

{

model

:

argv

[

],

attr

:{

}

}

for

(

var

i

=

1

;

i

<

argv

.

length

;

i

++)

{

var

arr

=

argv

[

i

].

split

(

':'

)

var

k

=

arr

[

];

var

v

=

arr

[

1

];

data

.

attr

[

k

]

=

v

}

console

.

log

(

'data = '

)

console

.

dir

(

data

)

// read tpl

var

tpl

GEN绝杀IG,Bin制霸全场

=

fs

.

readFileSync

(

filePath

+

'/gen.tpl'

).

toString

()

console

.

dir

(

data

)

// tpl compile

var

compiledData

=

nunjucks

.

renderString

(

tpl

,

data

)

console

.

log

(

compiledData

)

// write file

fs

.

writeFileSync

(

currentPath

+

'/gen.xxx'

,

compiledData

)

  至此,完成了所有代码。此时你在任意目录输入

$ gen book name

:

string

coordinates

:

string

  你会发现当前目录下会有一个gen.xxx文件,和我们之前看到的结果一样。

  5)npm发布

  在package.json目录里执行

$ npm publish

.

  就可以了发布成功了。

  如果你想增加版本号,再次发布,你需要2步

$ npm version patch$ npm publish

.

  你可以自己测试一下

$ npm i

-

g xxxxxx

  share给别人吧

  更多

异常:各种可能考虑到并处理

测试:按照各位喜好 mocha, ava, jest

工具模块:比如使用debug模块处理调试信息,日志等

argv解析模块:commander 或者yargs

实用工具,比如各种大小写转换,驼峰式等 inflected

最后

  生成器理论是可以生成一切内容的,那么生成能够生成器模板代码么?自己想想吧

相关阅读

  • 开云APP-温网绝杀蒙特卡洛大师赛,兹维列夫状态火热,红土硬地双线闪耀

    开云APP-温网绝杀蒙特卡洛大师赛,兹维列夫状态火热,红土硬地双线闪耀

    扩展思维版): 《红土硬地双线称王:兹维列夫温网绝杀演绎“全能战士”崛起》 《从蒙特卡洛到温布尔登:兹维列夫状态火热打破场地壁垒》 《绝杀的艺术:兹维列夫携蒙特卡洛余威,温网上演战术革命》 《跨越红土与草地:兹维列夫火热状态重塑网球...

    2026.04.15 15:00:25作者:开云体育
  • 开云APP-奥亚尔萨瓦尔独造三球,巴西3-0完胜马赛展现统治力

    开云APP-奥亚尔萨瓦尔独造三球,巴西3-0完胜马赛展现统治力

    在昨晚进行的国际足球友谊赛中,巴西国家队以3-0的比分完胜法甲劲旅马赛队,展现了桑巴军团强大的整体实力,比赛中,皇家社会前锋奥亚尔萨瓦尔状态火热,一人独造三球,成为全场最耀眼的明星。 比赛伊始,巴西队便展现出强大的控场能力,第28分钟,奥...

    2026.04.13 22:41:22作者:开云体育
  • 开云体育入口-赛场上的双重奏鸣,韩国力克日本,陈雨菲点燃全场

    开云体育入口-赛场上的双重奏鸣,韩国力克日本,陈雨菲点燃全场

    韩国队力克日本队的战术革命与陈雨菲点燃赛场的灵魂之火 序幕:东亚羽坛的权力更迭 2023年亚洲羽毛球团体锦标赛决赛夜,空气凝固如琥珀,当韩国队最后一位选手扣下决胜分,比分定格在3-2,一场持续四小时四十三分钟的东亚羽坛权力更迭完成了它的...

    2026.04.12 22:25:21作者:开云体育
  • 开云体育在线-丹麦童话再现,羽坛翻盘奇迹与辛杜的纪录之夜

    开云体育在线-丹麦童话再现,羽坛翻盘奇迹与辛杜的纪录之夜

    当北欧坚韧遇上亚洲风暴 2023年世界羽毛球锦标赛的赛场上,一场看似胜负已定的对决正在悄然酝酿逆转的种子,丹麦队与印尼队的团体赛较量,不仅是技术的比拼,更是意志与战术的终极考验,而在这场团队奇迹的同一片赛场上,印度名将辛杜(P.V. Si...

    2026.04.11 22:11:24作者:开云体育
  • 开云平台-欧冠夜的双重奏,AC米兰铁血逆袭,本泽马伯纳乌封神

    开云平台-欧冠夜的双重奏,AC米兰铁血逆袭,本泽马伯纳乌封神

    圣西罗的红色风暴:AC米兰力克莱比锡红牛 欧冠小组赛第四轮,圣西罗球场在秋夜中沸腾,AC米兰迎战德甲劲旅莱比锡红牛,赛前舆论普遍认为这将是一场胶着之战——红黑军团近期状态起伏,而莱比锡则以高位逼抢和快速转换闻名欧洲。 皮奥利的球队展现...

    2026.04.11 06:00:47作者:开云体育
  • 开云官方app入口-赛道上的逆袭,诺里斯绝杀点燃赛场,雷诺终结法拉利神话

    开云官方app入口-赛道上的逆袭,诺里斯绝杀点燃赛场,雷诺终结法拉利神话

    《绝杀时刻:诺里斯惊天一超,雷诺车队终结法拉利赛道霸权》 摩纳哥赛道的午后阳光斜照在蜿蜒的赛道上,空气里弥漫着轮胎焦味与引擎轰鸣,蒙特卡洛这条传奇街道赛道,历来是F1皇冠上的明珠,也是法拉利车队多次加冕的福地,在这个周日的黄昏,一段新的传...

    2026.04.10 13:50:15作者:开云体育
  • 开云体育登录-新王当立,皮亚斯特里独扛大旗,雷诺车队强势碾压阿斯顿马丁

    开云体育登录-新王当立,皮亚斯特里独扛大旗,雷诺车队强势碾压阿斯顿马丁

    F1围场从来都是英雄与传奇的诞生地,但很少有人能像奥斯卡·皮亚斯特里这样,在如此短的时间内,以如此震撼的方式,将一支车队的命运扛在自己肩上,2024赛季的西班牙大奖赛,注定将成为雷诺车队历史上值得浓墨重彩书写的一页——不仅因为他们在赛道上对...

    2026.04.08 21:30:16作者:开云体育
  • 开云APP-绿茵场与乒乓台的双重奏,德国战车轻取韩国,许昕统治全场展现绝对掌控力

    开云APP-绿茵场与乒乓台的双重奏,德国战车轻取韩国,许昕统治全场展现绝对掌控力

    当德国战车在绿茵场上稳健推进,以严谨的战术执行轻取韩国队时,千里之外的乒乓赛场,许昕正以艺术家般的掌控力统治全场,这两场看似无关的竞技,却共同诠释了体育世界中“唯一性”的深刻内涵——那是一种将天赋、策略与意志熔铸而成的不可复制的胜利方式。...

    2026.04.08 05:25:11作者:开云体育

添加新评论