mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-10-09 07:05:23 +00:00
初始化
This commit is contained in:
182
engine/gulp/util/create-bundler.js
Normal file
182
engine/gulp/util/create-bundler.js
Normal file
@@ -0,0 +1,182 @@
|
||||
'use strict';
|
||||
|
||||
const Path = require('path');
|
||||
allowReturnOutsideFunctionInBrowserifyTransform();
|
||||
const Fs = require('fs');
|
||||
const Del = require('del');
|
||||
|
||||
const dropPureExport = require('./drop-pure-export');
|
||||
const inlineProp = require('./inline-prop');
|
||||
const polyfillPromisify = require('./polyfill-node-promisify');
|
||||
|
||||
const preludePath = Path.resolve(__dirname, '../browserify_prelude.js');
|
||||
const prelude = Fs.readFileSync(preludePath, 'utf8');
|
||||
|
||||
function allowReturnOutsideFunctionInBrowserifyTransform () {
|
||||
var paths = [
|
||||
'browserify/node_modules/syntax-error/node_modules/acorn',
|
||||
'syntax-error/node_modules/acorn',
|
||||
'acorn'
|
||||
];
|
||||
function patch (path) {
|
||||
var acorn = require(path);
|
||||
var parse = acorn.parse;
|
||||
if (typeof parse === 'function') {
|
||||
if (acorn.parse.name !== 'monkeyPatchedParse') {
|
||||
acorn.parse = function monkeyPatchedParse(input, options) {
|
||||
if (options) {
|
||||
options.allowReturnOutsideFunction = true;
|
||||
}
|
||||
else {
|
||||
options = {
|
||||
allowReturnOutsideFunction: true
|
||||
};
|
||||
}
|
||||
return parse(input, options);
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error('Can not find acorn.parse to patch');
|
||||
}
|
||||
}
|
||||
|
||||
var patched = false;
|
||||
for (var i = 0; i < paths.length; i++) {
|
||||
try {
|
||||
patch(paths[i]);
|
||||
patched = true;
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
if (!patched) {
|
||||
console.error('Can not find acorn to patch');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @param [options.sourcemaps = true]
|
||||
* @param [options.babelifyOpt]
|
||||
* @param [options.aliasifyConfig]
|
||||
*/
|
||||
module.exports = function createBundler(entryFiles, options) {
|
||||
|
||||
// Ignore IDE compiled JavaScript files
|
||||
Del.sync('./cocos2d/core/platform/deserialize-compiled.js');
|
||||
Del.sync('./cocos2d/core/value-types/*.js');
|
||||
|
||||
// https://github.com/substack/node-browserify#methods
|
||||
var browserifyOpt = {
|
||||
extensions: ['.js', '.json', '.ts'],
|
||||
entries: [].concat(entryFiles),
|
||||
debug: (options && 'sourcemaps' in options) ? options.sourcemaps : true,
|
||||
detectGlobals: false, // dont insert `process`, `global`, `__filename`, and `__dirname`
|
||||
bundleExternal: !!(options && options.bundleExternal) || false, // dont bundle external modules
|
||||
//standalone: 'engine-framework',
|
||||
//basedir: tempScriptDir
|
||||
|
||||
// define custom prelude to optimize script evaluate time
|
||||
prelude: prelude,
|
||||
preludePath: Path.relative(process.cwd(), preludePath),
|
||||
};
|
||||
|
||||
var presets = [
|
||||
[
|
||||
require('@babel/preset-env'),
|
||||
{
|
||||
"loose": true,
|
||||
// "bugfixes": true, since babel 7.9
|
||||
}
|
||||
],
|
||||
{
|
||||
plugins: [
|
||||
[
|
||||
require('@babel/plugin-proposal-decorators'),
|
||||
{ legacy: true },
|
||||
],
|
||||
[
|
||||
require('@babel/plugin-proposal-class-properties'),
|
||||
{ loose: true },
|
||||
],
|
||||
]
|
||||
},
|
||||
[
|
||||
require('@babel/preset-typescript'),
|
||||
{
|
||||
allowDeclareFields: true,
|
||||
}
|
||||
],
|
||||
];
|
||||
|
||||
var plugins = [
|
||||
// // < 6.16.0
|
||||
// [ 'babel-plugin-parser-opts', { allowReturnOutsideFunction: true } ]
|
||||
[
|
||||
require('babel-plugin-const-enum'),
|
||||
{ transform: "constObject" },
|
||||
],
|
||||
[
|
||||
require('babel-plugin-add-module-exports'),
|
||||
],
|
||||
];
|
||||
|
||||
var Babelify;
|
||||
try {
|
||||
Babelify = require('babelify');
|
||||
} catch (e) {
|
||||
console.error('Please run "npm install babelify".');
|
||||
throw e;
|
||||
}
|
||||
var aliasify;
|
||||
try {
|
||||
aliasify = require('aliasify');
|
||||
} catch (e) {
|
||||
console.error('Please run "npm install aliasify".');
|
||||
throw e;
|
||||
}
|
||||
|
||||
var b;
|
||||
if (options && options.cacheDir) {
|
||||
// https://github.com/royriojas/persistify
|
||||
const Persistify = require('persistify');
|
||||
b = Persistify(browserifyOpt, {
|
||||
recreate: false,
|
||||
cacheId: require('../../package.json').version + entryFiles,
|
||||
cacheDir: options.cacheDir
|
||||
});
|
||||
}
|
||||
else {
|
||||
const Browserify = require('browserify');
|
||||
b = new Browserify(browserifyOpt);
|
||||
}
|
||||
|
||||
b = b.exclude(Path.join(__dirname, '../../package.json'));
|
||||
|
||||
if (browserifyOpt.bundleExternal) {
|
||||
b = b.transform(polyfillPromisify);
|
||||
}
|
||||
|
||||
return b
|
||||
.transform(dropPureExport)
|
||||
.transform(inlineProp.inlineConst)
|
||||
.transform(Babelify, (options && options.babelifyOpt) || {
|
||||
extensions: ['.ts', '.js'],
|
||||
presets: (options && options.presets) || presets,
|
||||
plugins: (options && options.plugins && options.plugins.concat(plugins)) || plugins,
|
||||
|
||||
// >= 6.16.0
|
||||
// parserOpts: {
|
||||
// allowReturnOutsideFunction: true,
|
||||
// },
|
||||
|
||||
comments: true,
|
||||
ast: false,
|
||||
babelrc: false,
|
||||
highlightCode: false,
|
||||
sourceMaps: true,
|
||||
compact: false
|
||||
})
|
||||
.transform(inlineProp.inlineEnum)
|
||||
.transform(aliasify, (options && options.aliasifyConfig) || {});
|
||||
};
|
45
engine/gulp/util/drop-pure-export.js
Normal file
45
engine/gulp/util/drop-pure-export.js
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
// Drop unused `export` syntax to indicate that the object will only be used inside the module at runtime.
|
||||
// So the expression can be evaluated by uglify.
|
||||
//
|
||||
// Replace:
|
||||
// /*@__DROP_PURE_EXPORT__*/
|
||||
// export xxx
|
||||
// As:
|
||||
// /*@__DROP_PURE_EXPORT__*/
|
||||
// xxx
|
||||
|
||||
const es = require('event-stream');
|
||||
const stream = require('stream');
|
||||
|
||||
const COMMENT_ANNOTATION = `/*@__DROP_PURE_EXPORT__*/`;
|
||||
const REG = /(\/\*@__DROP_PURE_EXPORT__\*\/\s*)(export\s+)?/g;
|
||||
|
||||
module.exports = function (filename) {
|
||||
if (filename.endsWith('.js') || filename.endsWith('.ts')) {
|
||||
return es.map(function (data, callback) {
|
||||
var content = data.toString();
|
||||
if (content.includes(COMMENT_ANNOTATION)) { // fast test
|
||||
let error = false;
|
||||
content = content.replace(REG, function (match, g1, g2) {
|
||||
if (g2) {
|
||||
return g1;
|
||||
}
|
||||
else {
|
||||
// console.log(content);
|
||||
error = true;
|
||||
return match;
|
||||
}
|
||||
});
|
||||
if (error) {
|
||||
return callback(new Error(`Uncaptured comment annotation "${COMMENT_ANNOTATION}" in "${filename}", please use it in the correct way.`));
|
||||
}
|
||||
data = new Buffer(content);
|
||||
}
|
||||
callback(null, data);
|
||||
});
|
||||
}
|
||||
else {
|
||||
return stream.PassThrough();
|
||||
}
|
||||
};
|
42
engine/gulp/util/fix-jsb-javascriptcore.js
Normal file
42
engine/gulp/util/fix-jsb-javascriptcore.js
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
// fix `typeof constructor` on JavaScriptCore
|
||||
|
||||
const ES = require('event-stream');
|
||||
const Path = require('path');
|
||||
|
||||
const getRealTypeOfObj = (function __realTypeOfObj (obj) {
|
||||
if (obj) {
|
||||
if (obj.toString) {
|
||||
if (obj.toString() === '[object CallbackConstructor]')
|
||||
return 'function';
|
||||
}
|
||||
else {
|
||||
// "Cannot convert object to primitive value"
|
||||
}
|
||||
}
|
||||
return 'object';
|
||||
}).toString();
|
||||
|
||||
const TYPEOF_SHIM = `\n${getRealTypeOfObj}\nvar __typeofVal = "";`;
|
||||
|
||||
const TYPEOF_REG = /typeof\s+([$A-Za-z_][0-9A-Za-z_$\.\[\]]*)([\s!=;\)])/g;
|
||||
const TYPEOF_REPLACEMENT = '(__typeofVal = typeof $1, __typeofVal === "object" ? __realTypeOfObj($1) : __typeofVal)$2';
|
||||
|
||||
const SUPPORT_JSC = false;
|
||||
|
||||
module.exports = function () {
|
||||
return ES.through(function (file) {
|
||||
if (Path.extname(file.path) === '.js' && SUPPORT_JSC) {
|
||||
var content = file.contents.toString();
|
||||
|
||||
content = content.replace(TYPEOF_REG, TYPEOF_REPLACEMENT);
|
||||
content += TYPEOF_SHIM;
|
||||
|
||||
// make shim as local variables so that variable names will be mangled
|
||||
content = '(function () {' + content + '})();';
|
||||
|
||||
file.contents = new Buffer(content);
|
||||
}
|
||||
this.emit('data', file);
|
||||
});
|
||||
};
|
52
engine/gulp/util/handleErrors.js
Normal file
52
engine/gulp/util/handleErrors.js
Normal file
@@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
// https://github.com/GoodBoyDigital/pixi.js/blob/c984191777001580b3a81f41cfe354b58d99757f/gulp/util/handleErrors.js
|
||||
var gutil = require('gulp-util'),
|
||||
plumber = require('gulp-plumber'),
|
||||
ERROR = gutil.colors.red('[ERROR]');
|
||||
|
||||
function errorHandler(err) {
|
||||
var msg = err.toString();
|
||||
|
||||
if (msg === '[object Object]') {
|
||||
msg = err;
|
||||
}
|
||||
|
||||
gutil.log(ERROR, err);
|
||||
|
||||
if (err.stack) {
|
||||
gutil.log(ERROR, err.stack);
|
||||
}
|
||||
|
||||
// Keep gulp from hanging on this task
|
||||
this.emit('end');
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
return plumber(errorHandler);
|
||||
};
|
||||
|
||||
module.exports.handler = errorHandler;
|
109
engine/gulp/util/inline-prop.js
Normal file
109
engine/gulp/util/inline-prop.js
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
// Force inline const enum.
|
||||
// We don't use terser >= 4.2.1 to do this because it obsoleted `reduce_funcs` option.
|
||||
//
|
||||
// Replace:
|
||||
// /*@__DROP_PURE_EXPORT__*/
|
||||
// var aa = {
|
||||
// bb: 0,
|
||||
// cc: 1,
|
||||
// };
|
||||
// const UPPER_CASE = 2;
|
||||
// console.log(aa.bb, aa.cc, UPPER_CASE);
|
||||
//
|
||||
// As:
|
||||
// /*@__DROP_PURE_EXPORT__*/
|
||||
// var aa = {
|
||||
// bb: 0,
|
||||
// cc: 1,
|
||||
// };
|
||||
// const UPPER_CASE = 2;
|
||||
// console.log(0, 1, 2);
|
||||
|
||||
const es = require('event-stream');
|
||||
const stream = require('stream');
|
||||
|
||||
const COMMENT_ANNOTATION = `/*@__DROP_PURE_EXPORT__*/`;
|
||||
const CONST_OBJ_REG = /^[ \t]*\/\*@__DROP_PURE_EXPORT__\*\/[\w\s]*?\s+([A-Za-z_$][0-9A-Za-z_$]*)\s*=\s*({[\n\s\S]*?})/gm;
|
||||
const CONST_NUM_REG = /^[ \t]*const[ \t]+([A-Z_$][0-9A-Z_$]*)[ \t]*=[ \t]*(\d{1,2});?$/gm;
|
||||
|
||||
function matchAll (str, reg, callback) {
|
||||
// the easiest matchAll polyfill ; )
|
||||
if (!reg.global) {
|
||||
throw new Error('Can not matchAll if the global property is false.');
|
||||
}
|
||||
str.replace(reg, function (m) {
|
||||
callback.apply(null, arguments);
|
||||
return m;
|
||||
});
|
||||
}
|
||||
|
||||
exports.inlineEnum = function (filename) {
|
||||
if (filename.endsWith('.js') || filename.endsWith('.ts')) {
|
||||
return es.map(function (data, callback) {
|
||||
var content = data.toString();
|
||||
if (content.includes(COMMENT_ANNOTATION)) { // fast test
|
||||
let error = null;
|
||||
matchAll(content, CONST_OBJ_REG, function (match, obj, body) {
|
||||
try {
|
||||
body = Function(`return ${body}`)();
|
||||
}
|
||||
catch (e) {
|
||||
error = new Error(`Failed to inline property "${obj}" in "${filename}", ${e}`);
|
||||
return;
|
||||
}
|
||||
for (const key in body) {
|
||||
let reg = new RegExp(`\\b${obj}\\.${key}\\b`, 'g');
|
||||
let replaced = content.replace(reg, body[key]);
|
||||
if (replaced !== content) {
|
||||
content = replaced;
|
||||
console.log(`[inline-prop] '${obj}.${key}' is inlined with ${body[key]}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
data = new Buffer(content);
|
||||
}
|
||||
callback(null, data);
|
||||
});
|
||||
}
|
||||
else {
|
||||
return stream.PassThrough();
|
||||
}
|
||||
};
|
||||
|
||||
exports.inlineConst = function (filename) {
|
||||
if (filename.endsWith('.js') || filename.endsWith('.ts')) {
|
||||
return es.map(function (data, callback) {
|
||||
var content = data.toString();
|
||||
if (content.includes(COMMENT_ANNOTATION)) { // fast test
|
||||
let error = null;
|
||||
matchAll(content, CONST_NUM_REG, function (match, name, value) {
|
||||
let reg = new RegExp(`([{,]\\s*|\\btypeof[ \\t]+)?(\\b${name}\\b)(?![ \\t]*=)`, 'g'); // not support negative lookbehind...
|
||||
let replaced = content.replace(reg, function (m, g1, g2) {
|
||||
if (m === g2) {
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
return m;
|
||||
}
|
||||
});
|
||||
if (replaced !== content) {
|
||||
content = replaced;
|
||||
console.log(`[inline-prop] '${name}' is inlined with ${value}`);
|
||||
}
|
||||
});
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
data = new Buffer(content);
|
||||
}
|
||||
callback(null, data);
|
||||
});
|
||||
}
|
||||
else {
|
||||
return stream.PassThrough();
|
||||
}
|
||||
};
|
44
engine/gulp/util/polyfill-node-promisify.js
Normal file
44
engine/gulp/util/polyfill-node-promisify.js
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
// Replace node promisify for testing editor-extends.
|
||||
//
|
||||
// Replace:
|
||||
// require('util')
|
||||
// As:
|
||||
// { promisify }
|
||||
|
||||
const es = require('event-stream');
|
||||
const stream = require('stream');
|
||||
|
||||
const promisify = (function (handle) {
|
||||
return function (...args) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
handle(...args, (err, res) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(res);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}).toString();
|
||||
|
||||
const REPLACE = /require\(['"]util['"]\)/g;
|
||||
const AS = `{promisify:${promisify}}`;
|
||||
|
||||
module.exports = function (filename) {
|
||||
if (filename.endsWith('.js') || filename.endsWith('.ts')) {
|
||||
return es.map(function (data, callback) {
|
||||
var content = data.toString();
|
||||
if (REPLACE.test(content)) { // fast test
|
||||
content = content.replace(REPLACE, AS);
|
||||
data = new Buffer(content);
|
||||
}
|
||||
callback(null, data);
|
||||
});
|
||||
}
|
||||
else {
|
||||
return stream.PassThrough();
|
||||
}
|
||||
};
|
202
engine/gulp/util/utils.js
Normal file
202
engine/gulp/util/utils.js
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
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'];
|
||||
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);
|
||||
});
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user