UNPKG

7.34 kBJavaScriptView Raw
1/*
2 This file 'make' is part of Firebird Integrated Solution 1.0
3
4 Copyright (c) 2019 Lincong
5
6 Contact:
7 Email: lincong1987@gmail.com
8
9 QQ: 159257119
10
11 See Usage at http://www.jplatformx.com/firebird
12
13 Create date: 2019-03-06 11:32
14 */
15
16/**
17 * 1. 构建出源码版本
18 * 2. 执行此脚本 node build.js
19 */
20
21let fs = require('fs')
22let path = require('path')
23let dayjs = require("dayjs");
24let uglifyjs = require('uglify-es')
25let es3ify = require("es3ify");
26
27
28// const jstransformSimple = require("jstransform/simple");
29
30function optimize(source) {
31
32 /**
33 * 因为 typeof 的问题,Babel 会加上下面这段代码,因此要删掉
34 *
35 * var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
36 * return typeof obj;
37 * } : function (obj) {
38 * return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
39 * };
40 *
41 */
42
43 source = source.replace(
44 /var _typeof = typeof Symbol [\s\S]+?};/,
45 ''
46 )
47
48 /**
49 * Babel 会把 typeof a === x 编译成 ((typeof a === 'undefined' ? 'undefined' : _typeof(a))) === x
50 * 这里替换回 typeof a
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 * 把 Object.freeze 去掉
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 `
76var inherits = function (subClass, superClass) {
77 subClass.prototype = extend({}, superClass.prototype, subClass.prototype);
78};
79 `
80 )
81
82 /**
83 * 改写 possibleConstructorReturn 函数
84 */
85 source = source.replace(
86 /var possibleConstructorReturn = function[\s\S]+?};/,
87 `
88var possibleConstructorReturn = function (self, call) {
89 return self
90};
91 `
92 )
93
94 /**
95 * 把 classCallCheck 去掉
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 * 类属性 value: function has$$1
109 * 转成 value: function
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 * var Node$2 = function Node(type) {
121 * classCallCheck(this, Node);
122 * this.type = type;
123 * };
124 *
125 * 此例改成
126 *
127 * var Node$2 = function Node$2(type) {
128 * classCallCheck(this, Node$2);
129 * this.type = type;
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 * babel 会把函数 function Node {} 转成 var Node = function Node {}
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 // throw new Error(`${$1} is not equals to ${$2}`)
160 }
161 )
162
163 /**
164 * 把 new TypeError 转成 new Error
165 */
166 source = source.replace(
167 /new TypeError/g,
168 'new Error'
169 )
170
171 /**
172 * 把 var name = void 0 转成 var name
173 */
174 source = source.replace(
175 /(\w+) = void 0/g,
176 function ($0, $1) {
177 return $1
178 }
179 )
180
181 /**
182 * 处理 legacy 版本
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 }
201debugger
202 source = source.replace(/"The data \\"" \+ keypath \+ "\\" can't be found in the current context, start looking up."/g,
203 `"该路径 "+ keypath +" 的数据无法在本context中找到。"`)
204
205 //source = source.replace(`"emitter.on(type, listener) invoke failed\uFF1A\n\n\"listener\" is expected to be a Function or an EmitterOptions.\n"`, ``);
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
224 source = es3ify.transform(source);
225
226
227 // source = jstransformSimple.transform(source, {
228 // harmony: true,
229 // utility: true,
230 // target: "es3"
231 // }).code;
232
233 // source = source
234 // .replace(
235 // /\/\/ shim start([\s\S]+?)\/\/ shim end/,
236 // function ($0, $1) {
237 // shim = $1
238 // return ''
239 // }
240 // )
241
242 source = source.replace("typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :", "");
243 source = source.replace("typeof define === 'function' && define.amd ? define(['exports'], factory) :", "");
244 source = source.replace("(global = global || self, factory(global['fb-core'] = {}));", `
245 /* fb loader wrapper start */
246
247 if(typeof fb !== "undefined") {
248
249 define(function (require, exports, module) {
250 var _exports = {};
251 factory(_exports);
252 module.exports = _exports;
253 });
254
255 } else {
256 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global['fb-core'] = {})));
257 }
258 /* fb loader wrapper end */
259 `);
260
261 source = source.replace("{{build-date}}", dayjs().format());
262
263 return source
264
265}
266
267function minify(source) {
268 return uglifyjs.minify(
269 source,
270 {
271 compress: {
272 warnings: false,
273 // see https://github.com/ecomfe/edp/issues/230
274 conditionals: false,
275 properties: false,
276 },
277 mangle: {
278 reserved: ['require', 'exports', 'module'],
279 },
280 output: {
281 quote_keys: true
282 },
283 sourceMap: {},
284 ie8: true
285 }
286 )
287}
288
289function readFile(file) {
290 return fs.readFileSync(path.join(__dirname, '../dist', file)).toString()
291}
292
293function writeFile(file, content) {
294 fs.writeFileSync(path.join(__dirname, '../dist', file), content)
295}
296
297function build(file, minifiedFile) {
298 let sourceMapFile = `${file}.map`
299 let source = optimize(readFile(file))
300 let minified = minify(source)
301 writeFile(file, source)
302 writeFile(minifiedFile, minified.code)
303 writeFile(sourceMapFile, minified.map)
304}
305
306function buildBySource(source, file, minifiedFile) {
307
308 let polyfill = fs.readFileSync(require.resolve("fb-polyfill"));
309 source = polyfill + optimize(source);
310 console.log(`${file} ${(source.length / 1024).toFixed(0)} KB`)
311 let sourceMapFile = `${file}.map`
312 let minified = minify(source);
313
314 console.log("写入代码")
315
316
317 writeFile(file, source)
318 console.log(`写入min code, ${minifiedFile}: ${(minified.code.length / 1024).toFixed(0)} KB`)
319 writeFile(minifiedFile, minified.code)
320 console.log("写入source map")
321 writeFile(sourceMapFile, minified.map)
322}
323
324
325// build('fb-core.js', 'fb-core.min.js');
326
327
328module.exports = { build, buildBySource };
\No newline at end of file