最近有一个这样的需求: 写一个列表页面的模板, 然后所有的列表页面都基于这个模板去实现, 为了避免复制黏贴的操作所以决定用命令来实现一个, 正好 node 自带了这样的功能, 记录一下实现过程。
首先在桌面上新建一个文件夹, 名字无所谓只是为了测试而已, 新建一个main.js
文件, 然后npm init
一个package.json
可以在这里看到 node 文件操作的方法, 我们的目的是从一个文件中拷贝出主要的代码到另一个文件中, 所以主要用到的就是读取和写入命令, 举个例子
1 |
|
在我们生成的package.json
中, 我们需要加入一行我们自定义的命令以及执行的js路径, 比如这里我就叫mycmd
1 |
|
最后执行npm link
然后就可以使用自定义的命令了, 比如mycmd hello
, 如果没有报错的话, 目录的文件夹下会生成一个叫hello的文件, 并拥有template.js
中的内容。
但实际的开发远远不是这么简单, 虽然功能实现了, 但是往往需要一些额外的操作, 我们目前的前端框架是 angular 封装的组件自然也是一个 angular 组件模板, 这就回有四个文件, .css .html 和两个 .ts 文件, 所以大概的工作流程是, 先使用 ng 命令创建一个组件, 然后把写好组件的信息拷贝到新创建的组件上。这里有两个问题:
1.如何让js执行其他命令 2.生成文件的命名处理和文件中参数的处理(比如页面的title)
第一个问题还是蛮好解决的, 我们可以借助child_process
这个模块来执行其他的命令, 比如 shell python 都可以, 具体可以看这里
1 |
|
到这里我们可以用我们的命令去创建一个 angular 组件了, 那接下来就是去替换掉 angular 组件的内容了。css 和 spec.ts 都还好说, 因为这两个基本上没有什么更改的内容, 主要的内容在 .html 和 .ts 上面。我们封装一个组件肯定要有一些参数的, 那么如何将这些参数替换成指定的内容呢~
其实我也没有找到太好的方法, 所以我用的是字符串替换, = = 类似于这样:
1 |
|
比如我的模板是这样的
1 |
|
那么生成出来的文件就是这样的:
1 |
|
这个只是简单的处理方式, 但是到了 .ts 文件上就很头疼, 因为你不能确定你的组件就只有一个英文单词的名称, 所以肯定需要支持驼峰式命名组件, 而驼峰式命名组件又会被 angular 解析成横线式文件 + 驼峰式组件名称, 所以要特别处理组件注解和组件类名, 也就是这一部分:
1 |
|
那么如果按照替换字符串来说的话, 需要驼峰转小写和小写转驼峰的方法:
1 |
|
所以执行的替换脚本大概是这样
1 |
|
template.js
文件内容:
1 |
|
这样对于驼峰命名的类比如aFreeMiBand
, 在@Component
注解中会变为a-free-mi-band
, 而类名会变为AFreeMiBand
这样就完全符合 angular 组件的命名规则了。为了方便, 我直接把这个带有 main.js 和 package.json 的文件夹拷贝到项目中, 这个时候问题又来了, 因为路径的原因, 我们往往不能在这个文件夹下执行命令, 那么怎么才能在工程的任意文件夹下执行命令, 并且能准确拷贝template.js中的内容呢?
其实就是使用相对路径而已。
1 |
|
最后, 我们在我们 web 工程的根目录下面 npm link 自己定义命令的文件夹
之后, 就可以随意使用自己的命令了。
完整的组件替换:
1 |
|