@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.
@@ -16,5 +16,12 @@ export declare class MapContext {
16
16
  private init;
17
17
  private writeToLocal;
18
18
  private buildMapContext;
19
+ /**
20
+ * 过滤self的dependencies中无效方法
21
+ */
22
+ private filtering;
23
+ /**
24
+ * 去除dependencies中未使用方法
25
+ */
19
26
  private shaking;
20
27
  }
@@ -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
- const requireMethodNamesByMod = (0, ast_1.getRequireMethodNames)(srcAst, requireModNames);
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
- shaking() {
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
- depNames.forEach((depName) => {
111
- mod.dependencies[depName] = new map_config_1.Dependency(methodNamesByDepName.has(depName)
112
- ? methodNamesByDepName.get(depName)
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
  }
@@ -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
- export {};
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.filter(item => core_1.types.isVariableDeclaration(item)).flatMap(item => item.declarations)
52
- .filter(item => {
53
- if (core_1.types.isCallExpression(item.init) && core_1.types.isIdentifier(item.init.callee)) {
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
- }).forEach(item => {
67
- const args = (item.init.arguments);
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 key = invokeObj.name;
98
- if (!mod.includes(key)) {
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
- path.node.object = core_1.types.thisExpression();
248
- if (core_1.types.isIdentifier(path.node.property)) {
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kezh/my-custom-js-converter",
3
- "version": "0.1.59",
3
+ "version": "0.2.0",
4
4
  "description": "自定义代码转换器",
5
5
  "main": "index.js",
6
6
  "bin": {