babel-plugin-define-variables
Version:
一个类似 webpack.DefinePlugin 的 Babel 插件,用于在编译时定义全局变量和常量
348 lines (277 loc) • 10.3 kB
JavaScript
"use strict";
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var t = require('@babel/types');
var findUp = require('find-up');
var fs = require('fs');
var path = require('path');
var template = require('@babel/template').default;
function formatDate(date, fmt) {
var o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds(),
'q+': Math.floor((date.getMonth() + 3) / 3),
S: date.getMilliseconds()
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
Object.keys(o).forEach(function (k) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
}
});
return fmt;
}
function fileExists(path) {
try {
return !fs.accessSync(path, fs.F_OK);
} catch (e) {
return false;
}
}
function getConfigPath(filename) {
var packagePath = findUp.sync('package.json', {
cwd: path.dirname(filename),
type: 'file'
});
if (packagePath && fileExists(packagePath)) return packagePath;
}
var NOW = formatDate(new Date(), 'yyyy-MM-dd hh:mm:ss');
var constCached = [];
function getConstCache(filename) {
var pkgPath = getConfigPath(filename);
if (!pkgPath || filename === path.resolve(pkgPath)) return {};
var cwd;
var cache = constCached[pkgPath];
if (!cache) {
var pkg = require(pkgPath);
if (!pkg || !Object.keys(pkg).length) return {};
cwd = path.dirname(pkgPath);
cache = {
pkg: pkg,
cwd: cwd
};
constCached[pkgPath] = cache;
cache.now = NOW;
}
cwd = cache.cwd;
cache.filename = '/' + path.relative(cwd, filename).replace(/\\/g, '/');
cache.dirname = '/' + path.relative(cwd, path.dirname(filename)).replace(/\\/g, '/');
return cache;
}
function arr2Expression(arr, parent) {
var temp = '';
var vars = {};
arr.forEach(function (v, i) {
// eslint-disable-next-line no-use-before-define
var expr = var2Expression(v, arr);
if (!expr) return;
var key = "$".concat(i);
temp += (temp ? ', ' : '') + key;
vars[key] = expr;
});
return template("[".concat(temp, "]"))(vars);
}
function obj2Expression(obj, parent) {
var props = Object.keys(obj).map(function (k) {
var v = obj[k]; // eslint-disable-next-line no-use-before-define
var expr = var2Expression(v, obj);
if (!expr) return;
return t.objectProperty(t.identifier(k), expr);
}).filter(Boolean);
return t.objectExpression(props);
}
function var2Expression(v, parent) {
if (t.isNode(v)) return v;
if (v === undefined) return;
if (Array.isArray(v)) return arr2Expression(v, parent);
switch (_typeof(v)) {
case 'string':
return t.stringLiteral(v);
case 'boolean':
return t.booleanLiteral(v);
case 'number':
return t.numericLiteral(v);
case 'object':
if (v === null) return t.nullLiteral();
if (v instanceof RegExp) return t.regExpLiteral(v.source, v.flags);
if (v instanceof Date) return template('new Date(TIME)')({
TIME: t.numericLiteral(v.getTime())
});
if (v instanceof Function) return template(v.toString())();
return obj2Expression(v, parent);
default:
return t.identifier('undefined');
}
}
function expr2str(expr) {
if (!expr) return '';
if (typeof expr === 'string') return expr; // if (expr.extra) return expr.extra.raw;
switch (expr.type) {
case 'JSXExpressionContainer':
return expr2str(expr.expression);
case 'MemberExpression':
case 'JSXMemberExpression':
// eslint-disable-next-line no-use-before-define
return memberExpr2Str(expr);
case 'Identifier':
case 'JSXIdentifier':
return expr.name;
case 'JSXNamespacedName':
return "".concat(expr.namespace.name, ":").concat(expr.name.name);
case 'ThisExpression':
return 'this';
case 'NumericLiteral':
case 'BooleanLiteral':
case 'StringLiteral':
return expr.value;
case 'NullLiteral':
return 'null';
case 'RegExpLiteral':
return "/".concat(expr.pattern, "/").concat(expr.flags);
case 'SpreadElement':
return "...".concat(expr2str(expr.argument));
case 'BinaryExpression':
return "".concat(expr2str(expr.left), " ").concat(expr.operator, " ").concat(expr2str(expr.right));
case 'UpdateExpression':
case 'UnaryExpression':
return "".concat(expr.prefix ? expr.operator : '').concat(expr2str(expr.argument)).concat(!expr.prefix ? expr.operator : '');
case 'ConditionalExpression':
return "".concat(expr2str(expr.test), " ? ").concat(expr2str(expr.consequent), " : ").concat(expr2str(expr.alternate));
case 'CallExpression':
return "".concat(expr2str(expr.callee), "(").concat(expr.arguments.map(function (a) {
return expr2str(a);
}).join(','), ")");
case 'NewExpression':
return "new ".concat(expr2str(expr.callee), "(").concat(expr.arguments.map(function (a) {
return expr2str(a);
}).join(','), ")");
case 'VariableDeclarator':
return "".concat(expr.id).concat(expr.init ? " = ".concat(expr2str(expr.init)) : '');
case 'VariableDeclaration':
return "".concat(expr.kind, " ").concat(expr.declarations.map(function (d) {
return expr2str(d);
}), ";");
case 'BlockStatement':
return "{".concat(expr2str(expr.body), "}");
case 'TemplateLiteral':
// eslint-disable-next-line no-use-before-define
return temp2var(expr);
case 'TaggedTemplateExpression':
return "".concat(expr2str(expr2str(expr.tag))).concat(expr2str(expr.quasi));
case 'FunctionExpression':
return "function ".concat(expr2str(expr.id), "(").concat(expr.params.map(function (a) {
return expr2str(a);
}).join(','), ")").concat(expr2str(expr.body));
case 'AssignmentPattern':
return "".concat(expr2str(expr.left), " = ").concat(expr2str(expr.right));
case 'ArrayExpression':
case 'ArrayPattern':
return "[".concat(expr.elements.map(function (v) {
return expr2str(v);
}).join(', '), "]");
case 'ObjectProperty':
return "".concat(expr.computed ? "[".concat(expr2str(expr.key), "]") : expr2str(expr.key), ": ").concat(expr2str(expr.value));
case 'ObjectMethod':
// eslint-disable-next-line
return "".concat(expr.kind !== 'method' ? "".concat(expr.kind, " ") : '').concat(expr2str(expr.key), "(").concat(expr.params.map(function (a) {
return expr2str(a);
}).join(', '), ")").concat(expr2str(expr.body));
case 'ObjectPattern':
case 'ObjectExpression':
return "{".concat(expr.properties.map(function (v) {
return expr2str(v);
}).join(', '), "}");
default:
return '';
}
}
function temp2var(expr) {
var arr = [].concat(_toConsumableArray(expr.expressions), _toConsumableArray(expr.quasis)).sort(function (a, b) {
return a.start - b.start;
});
var ret = '';
arr.forEach(function (v) {
if (v.type === 'TemplateElement') ret += v.value.raw;else ret += '${' + expr2str(v) + '}';
});
return '`' + ret + '`';
}
function memberExpr2Str(expr) {
var objStr;
var object = expr.object;
if (!object) return String(expr.value);
switch (expr.object.type) {
case 'MemberExpression':
case 'JSXMemberExpression':
objStr = memberExpr2Str(expr.object);
break;
default:
objStr = expr2str(expr.object);
}
var propIsMember = expr.property.type === 'MemberExpression';
var propStr = expr2str(expr.property);
return objStr + (objStr && !propIsMember ? '.' : '') + (propIsMember ? "[".concat(propStr, "]") : propStr);
}
function getPackage(filename) {
var configPath = filename && getConfigPath(filename);
if (configPath) return require(configPath);
}
var _toString = Object.prototype.toString;
function isPlainObject(obj) {
return _toString.call(obj) === '[object Object]';
}
function mergeObject(target) {
function _mergeObject(target, source, copiedObjects) {
if (!target) return target;
if (!isPlainObject(source)) return target;
copiedObjects.push({
source: source,
target: target
});
Object.keys(source).forEach(function (key) {
var v = source[key];
if (isPlainObject(v)) {
var copied = copiedObjects.find(function (c) {
return c.target === v;
});
if (copied) target[key] = copied.target;else {
var w = target[key];
if (!isPlainObject(w)) w = target[key] = {};
_mergeObject(w, v, copiedObjects);
}
} else target[key] = v;
});
return target;
}
var ret = target;
var copiedObjects = [];
for (var i = 1; i < arguments.length; i++) {
_mergeObject(ret, arguments[i], copiedObjects);
}
return ret;
}
var _hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* @param {object} obj
* @param {string} key
* @returns {boolean}
*/
function hasOwnProp(obj, key) {
return Boolean(obj) && _hasOwnProperty.call(obj, key);
}
module.exports = {
getConstCache: getConstCache,
var2Expression: var2Expression,
arr2Expression: arr2Expression,
obj2Expression: obj2Expression,
expr2str: expr2str,
getConfigPath: getConfigPath,
getPackage: getPackage,
mergeObject: mergeObject,
hasOwnProp: hasOwnProp
};