@areslabs/alita-core
Version:
alita-core
248 lines (208 loc) • 7.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _traverse = _interopRequireDefault(require("@babel/traverse"));
var npath = _interopRequireWildcard(require("path"));
var _configure = _interopRequireDefault(require("../configure"));
var _uast = require("../util/uast");
var _cacheModuleInfos = require("../util/cacheModuleInfos");
var _getAndStorecompInfos = require("../util/getAndStorecompInfos");
var _util = require("../util/util");
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) Areslabs.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* 收集alita 处理所必须的信息
* @param context
*/
function _default(context) {
const filepath = this.resourcePath;
console.log(`开始处理:${filepath.replace(_configure.default.inputFullpath, '')} ...`.info);
const ast = (0, _uast.parseCode)(context, npath.extname(filepath)); //TODO 暂时通过此方式,让ast和sourceCode/filepath 建立联系
// @ts-ignore
ast.__sourceCode = context; // @ts-ignore
ast.__filepath = filepath;
const {
isEntry,
isRF,
isFuncComp,
imports,
exports,
JSXElements
} = getFileInfo(ast, filepath);
const moduleInfo = (0, _cacheModuleInfos.getModuleInfo)(filepath);
if (moduleInfo) {
checkImports(moduleInfo.im, imports, filepath);
}
(0, _cacheModuleInfos.setModuleInfo)(filepath, imports, exports, isRF, isEntry, JSXElements);
return {
ast,
isEntry,
isRF,
isFuncComp,
rawCode: context
};
}
function checkImports(oldIm, newIm, filepath) {
const oldKeys = Object.keys(oldIm);
for (let i = 0; i < oldKeys.length; i++) {
const k = oldKeys[i];
if (newIm[k]) {
if (oldIm[k].source !== newIm[k].source) {
console.log(`${filepath.replace(_configure.default.inputFullpath, '')} 检测到 ${k} 导入路径改变 ${oldIm[k].source} --> ${newIm[k].source} ,\n若 ${k}是组件,可能出现usingComponents路径错误,需要重新执行 alita --dev`.warn);
}
}
}
}
function getFileInfo(ast, filepath) {
let isRF = false;
let isEntry = false;
let isClassComp = false;
let isRNEntry = false;
const JSXElements = new Set();
const im = {};
const ex = {};
(0, _traverse.default)(ast, {
ClassDeclaration: path => {
const sc = path.node.superClass;
isClassComp = (0, _uast.isReactComponent)(sc);
},
JSXOpeningElement: path => {
if ((0, _uast.isReactFragment)(path.node)) {
return;
}
const name = path.node.name.name;
if (name === 'Router') {
isEntry = true;
}
JSXElements.add(name);
isRF = true;
},
Identifier: path => {
// Expo root
if (path.node.name === 'registerRootComponent') {
isRNEntry = true;
}
},
CallExpression: path => {
const callee = path.node.callee;
if (callee.type === 'MemberExpression' && callee.object // @ts-ignore
&& callee.object.name === 'AppRegistry' && callee.property && callee.property.name === 'registerComponent') {
isRNEntry = true;
}
}
});
if (!isEntry) {
// 处理小程序组件信息
// 必须在JSXElement收集结束之后 处理
(0, _traverse.default)(ast, {
exit(path) {
if (path.type === 'ImportDeclaration') {
handleImport(path, filepath, JSXElements, im);
return;
} // export {A} from './A'
if (path.type === 'ExportNamedDeclaration' && path.node.source) {
// TODO
handleExportSource(path, filepath, JSXElements, im);
return;
} // @ts-ignore
if (path.type === 'CallExpression' && path.node.callee.name === 'require' && path.key === 'init') {
handleRequire(path, filepath, JSXElements, im);
return;
}
}
});
}
if (isClassComp) {
isRF = true;
}
const isFuncComp = isRF && !isClassComp;
return {
isRF,
isRNEntry,
isEntry,
isFuncComp,
imports: im,
exports: ex,
JSXElements
};
}
function handleRequire(path, filepath, JSXElements, im) {
const relativePath = path.node.arguments[0].value;
const idens = [];
const id = path.parentPath.node.id;
if (id.type === 'Identifier') {
im[id.name] = {
source: relativePath,
defaultSpecifier: true
};
idens.push(id.name);
} else if (id.type === 'ObjectPattern') {
const opp = id.properties;
for (let i = 0; i < opp.length; i++) {
const item = opp[i];
if (item.type === 'ObjectProperty') {
im[item.value.name] = {
source: relativePath,
defaultSpecifier: false,
imported: item.key.name
};
idens.push(item.value.name);
}
}
}
const isLibPath = (0, _util.judgeLibPath)(relativePath);
if (!isLibPath) return;
const isCompPack = idens.some(iden => JSXElements.has(iden));
if (!isCompPack) return;
(0, _getAndStorecompInfos.getLibCompInfos)(idens, JSXElements, filepath, relativePath);
}
function handleImport(path, filepath, JSXElements, im) {
const relativePath = path.node.source.value;
const idens = [];
path.node.specifiers.forEach(spe => {
//spe = spe as t.ImportSpecifier
const name = spe.local.name;
im[name] = {
source: relativePath,
defaultSpecifier: spe.type === 'ImportDefaultSpecifier',
// @ts-ignore
imported: spe.type === 'ImportSpecifier' ? spe.imported.name : null
};
idens.push(name);
});
const isLibPath = (0, _util.judgeLibPath)(relativePath);
if (!isLibPath) return;
const isCompPack = idens.some(iden => JSXElements.has(iden));
if (!isCompPack) return;
(0, _getAndStorecompInfos.getLibCompInfos)(idens, JSXElements, filepath, relativePath);
}
function handleExportSource(path, filepath, JSXElements, im) {
const relativePath = path.node.source.value;
const idens = [];
path.node.specifiers.forEach(spe => {
//spe = spe as t.ImportSpecifier
const name = spe.exported.name;
im[name] = {
source: relativePath,
defaultSpecifier: false,
// @ts-ignore
imported: spe.local.name
};
idens.push(name);
});
const isLibPath = (0, _util.judgeLibPath)(relativePath);
if (!isLibPath) return;
const isCompPack = idens.some(iden => JSXElements.has(iden));
if (!isCompPack) return;
(0, _getAndStorecompInfos.getLibCompInfos)(idens, JSXElements, filepath, relativePath);
}