babel-plugin-transform-me-module
Version:
Transform me.js module to commonjs module
113 lines (98 loc) • 4.43 kB
JavaScript
import {resolve} from 'path';
import {get, each, findKey} from 'lodash';
import {parse} from '@babel/parser';
import {getMeModuleInstance, relativeRequirePath} from 'me-module-utils';
import {isProvideFunctionCall, isReadyFunctionCall, isEvalFunctionCall} from "./pathDetector";
import {generateModuleRequire, generateRequireCss} from "./codeGenerator";
import {unshiftHeader} from "./pathModifier";
export default function transformMeModulePlugin({types: t}) {
return {
pre(state) {
this._filename = state.opts.filename;
this._absolutePath = resolve(this._filename);
if (state.opts.enableDebug) {
console.log('Parsing...', this._absolutePath);
}
},
visitor: {
Program: {
exit(path, state) {
const basePath = resolve(state.opts.basePath);
const meModules = getGlobalMeModuleInstance({basePath, enableDebug: state.opts.enableDebug});
const curModule = meModules.get({src: this._absolutePath});
if (!curModule) {
return;
}
// 在头部中插入解构依赖模块
each(curModule.deps, (dep, name) => {
const mod = meModules.get({name});
const depAbsolutePath = mod.absolutePath;
const requireRelativePath = relativeRequirePath(this._absolutePath, depAbsolutePath);
const requireNode = parse(generateModuleRequire(mod.varName, requireRelativePath)).program.body[0];
unshiftHeader(path, requireNode);
});
// 插入css
each(curModule.css, cssPath => {
const cssRelativePath = relativeRequirePath(this._absolutePath, cssPath);
const requireNode = parse(generateRequireCss(cssRelativePath)).program.body[0];
unshiftHeader(path, requireNode);
});
}
},
CallExpression: {
enter(path) {
const node = path.node;
if (isEvalFunctionCall(node)) {
return path.remove();
}
if (isProvideFunctionCall(node) || isReadyFunctionCall(node)) {
let meCallbackFn = null;
let i = -1;
while(i++ < path.node.arguments.length) {
const curNode = path.node.arguments[i];
if (t.isFunctionExpression(curNode)) {
meCallbackFn = curNode;
break;
}
}
if (meCallbackFn) {
meCallbackFn.params = [];
path.replaceWith(t.callExpression(meCallbackFn, []));
}
}
}
},
Identifier(path, state) {
const basePath = resolve(state.opts.basePath);
const meModules = getGlobalMeModuleInstance({basePath, enableDebug: state.opts.enableDebug});
const curModule = meModules.get({src: this._absolutePath});
if (!curModule || !curModule.isMeModule) {
return;
}
if (path.node.name === 'exports') {
if (path.parentPath.node.property) {
const exportsVar = path.parentPath.node.property.name;
const depName = findDep(exportsVar, curModule.deps);
if (!curModule.selfExports.includes(exportsVar) && depName) {
path.node.name = `${depName}_module`;
}
}
}
}
}
};
}
function getGlobalMeModuleInstance(options) {
global.meModules = getMeModuleInstance(options);
return global.meModules;
}
/**
* 搜索某个变量属于那个模块
*
* @param {string} exportName 输出变量名
* @param {Object} deps 依赖关系
* @returns {string}
*/
function findDep(exportName, deps) {
return findKey(deps, e => e.includes(exportName));
}