UNPKG

10.8 kBJavaScriptView Raw
1/// <reference path="../typings/globals/node/index.d.ts" />
2'use strict';
3const fs = require('fs-extra');
4
5let aConfigDirList = fs.readdirSync(fws.tplConfigPath),//获取配置目录所有文件列表
6 aConfigList = [],
7 re = /^(\w*)(.json)$/i;
8
9aConfigDirList.forEach((item,index)=>{
10 if(re.test(item)){
11 aConfigList.push(item.substr(0,item.length - 5));
12 };
13});
14
15class create{
16 constructor(name,options){
17 const _ts = this;
18
19 //任务依赖模块
20 let m = _ts.m = {
21 fs:require('fs-extra'),
22 path:require('path'),
23 tip:require('../lib/tip'), //文字提示
24 getType:require('../lib/getType'), //获取数据类型
25 pathInfo:require('../lib/getPathInfo'), //获取目标路径的相关信息
26 getDirFilesPath:require('../lib/getDirFilesPath') //获取目录文件数据
27 },
28 config = _ts.config = {
29 // name:'demo', //<string>,项目名称
30 // template:'default' //<string>,项目配置文件名
31 };
32 config.name = name;
33
34 config.template = typeof options.template === 'string' ? options.template : 'default';
35 config.unittest = options.unittest;
36
37 _ts.starTime = new Date();
38 }
39
40 /**
41 * 任务初始入口
42 */
43 init(){
44 const _ts = this,
45 m = _ts.m,
46 config = _ts.config;
47 let f = async ()=>{
48 let pList = _ts.start();
49
50 for(let i of pList){
51 await i;
52 };
53
54 return '项目【'+config.name+'】创建成功。用时'+ (new Date() - _ts.starTime) + 'ms';
55 };
56
57 f().then(v => {
58 m.tip.highlight('========================================');
59 m.tip.highlight(v);
60 m.tip.highlight('========================================');
61 }).catch(err => {
62 m.tip.error(err);
63 });
64 }
65
66 /**
67 * 创建方法
68 */
69 start(){
70 const _ts = this,
71 m = _ts.m,
72 config = _ts.config;
73
74 //初始化相关目录
75 let initDir,
76 initFilesData,
77 taskListData = [],
78 taskList = [];
79
80 //定义初始化目录任务
81 initDir = new Promise((resolve,reject)=>{
82 //检查项目名称参数是否传入
83 if(config.name === undefined){
84 reject('项目名称不允许为空');
85 };
86
87 //获取设置项目的相关目录信息
88 let projectPath = m.path.join(fws.cmdPath,config.name),
89 projectIsExist = m.pathInfo(projectPath).type === 'dir';
90
91 //检查项目目录是否已经存在
92 if(projectIsExist){
93 reject('警告:'+config.name+'目录已存在。请更换项目名称或删除原有项目之后重试。');
94 };
95
96 fws.srcPath = m.path.join(projectPath,'src');
97 fws.devPath = m.path.join(projectPath,'dev');
98 fws.distPath = m.path.join(projectPath,'dist');
99 fws.testPath = m.path.join(projectPath,'test');
100
101 //创建目录
102 fs.mkdirSync(projectPath);
103 m.tip.success('创建 '+projectPath);
104
105 fs.mkdirSync(fws.srcPath);
106 m.tip.success('创建 '+fws.srcPath);
107
108 fs.mkdirSync(fws.devPath);
109 m.tip.success('创建 '+fws.devPath);
110
111 fs.mkdirSync(fws.distPath);
112 m.tip.success('创建 '+fws.distPath);
113
114 if(config.unittest){
115 fs.mkdirSync(fws.testPath);
116 m.tip.success('创建 '+fws.testPath);
117
118 //创建单元测试演示及依赖文件
119 let demoTestPath = m.path.join(fws.testPath,'main.test.js'),
120 packagePath = m.path.join(projectPath,'package.json'),
121 packageTplPath = m.path.join(fws.tplPath,'json','packageTpl.json'),
122 packageTpl = JSON.parse(m.fs.readFileSync(packageTplPath).toString());
123 m.fs.copySync(
124 m.path.join(fws.tplPath,'test','main.test.js'),
125 demoTestPath
126 );
127 m.tip.success('创建 '+demoTestPath);
128
129 packageTpl.author = fws.config.author;
130 packageTpl.name = config.name;
131
132 m.fs.writeFileSync(packagePath,JSON.stringify(packageTpl,null,4));
133 m.tip.success('创建 '+packagePath);
134 };
135
136 //创建项目配置文件
137 let projectType = (()=>{
138 let type = config.template.split('_')[0],
139 list = ['vue','react'];
140 for(let i=0,len=list.length; i<len; i++){
141 let item = list[i];
142 if(item === type){
143 return item;
144 };
145 };
146 return undefined;
147 })(),
148 fws_config = {
149 author:fws.config.author, //作者
150 mail:fws.config.mail, //邮箱
151 projectName:config.name, //项目名称
152 template:config.template, //模版
153 projectType:projectType, //模版类型
154 createTime:new Date().valueOf(), //创建时间
155 updater:undefined, //更新者
156 updateTime:undefined, //更新时间
157 distReplace:fws.config.distReplace, //资源匹配对应关系
158 srcSync:fws.config.srcSync, //src同步目录配置
159 devSync:fws.config.devSync, //dev同步目录配置
160 distSync:fws.config.distSync //dist同步目录配置
161 },
162 fwsConfigPath = m.path.join(projectPath,'fws_config.js');
163
164 fws_config = `module.exports = ${JSON.stringify(fws_config,null,4)};`;
165
166 fs.writeFileSync(fwsConfigPath,fws_config);
167 m.tip.success('创建 '+fwsConfigPath);
168
169 //初始化项目文件结构数据
170 (initFilesData = (dirPath,configData)=>{
171 for(let i in configData){
172
173 //得到当前路径
174 let currentPath = m.path.join(dirPath);
175
176 if(i === '__files__'){
177 configData[i].forEach((item,index)=>{
178 taskListData.push({
179 src:m.path.join(fws.tplPath,item[0]),
180 target:m.path.join(currentPath,item[1])
181 });
182 });
183 }else if(i !== '__name__'){
184 currentPath = m.path.join(currentPath,i); //设置当前路径为新目录
185 fs.mkdirSync(currentPath); //创建目录
186 m.tip.success('创建 '+currentPath);
187
188 if(m.getType(configData[i]) === 'object'){
189 initFilesData(currentPath,configData[i]); //如果是目录则无限级循环
190 };
191 };
192 };
193 })(fws.srcPath,_ts.getTemplate());
194
195 resolve('项目目录结构初始成功');
196 });
197
198 //将初始化目录添加到任务列表
199 taskList.push(initDir);
200
201 //遍历项目文件结构数据,并将文件初始任务追加到任务列表
202 taskListData.forEach((item,index)=>{
203 taskList.push(_ts.taskInit(item.src,item.target));
204 });
205
206 return taskList;
207 }
208
209 /**
210 * 任务初始化
211 * @param {*} src
212 * @param {*} target
213 */
214 taskInit(src,target){
215 const _ts = this,
216 m = _ts.m,
217 config = _ts.config;
218
219 let srcInfo = m.pathInfo(src);
220
221 return new Promise((resolve,reject)=>{
222 if(srcInfo.type === 'file'){
223 let readAble = fs.createReadStream(src), //创建读取流
224 writAble = fs.createWriteStream(target); //创建写入流
225 readAble.pipe(writAble); //管道写入文件
226 m.tip.success('创建 '+target);
227 resolve({
228 status:'success',
229 path:target
230 });
231 }else if(srcInfo.type === 'dir'){
232
233 //如果是目录,则将目录直接copy到对应的项目中
234 target = m.path.join(target,srcInfo.name);
235 m.tip.success('拷贝 '+target);
236 fs.copy(src,target,err => {
237 if(err){
238 reject({
239 status:'error',
240 msg:err
241 });
242 }else{
243 resolve({
244 status:'success',
245 path:target
246 });
247 };
248 });
249 };
250 });
251 }
252
253 /**
254 * 用于获取模版配置信息
255 */
256 getTemplate(){
257 const _ts = this,
258 m = _ts.m,
259 config = _ts.config;
260
261 let tplFilePath = m.path.join(fws.tplConfigPath,config.template+'.json'),
262 tplConfig;
263
264 if(m.pathInfo(tplFilePath).type === 'file'){
265 tplConfig = JSON.parse(fs.readFileSync(tplFilePath));
266 }else{
267 throw new Error(tplFilePath + '不存在');
268 };
269
270 return tplConfig;
271 }
272};
273
274module.exports = {
275 regTask:{
276 command:'[name]',
277 description:'创建一个新的空项目',
278 option:[
279 ['-t, --template [template]','项目模版。默认pc,可选参数 '+aConfigList.toString()],
280 ['-u, --unittest','创建单元测试模块文件及依赖配置']
281 ],
282 help:()=>{
283 console.log('');
284 console.log(' 补充说明:');
285 console.log(' ------------------------------------------------------------');
286 console.log(' 如何自定义项目模版见 '+fws.tplPath);
287 },
288 action:create
289 },
290 fun:()=>{}
291};
\No newline at end of file