UNPKG

7.68 kBJavaScriptView Raw
1"use strict";
2
3const path = require('path');
4const fs = require('fs');
5
6const jdfUtils = require('jdf-utils');
7const $ = jdfUtils.base;
8const f = jdfUtils.file;
9const logger = require('jdf-log');
10const shelljs = require('shelljs');
11const _ = require('lodash');
12
13const jdf = require('./jdf.js');
14const cssSprite = require('./cssSprite');
15const base64 = require('./base64');
16const buildCss = require("./buildCss");
17const buildHTML = require("./buildHTML");
18const buildHTMLDeep = require('./buildHTMLDeep')
19const buildOutputWidget = require('./buildOutputWidget');
20const buildES6 = require('./buildES6');
21const VFS = require('./VFS/VirtualFileSystem');
22const bs = require('./server/browserSyncServer');
23const middleware = require('./server/middlewareVFS');
24const pluginCore = require('./pluginCore');
25
26//exports
27const build = module.exports = {};
28
29build.serverDir = '';
30
31build.init = function (options) {
32 let buildType = options.buildType;
33 let serverDir = options.serverDir;
34 build.serverDir = serverDir;
35 let projectDir = options.projectDir;
36
37 var logText = 'build files success';
38
39 //注册plugin, todo异步
40 pluginCore.addPluginFromConfiguration();
41
42 return VFS.go()
43 .then(() => {
44 logger.profile('plugin.beforeBuild');
45 return pluginCore.excuteBeforeBuild();
46 })
47 .then(() => {
48 logger.profile('plugin.beforeBuild');
49 return buildCss.init();
50 })
51 .then(() => {
52 if (jdf.config.widgetNesting) {
53 return buildHTMLDeep.init(options);
54 } else {
55 return buildHTML.init(options);
56 }
57 })
58 .then(() => {
59 return buildES6.init();
60 })
61 .then(() => {
62 base64.init();
63 })
64 .then(() => {
65 cssSprite.init();
66 })
67 .then(() => {
68 return buildOutputWidget.init();
69 })
70 .then(() => {
71 logger.profile('plugin.afterBuild');
72 return pluginCore.excuteAfterBuild();
73 })
74 .then(() => {
75 logger.profile('plugin.afterBuild');
76
77 logger.profile(options.profileText);
78 logger.info(logText);
79 })
80 .then(() => {
81 let bsOptions = {
82 autoOpen: false,
83 watchDir: projectDir,
84 serverDir: serverDir
85 };
86 if (buildType === 'open') {
87 bsOptions.autoOpen = true;
88
89 }
90
91 if (true) {
92 return build.startVFSServer(bsOptions);
93 }
94 else {
95 // 启动localserver,基于temp目录,性能低一些
96 // 这个是用来做对比测试的,保证VFS server正确性,不提供watch功能
97 logger.profile('delete temp files');
98 shelljs.rm("-Rf", jdf.transferDir);
99 logger.profile('delete temp files');
100 return VFS.writeFilesToDir(jdf.transferDir).then(() => {
101 return build.startLocalServer(bsOptions);
102 });
103 }
104
105
106
107 })
108 .catch(err => {
109 logger.error(err);
110 });
111}
112
113build.rebuild = function (callback, option) {
114 return VFS.go()
115 .then(() => {
116 logger.profile('plugin.beforeBuild');
117 return pluginCore.excuteBeforeBuild();
118 })
119 .then(() => {
120 logger.profile('plugin.beforeBuild');
121
122 logger.profile('rebuild');
123 if (option && option.buildcss === false) {
124 // 主动不编译css,等于false是为了避免 ===undefined 这种非主动情况
125 return;
126 }
127 return buildCss.init();
128 })
129 .then(() => {
130 if (option && option.buildwidget === false) {
131 return;
132 }
133 if (jdf.config.widgetNesting) {
134 return buildHTMLDeep.init();
135 } else {
136 return buildHTML.init();
137 }
138 })
139 .then(() => {
140 if (option && option.buildjs === false) {
141 return;
142 }
143 return buildES6.init();
144 })
145 .then(() => {
146 if (option && option.buildcss === false) {
147 return;
148 }
149 base64.init();
150 })
151 .then(() => {
152 if (option && option.buildcss === false) {
153 return;
154 }
155 cssSprite.init();
156 })
157 .then(() => {
158 return buildOutputWidget.init();
159 })
160 .then(() => {
161 logger.profile('plugin.afterBuild');
162 return pluginCore.excuteAfterBuild();
163 })
164 .then(() => {
165 logger.profile('plugin.afterBuild');
166
167 logger.profile('rebuild');
168 // TODO 把arguments后面的参数传给callback
169 callback && callback();
170 })
171 .catch(err => {
172 logger.error(err);
173 });
174}
175
176build.debounceRebuild = function () {}
177
178build.startVFSServer = function (options) {
179 return new Promise((resolve, project) => {
180 // startup第一个参数是服务器根目录,基于VFS,不存在在内存中的文件从watchDir,也就是projectDir
181 // 要改成middlewareLocal服务,则这个目录应该设置成jdf.transferDir
182 // jdf server命令调用无参bs.startup(),用的middlewareLocal中间件服务,请参见。
183 bs.startup(options.watchDir, {
184 autoOpen: options.autoOpen,
185 watchDir: options.watchDir,
186 port: parseInt(jdf.config.localServerPort)
187 }, function (port) {
188 // save all的时候每save单个file都会触发一次reload,因此设置debounce,每次触发时只修改VFS
189 // 设定保存一个文件的时间为300ms
190 build.debounceRebuild = _.debounce(build.rebuild, 300);
191
192 bs.watch(function (event, filename, reloadIt) {
193 build.buildChangeFile(event, filename, reloadIt);
194 });
195 resolve(port);
196 }, middleware);
197 });
198}
199
200build.startLocalServer = function (options) {
201 return new Promise((resolve, project) => {
202 bs.startup(options.serverDir, {autoOpen: options.autoOpen, watchDir: options.watchDir});
203 });
204}
205
206build.buildChangeFile = function (event, filename, reloadIt) {
207 if (!jdf.config.build.livereload) {
208 reloadIt = undefined;
209 }
210
211 if (event === 'update') {
212 let newvfile = VFS.createFile(filename);
213 VFS.updateFile(filename, newvfile.originContent);
214 } else if (event === 'remove') {
215 VFS.deleteFile(filename);
216 VFS.deleteDir(filename);
217 }
218
219 this.debounceRebuild(reloadIt, this.buildOption(filename));
220}
221
222/**
223 * 引入按文件编译,在同时保存多个文件时存在风险,比如,最后保存的文件为js,那么就只会编译js
224 * @param {*} filename
225 */
226build.buildOption = function (filename) {
227 let option = {
228 buildcss: true,
229 buildjs: true,
230 buildwidget: true
231 }
232 if (pluginCore.plugins.length > 0) {
233 // 带插件全部编译
234 return option;
235 }
236
237 let extname = path.extname(filename).replace('.', '');
238
239 let cssRelativeTypeArr = VFS.fileType.getRelativeType('css');
240 let jsRelativeTypeArr = VFS.fileType.getRelativeType('js');
241 let imgRelativeTypeArr = VFS.fileType.getRelativeType('img');
242 if (cssRelativeTypeArr.indexOf(extname) !== -1) {
243 option.buildcss = true;
244 option.buildjs = false;
245 option.buildwidget = false;
246 }
247 else if (jsRelativeTypeArr.indexOf(extname) !== -1) {
248 option.buildcss = false;
249 option.buildjs = true;
250 option.buildwidget = false;
251 }
252 else if (imgRelativeTypeArr.indexOf(extname) !== -1) {
253 option.buildcss = false;
254 option.buildjs = false;
255 option.buildwidget = false;
256 }
257 else {
258 option.buildcss = false;
259 option.buildjs = false;
260 option.buildwidget = true;
261 }
262 return option;
263}