1 |
|
2 | 'use strict';
|
3 | const fs = require('fs-extra');
|
4 |
|
5 | let aConfigDirList = fs.readdirSync(fws.tplConfigPath),
|
6 | aConfigList = [],
|
7 | re = /^(\w*)(.json)$/i;
|
8 |
|
9 | aConfigDirList.forEach((item,index)=>{
|
10 | if(re.test(item)){
|
11 | aConfigList.push(item.substr(0,item.length - 5));
|
12 | };
|
13 | });
|
14 |
|
15 | class 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 |
|
30 |
|
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,
|
159 | devSync:fws.config.devSync,
|
160 | distSync:fws.config.distSync
|
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 |
|
212 |
|
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 |
|
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 |
|
274 | module.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 |