babel-plugin-transform-me-module
Version:
Transform me.js module to commonjs module
131 lines (110 loc) • 3.85 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));
}