1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | let fs = require('fs')
|
22 | let path = require('path')
|
23 | let dayjs = require("dayjs");
|
24 | let uglifyjs = require('uglify-es')
|
25 | let es3ify = require("es3ify");
|
26 |
|
27 |
|
28 |
|
29 |
|
30 | function optimize(source) {
|
31 |
|
32 | |
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | source = source.replace(
|
44 | /var _typeof = typeof Symbol [\s\S]+?};/,
|
45 | ''
|
46 | )
|
47 |
|
48 | |
49 |
|
50 |
|
51 |
|
52 | source = source.replace(
|
53 | /\(typeof \w+ === 'undefined' \? 'undefined' : _typeof\(\w+\)\)/g,
|
54 | function ($0) {
|
55 | return 'typeof ' + $0.split(' ')[1]
|
56 | }
|
57 | )
|
58 |
|
59 |
|
60 | |
61 |
|
62 |
|
63 | source = source.replace(
|
64 | /Object\.freeze\(([^)]+)\)/g,
|
65 | function ($0, $1) {
|
66 | return $1
|
67 | }
|
68 | )
|
69 |
|
70 | |
71 |
|
72 |
|
73 | source = source.replace(
|
74 | /var inherits = function[\s\S]+?};/,
|
75 | `
|
76 | var inherits = function (subClass, superClass) {
|
77 | subClass.prototype = extend({}, superClass.prototype, subClass.prototype);
|
78 | };
|
79 | `
|
80 | )
|
81 |
|
82 | |
83 |
|
84 |
|
85 | source = source.replace(
|
86 | /var possibleConstructorReturn = function[\s\S]+?};/,
|
87 | `
|
88 | var possibleConstructorReturn = function (self, call) {
|
89 | return self
|
90 | };
|
91 | `
|
92 | )
|
93 |
|
94 | |
95 |
|
96 |
|
97 | source = source
|
98 | .replace(
|
99 | /var classCallCheck = function[\s\S]+?};/g,
|
100 | ''
|
101 | )
|
102 | .replace(
|
103 | /classCallCheck\(this, \w+\);/g,
|
104 | ''
|
105 | )
|
106 |
|
107 | |
108 |
|
109 |
|
110 |
|
111 | source = source.replace(
|
112 | /\.prototype\.(\w+) = function [$\w]+\(/g,
|
113 | function ($0, $1) {
|
114 | return '.prototype.' + $1 + ' = function ('
|
115 | }
|
116 | )
|
117 |
|
118 |
|
119 | |
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 | source = source.replace(
|
133 | /var ([\w$]+) = function (\w+)\([^)]+\) {\n\s+classCallCheck\(this, \w+\);/g,
|
134 | function ($0, $1, $2) {
|
135 | if ($1 !== $2) {
|
136 | let [part1, part2] = $0.split('=')
|
137 | part2 = part2.replace(new RegExp(`\\b${$2}\\b`, 'g'), $1)
|
138 | return `${part1}=${part2}`
|
139 | }
|
140 | return $0
|
141 | }
|
142 | )
|
143 |
|
144 | |
145 |
|
146 |
|
147 |
|
148 | source = source.replace(
|
149 | /(\b)([\w$]+) = function ([\w$]+)/g,
|
150 | function ($0, $1, $2, $3) {
|
151 |
|
152 | if ($0.indexOf("_") === 0) {
|
153 | return $0;
|
154 | }
|
155 | if ($2 === $3) {
|
156 | return `${$1}${$2} = function `
|
157 | }
|
158 |
|
159 |
|
160 | }
|
161 | )
|
162 |
|
163 | |
164 |
|
165 |
|
166 | source = source.replace(
|
167 | /new TypeError/g,
|
168 | 'new Error'
|
169 | )
|
170 |
|
171 | |
172 |
|
173 |
|
174 | source = source.replace(
|
175 | /(\w+) = void 0/g,
|
176 | function ($0, $1) {
|
177 | return $1
|
178 | }
|
179 | )
|
180 |
|
181 | |
182 |
|
183 |
|
184 | if (/shim start/.test(source)) {
|
185 | let shim = ''
|
186 | source = source
|
187 | .replace(
|
188 | /\/\/ shim start([\s\S]+?)\/\/ shim end/,
|
189 | function ($0, $1) {
|
190 | shim = $1
|
191 | return ''
|
192 | }
|
193 | )
|
194 | .replace(
|
195 | /'use strict';/,
|
196 | function ($0) {
|
197 | return $0 + shim
|
198 | }
|
199 | )
|
200 | }
|
201 | debugger
|
202 | source = source.replace(/"The data \\"" \+ keypath \+ "\\" can't be found in the current context, start looking up."/g,
|
203 | `"该路径 "+ keypath +" 的数据无法在本context中找到。"`)
|
204 |
|
205 |
|
206 |
|
207 | source = source.replace(/'Yox debug'/, "'debug'");
|
208 | source = source.replace(/'Yox info'/, "'info'");
|
209 | source = source.replace(/'Yox warn'/, "'warn'");
|
210 | source = source.replace(/'Yox error'/, "'error'");
|
211 | source = source.replace(/'Yox fatal'/, "'fatal'");
|
212 | source = source.replace(/'YOX_LOG_LEVEL'/, "'DEBUG_LEVEL'");
|
213 |
|
214 | source = source.replace(/Yox\.filter = function \(name, filter\) {/, `
|
215 |
|
216 | Yox.filters = globalFilters;
|
217 |
|
218 | Yox.filter = function (name, filter) {
|
219 |
|
220 | `);
|
221 |
|
222 |
|
223 | source = source.replace(/this\.originalEvent = originalEvent/, `
|
224 | // add this.e for short
|
225 | this.originalEvent = this.e = originalEvent`);
|
226 |
|
227 | source = es3ify.transform(source);
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 | source = source.replace("typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :", "");
|
246 | source = source.replace("typeof define === 'function' && define.amd ? define(['exports'], factory) :", "");
|
247 | source = source.replace("(global = global || self, factory(global['fb-core'] = {}));", `
|
248 | /* fb loader wrapper start */
|
249 |
|
250 | if(typeof fb !== "undefined") {
|
251 |
|
252 | define(function (require, exports, module) {
|
253 | var _exports = {};
|
254 | factory(_exports);
|
255 | module.exports = _exports;
|
256 | });
|
257 |
|
258 | } else {
|
259 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global['fb-core'] = {})));
|
260 | }
|
261 | /* fb loader wrapper end */
|
262 | `);
|
263 |
|
264 | source = source.replace("{{build-date}}", dayjs().format());
|
265 |
|
266 | return source
|
267 |
|
268 | }
|
269 |
|
270 | function minify(source) {
|
271 | return uglifyjs.minify(
|
272 | source,
|
273 | {
|
274 | compress: {
|
275 | warnings: false,
|
276 |
|
277 | conditionals: false,
|
278 | properties: false,
|
279 | },
|
280 | mangle: {
|
281 | reserved: ['require', 'exports', 'module'],
|
282 | },
|
283 | output: {
|
284 | quote_keys: true
|
285 | },
|
286 | sourceMap: {},
|
287 | ie8: true
|
288 | }
|
289 | )
|
290 | }
|
291 |
|
292 | function readFile(file) {
|
293 | return fs.readFileSync(path.join(__dirname, '../dist', file)).toString()
|
294 | }
|
295 |
|
296 | function writeFile(file, content) {
|
297 | fs.writeFileSync(path.join(__dirname, '../dist', file), content)
|
298 | }
|
299 |
|
300 | function build(file, minifiedFile) {
|
301 | let sourceMapFile = `${file}.map`
|
302 | let source = optimize(readFile(file))
|
303 | let minified = minify(source)
|
304 | writeFile(file, source)
|
305 | writeFile(minifiedFile, minified.code)
|
306 | writeFile(sourceMapFile, minified.map)
|
307 | }
|
308 |
|
309 | function buildBySource(source, file, minifiedFile) {
|
310 |
|
311 | let polyfill = fs.readFileSync(require.resolve("fb-polyfill"));
|
312 | source = polyfill + optimize(source);
|
313 | console.log(`${file} ${(source.length / 1024).toFixed(0)} KB`)
|
314 | let sourceMapFile = `${file}.map`
|
315 | let minified = minify(source);
|
316 |
|
317 | console.log("写入代码")
|
318 |
|
319 |
|
320 | writeFile(file, source)
|
321 | console.log(`写入min code, ${minifiedFile}: ${(minified.code.length / 1024).toFixed(0)} KB`)
|
322 | writeFile(minifiedFile, minified.code)
|
323 | console.log("写入source map")
|
324 | writeFile(sourceMapFile, minified.map)
|
325 | }
|
326 |
|
327 |
|
328 |
|
329 |
|
330 |
|
331 | module.exports = { build, buildBySource }; |
\ | No newline at end of file |