forked from EdgeTranslate/EdgeTranslate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gulpfile.js
291 lines (261 loc) · 8.32 KB
/
gulpfile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
const _ = require("lodash");
const del = require("del");
const gulp = require("gulp");
const stylus = require("gulp-stylus");
const fs = require("fs");
const through = require("through2");
const webpack = require("webpack");
const webpack_stream = require("webpack-stream");
const zip = require("gulp-zip");
const terser = require("gulp-terser");
const eslint = require("gulp-eslint");
const mergeStream = require("merge-stream");
const minimist = require("minimist");
const spawn = require("child_process").spawn;
let args = minimist(process.argv.slice(2));
let browser = args.browser || "chrome"; // store the name of browser: enum{chrome,firefox}
let environment; // store the type of environment: enum{production,development}
/**
* Define public tasks of gulp
*/
/**
*
* A public task to build JS in development mode
*
* Hint: The watch mode of webpack in development mode will block the current gulp task. So this task need to to be run independently in command line in another process
*/
exports.buildJS = gulp.series(setDevelopEnvironment, buildJS);
/**
* A public task to build a package in development mode and watch code changes.
*/
exports.dev = gulp.series(
setDevelopEnvironment,
clean,
gulp.parallel(eslintJS, buildJSDev, manifest, html, styl, packStatic),
watcher
);
/**
* A public task to build a package in production mode
*/
exports.build = gulp.series(
setProductEnvironment,
clean,
gulp.parallel(eslintJS, buildJS, manifest, html, styl, packStatic)
);
/**
* A public task to build and zip a package in production mode
*/
exports.pack = gulp.series(
setProductEnvironment,
clean,
gulp.parallel(eslintJS, buildJS, manifest, html, styl, packStatic),
packToZip
);
/**
* End public tasks' definition
*/
/**
* Define private tasks of gulp
*/
/**
* A private task to set development execution environment
*/
function setDevelopEnvironment(done) {
environment = "development";
done();
}
/**
* A private task to set production execution environment
*/
function setProductEnvironment(done) {
environment = "production";
done();
}
/**
* A private task to clean old packages before building new ones
*/
function clean() {
let output_dir = `./build/${browser}/`;
let packageName = `edge_translate_${browser}.zip`;
return del([output_dir, `./build/${packageName}`]);
}
/**
* 将build的扩展打包成zip文件以备发布
*/
function packToZip() {
let match_dir = `./build/${browser}/**/*`;
let packageName = `edge_translate_${browser}.zip`;
return gulp.src(match_dir).pipe(zip(packageName)).pipe(gulp.dest("./build/"));
}
/**
* A private task to watch change of code and update the package immediately
* @param {Function} done execute done to inform gulp that the task is finished
*/
function watcher(done) {
gulp.watch("./src/**/*.{js,jsx}").on("change", gulp.series(eslintJS));
gulp.watch("./src/(manifest|manifest_chrome|manifest_firefox).json").on(
"change",
gulp.series(manifest)
);
gulp.watch("./src/**/*.html").on("change", gulp.series(html));
gulp.watch("./static/**/*").on("change", gulp.series(packStatic));
gulp.watch("./src/**/*.styl").on("change", gulp.series(styl));
done();
}
/**
* A private task to run eslint check for JS code
*/
function eslintJS() {
return gulp
.src("./src/**/*.{js,jsx}", { base: "src" })
.pipe(
eslint({
configFile: "./.eslintrc.js",
})
)
.pipe(eslint.format());
}
/**
* A private code to build JS code
*/
function buildJS() {
let output_dir = `./build/${browser}/`;
let webpack_path =
environment === "production"
? "./config/webpack.prod.config.js"
: "./config/webpack.dev.config.js"; // webpack 配置文件路径
// Insert plugins.
let webpack_config = require(webpack_path);
webpack_config.plugins = webpack_config.plugins || [];
webpack_config.plugins.push(
new webpack.DefinePlugin({
BROWSER_ENV: JSON.stringify(browser),
BUILD_ENV: JSON.stringify(environment),
})
);
return gulp
.src("./src/**/*.js", { base: "src" })
.pipe(webpack_stream(webpack_config, webpack))
.pipe(gulp.dest(output_dir))
.on("error", (error) => log(error));
}
/**
* A private task to build js files in a child process in development mode with watch mode of webpack
*
* Hint: The watch mode of webpack in development mode will block the current gulp task. So the buildJS task need to to be run independently in command line in another process
*
* @param {Function} done execute done to inform gulp that the task is finished
*/
function buildJSDev(done) {
let result = spawn("gulp", ["buildJS", "--browser", browser, "--color"]);
result.stdout.on("data", (data) => {
log(data);
});
result.stderr.on("data", (data) => {
log(data);
});
done();
}
/**
* A private task to merge manifest json files to one json file
*/
function manifest() {
let output_dir = `./build/${browser}/`;
let manifest_patch = `./src/manifest_${browser}.json`;
return gulp
.src("./src/manifest.json", { base: "src" })
.pipe(merge_json(manifest_patch))
.pipe(gulp.dest(output_dir));
}
/**
* A private task to pack HTML files except HTML templates
*/
function html() {
let output_dir = `./build/${browser}/`;
return gulp.src(["./src/**/*.html"], { base: "src" }).pipe(gulp.dest(output_dir));
}
/**
* A private task to convert styl to css files
*/
function styl() {
let output_dir = `./build/${browser}/`;
return gulp
.src("./src/!(common)/**/*.styl", { base: "src" })
.pipe(
stylus({
compress: true, // 需要压缩
}).on("error", (error) => log(error))
)
.pipe(gulp.dest(output_dir));
}
/**
* A private task to pack static files under "./static/"
*/
function packStatic() {
let output_dir = `./build/${browser}/`;
if (browser === "chrome") {
// static JS files except google JS
let staticJSFiles = gulp
.src("./static/**/!(element_main).js", {
base: "static",
since: gulp.lastRun(packStatic),
})
.pipe(terser().on("error", (error) => log(error)))
.pipe(gulp.dest(output_dir));
// google page translation files
// Do not uglify element_main.js
let googleJS = gulp
.src("./static/google/element_main.js", {
base: "static",
since: gulp.lastRun(packStatic),
})
.pipe(gulp.dest(output_dir));
// non-js static files
let staticOtherFiles = gulp
.src("./static/**/!(*.js)", { base: "static" })
.pipe(gulp.dest(output_dir));
return mergeStream([staticJSFiles, googleJS, staticOtherFiles]);
}
// static JS files except google JS
let staticJSFiles = gulp
.src("./static/!(pdf)/**/!(element_main).js", { base: "static" })
.pipe(terser().on("error", (error) => log(error)))
.pipe(gulp.dest(output_dir));
// google page translation files
// Do not uglify element_main.js
let googleJS = gulp
.src("./static/google/element_main.js", { base: "static" })
.pipe(gulp.dest(output_dir));
// non-js static files
let staticOtherFiles = gulp
.src("./static/!(pdf)/**/!(*.js)", { base: "static" })
.pipe(gulp.dest(output_dir));
return mergeStream([staticJSFiles, googleJS, staticOtherFiles]);
}
/**
* End private tasks' definition
*/
/**
* 一个简易gulp插件,接收一组json文件作为参数,将它们合并到gulp.src引用的基本json文件;
* 在这里的作用是合并公共manifest和不同浏览器特有的manifest。
*/
function merge_json(...args) {
let objs = [];
for (let i in args) {
objs.push(JSON.parse(fs.readFileSync(args[i])));
}
let stream = through.obj(function (file, enc, callback) {
let obj = JSON.parse(file.contents.toString(enc));
for (let i in objs) {
obj = _.defaultsDeep(obj, objs[i]);
}
file.contents = Buffer.from(JSON.stringify(obj));
this.push(file);
callback();
});
return stream;
}
// 定义 log函数 ,便于输出task的执行情况
function log(d) {
process.stdout.write(`${d}\n`);
}