UNPKG

9.23 kBJavaScriptView Raw
1/**
2 * Created by Rodey on 2017/6/29.
3 */
4'use strict';
5
6const $ = require('gulp-load-plugins')(),
7 plumber = require('gulp-plumber'),
8 util = require('../utils'),
9 publish = require('../plugins/publish'),
10 T = require('../tools');
11
12class TaskNode {
13 /**
14 * 任务
15 * @param config 任务配置
16 * @param gupack Gupack对象
17 */
18 constructor(config, gupack) {
19 this.name = undefined;
20 this.src = '';
21 this.filters = '';
22 this.plugins = [];
23 this.watch = [];
24 this.run = true;
25 this.noWatch = false;
26 this.dest = null;
27 this.rely = undefined;
28 this.loader = {};
29 this.pathPrefix = '';
30 this.base = T.getArg('cwdir') || process.cwd();
31 this.gupack = undefined;
32 this._if = undefined;
33 this.pluginCache = {};
34 this.merge = false;
35 this.stream = null;
36 this.$ = this.loadPlugin = $;
37 // 编译前
38 this.before = null;
39 // 编译后
40 this.after = null;
41 // 编译当前任务前清理对应输出目录
42 this.beforeClean = false;
43
44 for (let prop in config) {
45 if (config.hasOwnProperty(prop)) {
46 this[prop] = config[prop];
47 }
48 }
49
50 if (gupack) {
51 this.gupack = gupack;
52 this.gulp = this.gupack.gulp;
53 this.basePath = this.gupack.basePath;
54 this.sourceDir = this.gupack.sourceDir;
55 this.buildDir = this.gupack.buildDir;
56 }
57
58 this.init();
59 }
60
61 init() {
62 //watcher
63 if (!this.noWatch || this.watch) this.watch = this.getTaskWatch();
64
65 //源文件 src
66 this.src = this.getSource();
67
68 //过滤文件 filters
69 this.filters = this.getFilters();
70 this.src = this.src.concat(this.filters);
71
72 //插件样式
73 this.plugins = this.getPlugins();
74 this.src = this.src.concat(this.plugins);
75
76 //合并压缩后的输出
77 this.dest = this.getDist();
78 }
79
80 getTaskWatch() {
81 let source = this.src || [],
82 watcher = this.watch || source || [],
83 pathPrefix = this.pathPrefix || '';
84
85 if (!this.watch && this.pathPrefix.length > 0) {
86 if (util.isString(source)) {
87 watcher = T.Path.join(pathPrefix, source);
88 } else if (util.isArray(source)) {
89 watcher = source.map(s => {
90 return T.Path.join(pathPrefix, s);
91 });
92 } else {
93 throw new ReferenceError('没有可用的源文件,请设置需要监听的文件或目录');
94 }
95 }
96 if (!this.noWatch) {
97 watcher = this.loadWatch(watcher);
98 }
99 return watcher;
100 }
101
102 getSource() {
103 let source = this.src || [],
104 pathPrefix = this.pathPrefix || '';
105 source && source.length !== 0 && (source = this.loadSource(source, pathPrefix));
106 return source;
107 }
108
109 getFilters() {
110 let filters = this.filters || [];
111 if (filters.length > 0) {
112 filters = this.loadSource(filters, this.pathPrefix, '!');
113 }
114 return filters;
115 }
116
117 getPlugins() {
118 let plugins = this.plugins || [];
119 if (plugins.length > 0) {
120 plugins = this.loadSource(plugins, this.pathPrefix);
121 }
122 return plugins;
123 }
124
125 getDist() {
126 return this.dest && T.Path.resolve(this.buildDir, this.dest);
127 }
128
129 getTaskFunction(done) {
130 // 加载的gulp插件,
131 let loaders = this.loader;
132 this.stream = this.gulp.src(this.src);
133
134 // 如果 loader 为Function,则必须返回stream
135 if (util.isFunction(loaders)) {
136 this.stream = loaders.call(null, this.stream, done) || this.stream;
137 // return this.stream;
138 }
139
140 this.stream = this.stream.pipe(plumber());
141
142 // 执行编译前 (必须返回stream)
143 if (util.isFunction(this.before)) {
144 this.stream = this.before.call(this, this.stream, done) || this.stream;
145 }
146
147 // 执行加载loader
148 this.excuteLoader(loaders, done);
149
150 // 判断是否存在hostname配置,如果存在则执行替换任务(一般在release)
151 this.excutePublish();
152
153 // 执行编译后
154 if (util.isFunction(this.after)) {
155 this.stream = this.after.call(this, this.stream, done) || this.stream;
156 }
157
158 this.stream = this.stream.pipe(plumber());
159
160 // 输出
161 this.excuteDest();
162
163 return this.stream;
164 }
165
166 loadWatch(source, pathPrefix) {
167 pathPrefix = pathPrefix || '';
168 if (!source) return '';
169 if (util.isString(source)) {
170 source = T.Path.resolve(this.sourceDir, pathPrefix, source);
171 } else {
172 source = source.map(src => {
173 return T.Path.resolve(this.sourceDir, pathPrefix, src);
174 });
175 }
176 return source;
177 }
178
179 loadSource(source, pathPrefix, nos) {
180 nos = nos || '';
181 pathPrefix = pathPrefix || '';
182 if (!source) return '';
183 if (util.isString(source)) {
184 source = [nos + T.Path.resolve(this.sourceDir, pathPrefix, source)];
185 } else {
186 source = source.map(src => {
187 return nos + T.Path.resolve(this.sourceDir, pathPrefix, src);
188 });
189 }
190 return source;
191 }
192
193 excuteLoader(loaders, done) {
194 process.chdir(this.basePath);
195 this.pluginCache = {};
196
197 util.isObject(loaders) &&
198 !util.isEmptyObject(loaders) &&
199 Object.keys(loaders).forEach(loaderName => {
200 let pluginName = loaderName,
201 plugin = this.pluginCache[pluginName],
202 options = loaders[loaderName];
203
204 if (util.isFunction(options)) {
205 this.stream = options.call(this, this.stream, done);
206 return false;
207 }
208
209 if (!plugin) {
210 plugin = (() => {
211 let ptemp = loaders[loaderName],
212 pp,
213 pluginPath;
214 ptemp && util.isObject(ptemp) && ptemp['pluginName'] && (pluginName = ptemp['pluginName']);
215 if (ptemp && util.isObject(ptemp)) {
216 ptemp['pluginName'] && (pluginName = ptemp['pluginName']);
217 ptemp['pluginPath'] && (pluginPath = ptemp['pluginPath']);
218 }
219
220 // 设置插件路径
221 if (pluginPath) {
222 pluginPath = this.getPluginPath(pluginPath, pluginName);
223 pp = require(pluginPath);
224 } else {
225 try {
226 // 从项目src/node_modeuls中找
227 pp = require(T.Path.resolve(this.basePath, `node_modules/${pluginName}/`));
228 } catch (e) {
229 // 从gupack中的node_modules中找
230 pp = require(pluginName);
231 }
232 }
233 if (!pp) {
234 T.log.error(`'${loaderName}' plugin is not loaded, Stream content is not supported`);
235 }
236 pp && (this.pluginCache[pluginName] = pp);
237 return pp;
238 })();
239 }
240
241 // 某些插件需要区分环境,
242 // 可能在开发环境不需要执行,而在生产或测试环境需要执行
243 if (plugin && util.isObject(options) && '_if' in options) {
244 options._if === true && (this.stream = this.stream.pipe(plugin(options)));
245 } else {
246 this.stream = this.stream.pipe(plugin(options));
247 }
248 });
249 }
250
251 excutePublish() {
252 if (!util.isEmptyObject(this.gupack.statics) && this.gupack.statics !== false) {
253 this.stream = this.stream.pipe(publish(this.gupack.statics));
254 }
255 }
256
257 excuteDest() {
258 if (this.dest) {
259 // if (!T.fs.existsSync(this.dest)) {
260 // T.fsa.mkdirsSync(this.dest);
261 // }
262 this.stream = this.stream.pipe(this.gulp.dest(this.dest || this.buildDir));
263 }
264 }
265
266 // 获取自定义插件路径
267 getPluginPath(pluginPath, pluginName) {
268 if (!T.isAbsolutePath(pluginPath)) {
269 pluginPath = T.Path.resolve(this.basePath, pluginPath);
270 }
271 if (!/.js$/i.test(pluginPath)) {
272 pluginPath = T.Path.resolve(pluginPath, pluginName);
273 }
274 return pluginPath;
275 }
276}
277
278module.exports = TaskNode;
\No newline at end of file