UNPKG

@areslabs/alita-core

Version:

alita-core

248 lines (208 loc) 7.55 kB
"use strict"; 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); }