UNPKG

9.45 kBJavaScriptView Raw
1'use strict';
2/**
3 * @jdf
4 */
5const path = require('path');
6const os = require('os');
7
8//lib自身组件
9const jdfUtils = require('jdf-utils');
10const $ = jdfUtils.base;
11const f = jdfUtils.file;
12const logger = require('jdf-log');
13const fileType = require('./VFS/fileType');
14
15//外部组件
16const stripJsonComments = require('strip-json-comments');
17const VFS = require('./VFS/VirtualFileSystem');
18const bs = require('./server/browserSyncServer');
19
20//define
21const jdf = module.exports;
22
23/**
24 * @配置项
25 */
26jdf.config = require('./config.js');
27
28/**
29 * @widget解析器
30 */
31jdf.widgetParser = require('./buildWidget');
32
33/**
34 * @当前运行命令
35 */
36jdf.currentCommand = '';
37
38/**
39 * 用于使用jdf api时,设置全局配置
40 */
41jdf.setConfig = function(options){
42 // 工程所在目录
43 if(!options){
44 options = {};
45 }
46 jdf.currentDir = path.normalize(options.projectPath || f.currentDir());
47}
48
49/**
50 * @总的初始化函数 from ../index.js
51 * @commander
52 */
53jdf.init = function () {
54 if(!jdf.currentDir){
55 jdf.currentDir = f.currentDir();
56 }
57
58 //读取配置文件 如果没有 config.json 则直接退出。
59 let jdfConfig = jdf.mergeConfig();
60 if (!jdfConfig) {
61 return false;
62 }
63
64 // 中转目录,现在的.jdf-temp/project/projectname。旧版本中的.jdf-temp/temp/projectname,
65 jdf.transferDir = jdf.getTransferDir(path.basename(jdf.currentDir))
66 jdf.transferDir = path.normalize(jdf.transferDir);
67
68 // output输出目录
69 jdf.outputDir = path.join(jdf.currentDir, jdf.config.outputDirName, jdf.config.projectPath);
70 if (!path.relative(jdf.outputDir, jdf.currentDir)) {
71 logger.error('output dir equal project dir, will cover project');
72 return;
73 }
74 return jdfConfig;
75};
76
77jdf.build = function (options, callback) {
78 logger.profile('build');
79
80 var buildType = 'default';
81 if (options.open) {
82 buildType = 'open';
83 }
84
85 logger.profile('require build modules');
86 const build = require('./build');
87 logger.profile('require build modules');
88
89 VFS.setOriginDir(jdf.currentDir);
90 VFS.setTargetDir(jdf.outputDir);
91 VFS.addIgnore(jdf.config.outputDirName, 'dir');
92
93 VFS.readFilesInOriginDirSync();
94 VFS.go().then(() => {
95 return build.init({
96 buildType: buildType,
97 serverDir: jdf.transferDir,
98 projectDir: jdf.currentDir,
99 profileText: 'build'
100 });
101 }).then(port => {
102 console.log('......');
103 callback && callback(port);
104 }).catch(err => {
105 logger.error(err);
106 });
107}
108
109jdf.server = function (options, callback) {
110 bs.startup('', {autoOpen: options.open}, function () {
111 if (!options.watch) {
112 return;
113 }
114
115 bs.watch({watcher: 'local'});
116 });
117}
118
119/**
120 * 退出jdf进程
121 */
122jdf.exit = function(){
123 process.exit(1);
124}
125
126jdf.output = function (outputList, options) {
127 logger.profile('output');
128
129 for(let source of outputList){
130 if(!f.exists(source)){
131 logger.error(`${source} is not found!`);
132 return;
133 }
134 }
135
136 var ignoreFiles = [];
137 if (jdf.config.output.excludeFiles.length > 0) {
138 ignoreFiles = jdf.config.output.excludeFiles.split(',');
139 }
140
141 var outputType = 'default';
142 var outputCustom = jdf.config.outputCustom;
143
144 if (options.debug) {
145 outputType = 'debug';
146 }
147 else if (options.plain) {
148 outputType = 'plain';
149 }
150 else if(options.preview){
151 outputType = 'preview';
152 }
153 else if(options.static){
154 outputType = 'static'
155 }
156
157 if (outputCustom.length > 0 && outputList.length == 0) {
158 outputList = outputCustom.split(',');
159 }
160
161 VFS.setOriginDir(jdf.currentDir);
162 VFS.setTargetDir(jdf.outputDir);
163 VFS.addIgnore(jdf.config.outputDirName, 'dir');
164 VFS.addIgnore(ignoreFiles, 'glob');
165
166 if(outputType == 'static'){
167 fileType.outputIgnore.extname = fileType.outputIgnore.extname.concat(fileType.extname.html);
168 }
169
170 VFS.readFilesInOriginDirSync([]);
171 return VFS.go().then(function () {
172 const output = require('./output');
173 return output.init({
174 outputType: outputType,
175 outputList: outputList
176 });
177 }).then(() => {
178 logger.profile('output');
179 }).catch(err => {
180 logger.error(err);
181 });
182}
183
184// 中转目录,现在的.jdf-temp/project/projectname。旧版本中的.jdf-temp/temp/projectname,
185jdf.getTransferDir = function (projectname) {
186 return path.join(os.tmpdir(), '.jdf-temp/project', projectname);
187}
188
189/** 获取用户自定义的配置
190 * return {object} userConfig
191 */
192jdf.getUserConfig = function (userConfigPath) {
193 if (f.exists(userConfigPath)) {
194 try {
195 var data = f.read(userConfigPath);
196 data = JSON.parse(stripJsonComments(data));
197 if (typeof (data) == 'object') {
198 return data;
199 }
200 } catch (e) {
201 logger.error('config.json format error');
202 }
203 }
204}
205
206jdf.checkValidDir = function () {
207 let isJDFDir = jdf.mergeConfig();
208 if (!isJDFDir) {
209 logger.error(`${jdf.currentDir} is not a jdf root dir, please check the right path or use "jdf s -o" to run a local server.`);
210 logger.info(`jdf exit.`);
211 process.exit();
212 }
213}
214
215/**
216 * @读取配置文件config.json, 覆盖默认配置
217 */
218jdf.mergeConfig = function () {
219 var userConfigPath = path.join(jdf.currentDir, jdf.config.configFileName);
220 var userConfig = jdf.getUserConfig(userConfigPath);
221 if (userConfig) {
222 return $.merageObj(jdf.config, userConfig);
223 }
224}
225
226/**
227 * @从服务器端下载文件 todo:检查版本号
228 */
229jdf.download = function (pathItem, targetDir, targetName) {
230 var url = jdf.config[pathItem];
231 var cacheDir = path.normalize(jdf.cacheDir + '/' + pathItem + '.tar');
232
233 logger.info('jdf downloading');
234
235 f.download(url, cacheDir, function (data) {
236 if (data == 'ok') {
237 f.tar(cacheDir, targetDir, function () {
238 //强制改项目名同时修改config.json中的projectPath字段
239 f.renameFile(path.resolve(targetDir, 'jdf_demo'), path.resolve(targetDir, targetName))
240 var configFilePath = path.resolve(targetDir, targetName, jdf.config.configFileName);
241 f.readJSON(configFilePath, function (json) {
242 json.projectPath = targetName;
243 f.write(configFilePath, JSON.stringify(json, null, '\t'));
244 logger.info(targetName + ' install done');
245 })
246 });
247 }
248 })
249}
250
251/**
252 * @获取项目前缀名字
253 * @仅从配置文件中取,不再支持branch/trunk 2014-5-24
254 * @del --> 1. d:\product\index\trunk ===> product/index
255 * @del --> 2. d:\product\index\branches\homebranches ===> product/index
256 * @del --> 3. d:\product\index\homebranches ===> product
257 */
258jdf.getProjectPath = function () {
259 var currentDir = jdf.currentDir,
260 nowDir = '',
261 result = '';
262 if (jdf.config.projectPath != null) {
263 result = jdf.config.projectPath;
264 } else {
265 //当前文件夹的文件夹命名为projectPath 2014-6-9
266 result = path.basename(jdf.currentDir);
267 }
268 return result;
269}
270
271
272/**
273 * @项目工程目录初始化
274 * @time 2014-2-19 10:21:37
275 */
276jdf.createStandardDir = function (dir, options) {
277 // 如果准备在当前文件夹下创建jdf工程,则至少要保证不存在config.json
278 if (!dir && options.current) {
279 if (f.exists('./config.json')) {
280 logger.error('This directory may already be a jdf project, please check if there is a `' + jdf.config.configFileName +'` file.')
281 return;
282 }
283 }
284
285 var dirArray = [];
286 dirArray.push(jdf.config.cssDir);
287 dirArray.push(jdf.config.imagesDir);
288 dirArray.push(jdf.config.jsDir);
289 dirArray.push(jdf.config.htmlDir);
290 dirArray.push(jdf.config.widgetDir);
291
292 if (dir) {
293 dir += '/';
294 if (options.current) {
295 logger.warn('Ignored the --current option');
296 }
297 } else {
298 if (options.current) {
299 dir = './';
300 } else {
301 dir = 'jdf_init/';
302 }
303 }
304
305 for (var i = 0; i < dirArray.length; i++) {
306 f.mkdir(path.resolve(dir, dirArray[i]));
307 }
308
309 var fileArray = [];
310 fileArray[0] = jdf.config.configFileName;
311 fileArray[1] = path.join(jdf.config.htmlDir, 'index.html');
312 fileArray[2] = path.join(jdf.config.cssDir, 'style.scss');
313
314 var templateDir = path.resolve(__dirname, '../template/');
315
316 for (var i = 0; i < fileArray.length; i++) {
317 if (!f.exists(path.resolve(dir, fileArray[i]))) {
318 f.write(path.resolve(dir, fileArray[i]), f.read(path.resolve(templateDir, fileArray[i])));
319 }
320 }
321 logger.info('jdf project directory init done!');
322}
323
324/**
325 * @将组件安装到本地
326 */
327jdf.install = function(componentName, options){
328 const install = require('./install');
329
330 if(componentName){
331 install.download(componentName);
332 }else if(options.list){
333 install.list();
334 }
335}
336
337/**
338 * @清除项目缓存文件夹
339 */
340jdf.clean = function () {
341 logger.profile('clean');
342 const shell = require('shelljs');
343 const tmpRootPath = path.resolve(os.tmpdir(), '.jdf-temp');
344 shell.rm('-rf', tmpRootPath);
345 logger.info('cache dir clean done');
346 logger.profile('clean');
347}