vite-require
Version:
Like Webpack's require
75 lines (74 loc) • 2.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.analyze = exports.TopScopeType = void 0;
const utils_1 = require("./utils");
var TopScopeType;
(function (TopScopeType) {
// require('foo')[.bar]
TopScopeType["ExpressionStatement"] = "ExpressionStatement";
// const bar = rquire('foo')[.bar]
TopScopeType["VariableDeclaration"] = "VariableDeclaration";
})(TopScopeType = exports.TopScopeType || (exports.TopScopeType = {}));
/**
* `require` statement analyzer
* require 语法分析器
*/
function analyze(ast, code) {
const analyzed = {
ast,
code,
require: []
};
(0, utils_1.simpleWalk)(ast, {
CallExpression(node, ancestors) {
if (node.callee.name !== 'require')
return;
const dynamic = checkDynamicId(node);
analyzed.require.push({
node,
ancestors,
topScopeNode: dynamic === 'dynamic'
? undefined
: findTopLevelScope(ancestors),
dynamic,
});
},
AssignmentExpression() {
}
});
return analyzed;
}
exports.analyze = analyze;
function checkDynamicId(node) {
var _a, _b, _c;
if (((_a = node.arguments[0]) === null || _a === void 0 ? void 0 : _a.type) === 'TemplateLiteral' &&
((_b = node.arguments[0]) === null || _b === void 0 ? void 0 : _b.quasis.length) === 1) {
// e.g. require(`@/foo/bar.js`)
return 'Literal';
}
// Only `require` with one-argument is supported
return ((_c = node.arguments[0]) === null || _c === void 0 ? void 0 : _c.type) !== 'Literal' ? 'dynamic' : undefined;
}
// At present, only the "MemberExpression" of the one-depth is considered as the top-level scope
// 当前,只认为一层的 MemberExpression 顶级作用域
// e.g.
// ✅ require('foo').bar
// ❌ require('foo').bar.baz
//
// Will be return nearset scope ancestor node (🎯-①)
// 这将返回最近作用域的祖先节点
function findTopLevelScope(ancestors) {
const ances = ancestors.map(an => an.type).join();
const arr = [...ancestors].reverse();
if (/Program,ExpressionStatement,(MemberExpression,)?CallExpression$/.test(ances)) {
// Program,ExpressionStatement,CallExpression | require('foo')
// Program,ExpressionStatement,MemberExpression,CallExpression | require('foo').bar
return arr.find(e => e.type === TopScopeType.ExpressionStatement);
}
// At present, "ancestors" contains only one depth of "MemberExpression"
if (/Program,VariableDeclaration,VariableDeclarator,(MemberExpression,)?CallExpression$/.test(ances)) {
// const bar = require('foo').bar
// const { foo, bar: baz } = require('foo')
return arr.find(e => e.type === TopScopeType.VariableDeclaration);
}
}