@kezh/my-custom-js-converter 0.1.59 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/context/map_context.d.ts +7 -0
- package/core/context/map_context.js +49 -16
- package/core/util/ast.d.ts +27 -4
- package/core/util/ast.js +87 -17
- package/package.json +1 -1
|
@@ -58,6 +58,7 @@ class MapContext {
|
|
|
58
58
|
}
|
|
59
59
|
init() {
|
|
60
60
|
this.buildMapContext(this.srcPath, this.entry, true);
|
|
61
|
+
this.filtering();
|
|
61
62
|
this.shaking();
|
|
62
63
|
this.writeToLocal();
|
|
63
64
|
}
|
|
@@ -82,7 +83,8 @@ class MapContext {
|
|
|
82
83
|
}
|
|
83
84
|
const requireModPathByName = (0, ast_1.getRequireModPaths)(path_1.default.dirname(inPath), srcAst);
|
|
84
85
|
const requireModNames = [...requireModPathByName.keys()].map((name) => name);
|
|
85
|
-
|
|
86
|
+
!root && requireModNames.unshift(entry);
|
|
87
|
+
const requireMethodNamesByMod = (0, ast_1.getRequireMethodNames)(srcAst, entry, requireModNames);
|
|
86
88
|
const dependencies = new map_config_1.Dependencies();
|
|
87
89
|
requireModNames.forEach((name) => {
|
|
88
90
|
const dep = new map_config_1.Dependency(requireMethodNamesByMod.get(name));
|
|
@@ -94,23 +96,54 @@ class MapContext {
|
|
|
94
96
|
this.buildMapContext(modPath, name, false);
|
|
95
97
|
});
|
|
96
98
|
}
|
|
97
|
-
|
|
99
|
+
/**
|
|
100
|
+
* 过滤self的dependencies中无效方法
|
|
101
|
+
*/
|
|
102
|
+
filtering() {
|
|
98
103
|
this.getModNames().forEach((modName) => {
|
|
99
|
-
const depNames = this.getDependencyNameByMod(modName);
|
|
100
|
-
if (!depNames.length) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
const methodNames = this.getMethodNamesByMod(modName);
|
|
104
|
-
if (!methodNames.length) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const srcAst = (0, ast_1.parseSrcAst)(this.getSrcPathByMod(modName));
|
|
108
|
-
const methodNamesByDepName = (0, ast_1.getDependentMethodNames)(srcAst, methodNames, depNames);
|
|
109
104
|
const mod = this.getMod(modName);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
const dependencies = mod.dependencies;
|
|
106
|
+
Object.keys(dependencies).forEach((depName) => {
|
|
107
|
+
const srcAst = (0, ast_1.parseSrcAst)(this.getSrcPathByMod(depName));
|
|
108
|
+
const methodNames = (0, ast_1.getObjectMethodNames)((0, ast_1.getObjectMethodsByEntryAndMethodNames)(srcAst, depName, dependencies[depName].methods));
|
|
109
|
+
dependencies[depName].methods = methodNames;
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 去除dependencies中未使用方法
|
|
115
|
+
*/
|
|
116
|
+
shaking() {
|
|
117
|
+
const astMap = new Map();
|
|
118
|
+
this.getModNames().forEach((mod) => {
|
|
119
|
+
astMap.set(mod, (0, ast_1.parseSrcAst)(this.getMod(mod).src));
|
|
120
|
+
});
|
|
121
|
+
const useMethodNameMap = new Map();
|
|
122
|
+
this.getModNames().forEach((mod) => {
|
|
123
|
+
useMethodNameMap.set(mod, this.getMethodNamesByMod(mod));
|
|
124
|
+
});
|
|
125
|
+
const dependencies = this.getMod("self").dependencies;
|
|
126
|
+
const filterMethodMap = new Map();
|
|
127
|
+
const readyStack = Object.keys(dependencies).flatMap((name) => dependencies[name].methods.map((method) => [name, method]));
|
|
128
|
+
while (readyStack.length) {
|
|
129
|
+
const method = readyStack.shift();
|
|
130
|
+
let filterMethods = new Set();
|
|
131
|
+
if (filterMethodMap.has(method[0])) {
|
|
132
|
+
filterMethods = filterMethodMap.get(method[0]);
|
|
133
|
+
}
|
|
134
|
+
filterMethods.add(method[1]);
|
|
135
|
+
filterMethodMap.set(method[0], filterMethods);
|
|
136
|
+
const inlineMethods = (0, ast_1.getInlineMethodsByMethodName)(astMap.get(method[0]), method[0], method[1], useMethodNameMap);
|
|
137
|
+
readyStack.push(...inlineMethods.map((m) => m.split("#")));
|
|
138
|
+
}
|
|
139
|
+
[...filterMethodMap.keys()].forEach((fMod) => {
|
|
140
|
+
const filterMethods = filterMethodMap.get(fMod);
|
|
141
|
+
this.getModNames().forEach((modName) => {
|
|
142
|
+
var _a;
|
|
143
|
+
const dep = (_a = this.getMod(modName)) === null || _a === void 0 ? void 0 : _a.dependencies[fMod];
|
|
144
|
+
if (dep) {
|
|
145
|
+
dep.methods = dep.methods.filter((m) => filterMethods.has(m));
|
|
146
|
+
}
|
|
114
147
|
});
|
|
115
148
|
});
|
|
116
149
|
}
|
package/core/util/ast.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Node } from "@babel/core";
|
|
|
2
2
|
import { ObjectMethod } from "@babel/types";
|
|
3
3
|
import { Mod } from "../config/map_config";
|
|
4
4
|
import { MapContext } from "../context/map_context";
|
|
5
|
-
declare type AstType = Node | Node[] | null | undefined;
|
|
5
|
+
export declare type AstType = Node | Node[] | null | undefined;
|
|
6
6
|
export declare function parseSrcAst(srcPath?: string): AstType;
|
|
7
7
|
export declare function outputObjectMethods(outPath: string, methods: ObjectMethod[]): void;
|
|
8
8
|
/**
|
|
@@ -15,12 +15,13 @@ export declare function outputObjectMethods(outPath: string, methods: ObjectMeth
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function getRequireModPaths(baseDir: string, srcAst: AstType, ignoreMod?: string[]): Map<string, string>;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* 获取源码方法中引用的第三方模块方法名和自身模块方法名
|
|
19
19
|
* @param mod - 依赖模块
|
|
20
|
+
* @param entry - 入口对象
|
|
20
21
|
* @param srcAst - 源码AST
|
|
21
22
|
* @returns
|
|
22
23
|
*/
|
|
23
|
-
export declare function getRequireMethodNames(srcAst: AstType, mod: string[]): Map<string, string[]>;
|
|
24
|
+
export declare function getRequireMethodNames(srcAst: AstType, entry: string, mod: string[]): Map<string, string[]>;
|
|
24
25
|
/**
|
|
25
26
|
* 获取方法名
|
|
26
27
|
* @param methods
|
|
@@ -42,7 +43,22 @@ export declare function getObjectMethodsByEntryAndMethodNames(srcAst: AstType, e
|
|
|
42
43
|
* @param methods
|
|
43
44
|
*/
|
|
44
45
|
export declare function getObjectMehtodsByMehtodNamesAndInsideOwnMethods(srcAst: AstType, entry: string, methodNames: string[]): ObjectMethod[];
|
|
46
|
+
/**
|
|
47
|
+
* 修改依赖方法调用者
|
|
48
|
+
* @param srcAst
|
|
49
|
+
* @param entry
|
|
50
|
+
* @param mod
|
|
51
|
+
* @param methods
|
|
52
|
+
* @param root
|
|
53
|
+
*/
|
|
45
54
|
export declare function modifyObjectMethods(srcAst: AstType, entry: string, mod: Mod, methods: ObjectMethod[], root?: boolean): void;
|
|
55
|
+
/**
|
|
56
|
+
* 获取调用方法中所依赖第三方模块方法名
|
|
57
|
+
* @param srcAst
|
|
58
|
+
* @param methodNames - 调用方法名
|
|
59
|
+
* @param depNames - 依赖模块名
|
|
60
|
+
* @returns
|
|
61
|
+
*/
|
|
46
62
|
export declare function getDependentMethodNames(srcAst: AstType, methodNames: string[], depNames: string[]): Map<string, string[]>;
|
|
47
63
|
/**
|
|
48
64
|
* 生成导入语句
|
|
@@ -57,4 +73,11 @@ export declare function importMods(outDir: string, srcAst: AstType, mapContext:
|
|
|
57
73
|
* @param srcAst - 源码AST
|
|
58
74
|
*/
|
|
59
75
|
export declare function deleteModMethods(srcAst: AstType, mapContext: MapContext): void;
|
|
60
|
-
|
|
76
|
+
/**
|
|
77
|
+
* 获取方法内部调用的方法名
|
|
78
|
+
* @param srcAst - 源码AST
|
|
79
|
+
* @param entry - 入口
|
|
80
|
+
* @param methodName - 方法名
|
|
81
|
+
* @param mapContext
|
|
82
|
+
*/
|
|
83
|
+
export declare function getInlineMethodsByMethodName(srcAst: AstType, entry: string, methodName: string, useMethodNameMap: Map<string, string[]>): string[];
|
package/core/util/ast.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.deleteModMethods = exports.importMods = exports.getDependentMethodNames = exports.modifyObjectMethods = exports.getObjectMehtodsByMehtodNamesAndInsideOwnMethods = exports.getObjectMethodsByEntryAndMethodNames = exports.getObjectMethodNames = exports.getRequireMethodNames = exports.getRequireModPaths = exports.outputObjectMethods = exports.parseSrcAst = void 0;
|
|
6
|
+
exports.getInlineMethodsByMethodName = exports.deleteModMethods = exports.importMods = exports.getDependentMethodNames = exports.modifyObjectMethods = exports.getObjectMehtodsByMehtodNamesAndInsideOwnMethods = exports.getObjectMethodsByEntryAndMethodNames = exports.getObjectMethodNames = exports.getRequireMethodNames = exports.getRequireModPaths = exports.outputObjectMethods = exports.parseSrcAst = void 0;
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const parser_1 = require("@babel/parser");
|
|
9
9
|
const traverse_1 = __importDefault(require("@babel/traverse"));
|
|
@@ -48,9 +48,12 @@ function getRequireModPaths(baseDir, srcAst, ignoreMod) {
|
|
|
48
48
|
const modPathByName = new Map();
|
|
49
49
|
(0, traverse_1.default)(srcAst, {
|
|
50
50
|
Program(path) {
|
|
51
|
-
path.node.body
|
|
52
|
-
.filter(item =>
|
|
53
|
-
|
|
51
|
+
path.node.body
|
|
52
|
+
.filter((item) => core_1.types.isVariableDeclaration(item))
|
|
53
|
+
.flatMap((item) => item.declarations)
|
|
54
|
+
.filter((item) => {
|
|
55
|
+
if (core_1.types.isCallExpression(item.init) &&
|
|
56
|
+
core_1.types.isIdentifier(item.init.callee)) {
|
|
54
57
|
if (item.init.callee.name === "require") {
|
|
55
58
|
if (core_1.types.isIdentifier(item.id)) {
|
|
56
59
|
if (ignoreMod === null || ignoreMod === void 0 ? void 0 : ignoreMod.includes(item.id.name)) {
|
|
@@ -63,8 +66,9 @@ function getRequireModPaths(baseDir, srcAst, ignoreMod) {
|
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
68
|
return false;
|
|
66
|
-
})
|
|
67
|
-
|
|
69
|
+
})
|
|
70
|
+
.forEach((item) => {
|
|
71
|
+
const args = item.init.arguments;
|
|
68
72
|
if (args.length) {
|
|
69
73
|
const modName = item.id.name;
|
|
70
74
|
const modPath = args[0].value;
|
|
@@ -77,25 +81,32 @@ function getRequireModPaths(baseDir, srcAst, ignoreMod) {
|
|
|
77
81
|
}
|
|
78
82
|
exports.getRequireModPaths = getRequireModPaths;
|
|
79
83
|
/**
|
|
80
|
-
*
|
|
84
|
+
* 获取源码方法中引用的第三方模块方法名和自身模块方法名
|
|
81
85
|
* @param mod - 依赖模块
|
|
86
|
+
* @param entry - 入口对象
|
|
82
87
|
* @param srcAst - 源码AST
|
|
83
88
|
* @returns
|
|
84
89
|
*/
|
|
85
|
-
function getRequireMethodNames(srcAst, mod) {
|
|
90
|
+
function getRequireMethodNames(srcAst, entry, mod) {
|
|
86
91
|
const methodsByMod = new Map();
|
|
87
92
|
(0, traverse_1.default)(srcAst, {
|
|
88
93
|
MemberExpression(path) {
|
|
89
|
-
const invokeObj = path.node.object;
|
|
90
|
-
if (!core_1.types.isIdentifier(invokeObj)) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
94
|
const invokeMethod = path.node.property;
|
|
94
95
|
if (!core_1.types.isIdentifier(invokeMethod)) {
|
|
95
96
|
return;
|
|
96
97
|
}
|
|
97
|
-
const
|
|
98
|
-
|
|
98
|
+
const invokeObj = path.node.object;
|
|
99
|
+
let key = null;
|
|
100
|
+
if (core_1.types.isIdentifier(invokeObj)) {
|
|
101
|
+
key = invokeObj.name;
|
|
102
|
+
if (!mod.includes(key)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else if (core_1.types.isThisExpression(invokeObj)) {
|
|
107
|
+
key = entry;
|
|
108
|
+
}
|
|
109
|
+
if (!key) {
|
|
99
110
|
return;
|
|
100
111
|
}
|
|
101
112
|
let methods = [];
|
|
@@ -224,6 +235,14 @@ function getInsideOwnMethodNames(srcAst, entry, methodNames, allMethodNameSet =
|
|
|
224
235
|
insideMethodNames.push(...getInsideOwnMethodNames(srcAst, entry, insideMethodNames, allMethodNameSet));
|
|
225
236
|
return insideMethodNames;
|
|
226
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* 修改依赖方法调用者
|
|
240
|
+
* @param srcAst
|
|
241
|
+
* @param entry
|
|
242
|
+
* @param mod
|
|
243
|
+
* @param methods
|
|
244
|
+
* @param root
|
|
245
|
+
*/
|
|
227
246
|
function modifyObjectMethods(srcAst, entry, mod, methods, root = false) {
|
|
228
247
|
const deps = Object.keys(mod.dependencies);
|
|
229
248
|
const methodNames = getObjectMethodNames(methods);
|
|
@@ -244,8 +263,9 @@ function modifyObjectMethods(srcAst, entry, mod, methods, root = false) {
|
|
|
244
263
|
path.node.object = core_1.types.thisExpression();
|
|
245
264
|
}
|
|
246
265
|
else if (deps.includes(depName)) {
|
|
247
|
-
|
|
248
|
-
|
|
266
|
+
if (core_1.types.isIdentifier(path.node.property) &&
|
|
267
|
+
mod.dependencies[depName].methods.includes(path.node.property.name)) {
|
|
268
|
+
path.node.object = core_1.types.thisExpression();
|
|
249
269
|
path.node.property.name = `${path.node.property.name}__${depName}`;
|
|
250
270
|
}
|
|
251
271
|
}
|
|
@@ -263,6 +283,13 @@ function modifyObjectMethods(srcAst, entry, mod, methods, root = false) {
|
|
|
263
283
|
});
|
|
264
284
|
}
|
|
265
285
|
exports.modifyObjectMethods = modifyObjectMethods;
|
|
286
|
+
/**
|
|
287
|
+
* 获取调用方法中所依赖第三方模块方法名
|
|
288
|
+
* @param srcAst
|
|
289
|
+
* @param methodNames - 调用方法名
|
|
290
|
+
* @param depNames - 依赖模块名
|
|
291
|
+
* @returns
|
|
292
|
+
*/
|
|
266
293
|
function getDependentMethodNames(srcAst, methodNames, depNames) {
|
|
267
294
|
const methodNamesByDepName = new Map();
|
|
268
295
|
(0, traverse_1.default)(srcAst, {
|
|
@@ -300,7 +327,7 @@ exports.getDependentMethodNames = getDependentMethodNames;
|
|
|
300
327
|
*/
|
|
301
328
|
function importMods(outDir, srcAst, mapContext) {
|
|
302
329
|
const depNames = mapContext.getDependencyNameByMod("self");
|
|
303
|
-
const importMods = depNames.map(name => {
|
|
330
|
+
const importMods = depNames.map((name) => {
|
|
304
331
|
const srcPath = mapContext.getSrcPathByMod(name);
|
|
305
332
|
const requireFrom = (0, path_1.relative)(outDir, srcPath.replace(/(index)?\.js$/, "")).replace(/[\\]+/g, "/");
|
|
306
333
|
const variableDeclarator = core_1.types.variableDeclarator(core_1.types.identifier(name), core_1.types.callExpression(core_1.types.identifier("require"), [
|
|
@@ -360,3 +387,46 @@ function deleteModMethods(srcAst, mapContext) {
|
|
|
360
387
|
});
|
|
361
388
|
}
|
|
362
389
|
exports.deleteModMethods = deleteModMethods;
|
|
390
|
+
/**
|
|
391
|
+
* 获取方法内部调用的方法名
|
|
392
|
+
* @param srcAst - 源码AST
|
|
393
|
+
* @param entry - 入口
|
|
394
|
+
* @param methodName - 方法名
|
|
395
|
+
* @param mapContext
|
|
396
|
+
*/
|
|
397
|
+
function getInlineMethodsByMethodName(srcAst, entry, methodName, useMethodNameMap) {
|
|
398
|
+
const inlineMethods = new Set();
|
|
399
|
+
const selfMethods = useMethodNameMap.get(entry);
|
|
400
|
+
const mods = [...useMethodNameMap.keys()];
|
|
401
|
+
(0, traverse_1.default)(srcAst, {
|
|
402
|
+
MemberExpression(path) {
|
|
403
|
+
const objectMethodPath = path.findParent((path) => core_1.types.isObjectMethod(path));
|
|
404
|
+
if (!objectMethodPath) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (!core_1.types.isIdentifier(objectMethodPath.node.key)) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (objectMethodPath.node.key.name !== methodName) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
if (core_1.types.isThisExpression(path.node.object) &&
|
|
414
|
+
core_1.types.isIdentifier(path.node.property)) {
|
|
415
|
+
if (selfMethods.includes(path.node.property.name)) {
|
|
416
|
+
inlineMethods.add(`${entry}#${path.node.property.name}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
if (core_1.types.isIdentifier(path.node.object) &&
|
|
420
|
+
core_1.types.isIdentifier(path.node.property)) {
|
|
421
|
+
const modName = path.node.object.name;
|
|
422
|
+
const methodName = path.node.property.name;
|
|
423
|
+
if (mods.includes(modName) &&
|
|
424
|
+
useMethodNameMap.get(modName).includes(methodName)) {
|
|
425
|
+
inlineMethods.add(`${modName}#${methodName}`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
return [...inlineMethods];
|
|
431
|
+
}
|
|
432
|
+
exports.getInlineMethodsByMethodName = getInlineMethodsByMethodName;
|