cocos-enhance-kit/engine/gulp/util/utils.js

209 lines
8.4 KiB
JavaScript

const PLATFORM_MACROS = ['CC_EDITOR', 'CC_PREVIEW', 'CC_BUILD', 'CC_TEST'];
const FLAGS = ['support_jit', 'jsb', 'runtime', 'debug', 'nativeRenderer', 'minigame', 'physics_builtin', 'physics_cannon'];
// generate macros for uglify's global_defs
// available platforms: 'editor' | 'preview' | 'build' | 'test'
// available keys of flags: 'jsb' | 'runtime' | 'minigame' | 'debug' | 'nativeRenderer'
exports.getMacros = function (platform, flags) {
// platform macros
var platformMacro = 'CC_' + platform.toUpperCase();
if (PLATFORM_MACROS.indexOf(platformMacro) === -1) {
throw new Error('Unknown platform: ' + platform);
}
var res = {};
for (let i = 0; i < PLATFORM_MACROS.length; i++) {
let macro = PLATFORM_MACROS[i];
res[macro] = (macro === platformMacro);
}
// flag macros
if (flags) {
for (let flag in flags) {
if (flags.hasOwnProperty(flag) && flags[flag]) {
if (FLAGS.indexOf(flag) === -1) {
throw new Error('Unknown flag: ' + flag);
}
}
}
}
for (let i = 0; i < FLAGS.length; i++) {
let flag = FLAGS[i];
let macro = 'CC_' + flag.toUpperCase();
res[macro] = !!(flags && flags[flag]);
}
// debug macros
res['CC_DEV'] = res['CC_EDITOR'] || res['CC_PREVIEW'] || res['CC_TEST'];
res['CC_DEBUG'] = res['CC_DEBUG'] || res['CC_DEV'];
// openHarmony does not support Funtion ,therefore this macro variable is temporarily set to false
//res['CC_SUPPORT_JIT'] = false;
if (typeof flags.force_setting_support_jit !== 'undefined') {
res['CC_SUPPORT_JIT'] = flags.force_setting_support_jit;
} else {
res['CC_SUPPORT_JIT'] = !(res['CC_RUNTIME'] || res['CC_MINIGAME']);
}
res['CC_NATIVERENDERER'] = res['CC_JSB'] && true;
return res;
};
// see https://github.com/terser/terser#compress-options
exports.getUglifyOptions = function (platform, flags) {
var global_defs = exports.getMacros(platform, flags);
var releaseMode = !global_defs['CC_DEBUG'];
var optimizeForJSC = releaseMode && global_defs['CC_JSB'];
if (optimizeForJSC) {
return {
parse: {
bare_returns: true
},
toplevel: false,
compress: {
global_defs: global_defs,
negate_iife: false,
sequences: false,
keep_infinity: true, // reduce jsc file size
typeofs: false,
inline: true,
reduce_funcs: false, // keep single-use function object being cached, but not supported since 4.2.1, see terser/terser#696
passes: 2, // first: remove deadcode, second: drop variables
keep_fargs: false,
unsafe_Function: true,
unsafe_math: true,
unsafe_methods: true,
},
output: {
beautify: true, // enable preserve_lines for line number
indent_level: 0, // reduce jsc file size
}
};
}
if (releaseMode) {
return {
parse: {
bare_returns: true
},
toplevel: false,
compress: {
global_defs: global_defs,
negate_iife: false,
inline: true,
reduce_funcs: false, // keep single-use function object being cached, but not supported since 4.2.1, see terser/terser#696
passes: 2, // first: remove deadcode, second: reduce constant variables
keep_fargs: false,
unsafe_Function: true,
unsafe_math: true,
unsafe_methods: true,
},
// mangle: false,
output: {
// http://lisperator.net/uglifyjs/codegen
// beautify: true,
// indent_level: 2,
ascii_only: true,
},
safari10: true, // cocos-creator/engine#5144
};
}
else {
return {
parse: {
bare_returns: true
},
toplevel: false,
compress: {
global_defs: global_defs,
negate_iife: false,
sequences: false, // join consecutive statements with the “comma operator”
properties: false, // optimize property access: a["foo"] → a.foo
// dead_code: true, // discard unreachable code
drop_debugger: false, // discard “debugger” statements
// ecma: 5, // transform ES5 code into smaller ES6+ equivalent forms
// evaluate: true, // evaluate constant expressions
unsafe: false, // some unsafe optimizations (see below)
// computed_props: true,
// conditionals: false, // optimize if-s and conditional expressions
comparisons: false, // optimize comparisons
booleans: false, // optimize boolean expressions
typeofs: false, // Transforms typeof foo == "undefined" into foo === void 0. Note: recommend to set this value to false for IE10 and earlier versions due to known issues.
loops: false, // optimize loops
unused: false, // drop unused variables/functions
hoist_funs: false, // hoist function declarations
hoist_props: false,
hoist_vars: false, // hoist variable declarations
if_return: false, // optimize if-s followed by return/continue
inline: false, // embed simple functions
join_vars: false, // join var declarations
collapse_vars: false, // Collapse single-use non-constant variables - side effects permitting.
reduce_funcs: false,
reduce_vars: false, // Improve optimization on variables assigned with and used as constant values.
//warnings: true,
pure_getters: false,
pure_funcs: null,
drop_console: false,
// expression: false, // Pass true to preserve completion values from terminal statements without return, e.g. in bookmarklets.
keep_fargs: true,
keep_fnames: true,
keep_infinity: true, // Pass true to prevent Infinity from being compressed into 1/0, which may cause performance issues on Chrome.
side_effects: false, // drop side-effect-free statements
},
mangle: false,
//preserveComments: 'all',
output: {
// http://lisperator.net/uglifyjs/codegen
beautify: true,
indent_level: 2,
ascii_only: true,
},
safari10: true, // cocos-creator/engine#5144
};
}
};
exports.uglify = function (platform, isJSB, isDebugBuild) {
const options = exports.getUglifyOptions(platform, isJSB, isDebugBuild);
if (false) {
const Composer = require('gulp-uglify/composer');
const Uglify = require('uglify-es');
return Composer(Uglify)(options);
}
else {
const Terser = require("terser");
const ES = require('event-stream');
const applySourceMap = require('vinyl-sourcemaps-apply');
return ES.through(function (file) {
if (file.path.endsWith('.js')) {
let build;
let eachOption;
let content = file.contents.toString();
if (file.sourceMap && file.sourceMap.file) {
build = {};
build[file.sourceMap.file] = content;
eachOption = Object.assign({}, options, {
sourceMap: {
filename: file.sourceMap.file,
},
});
} else {
build = content;
eachOption = options;
}
var result = Terser.minify(build, eachOption);
if (result.error) {
return this.emit('error', result.error);
}
content = result.code;
file.contents = new Buffer(content);
if (result.map) {
applySourceMap(file, result.map);
}
}
this.emit('data', file);
});
}
};