dependency-walk
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -1,8 +0,11 @@ | ||
import * as fs from 'node:fs'; | ||
import * as path from 'node:path'; | ||
import { parserCjs } from './parser-cjs'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.walk = void 0; | ||
const fs = require("node:fs"); | ||
const path = require("node:path"); | ||
const parser_cjs_1 = require("./parser-cjs"); | ||
const defaultTransformer = (moduleInfo) => moduleInfo; | ||
const defaultFilter = () => true; | ||
export const walk = (options) => { | ||
const { entry, parser = parserCjs(), transformer = defaultTransformer, filter = defaultFilter, onModule, afterModule, } = options; | ||
const walk = (options) => { | ||
const { entry, parser = (0, parser_cjs_1.parserCjs)(), transformer = defaultTransformer, filter = defaultFilter, onModule, afterModule, } = options; | ||
const moduleCache = new Map(); | ||
@@ -42,5 +45,7 @@ const parsedModule = new Set(); | ||
moduleInfo.dependencies.push(depModule); | ||
if (filter(depModule) && !parsedModule.has(depModule.filePath)) { | ||
traverse(depModule); | ||
// filter is just use to detect whether a module should be parsed | ||
if (filter(depModule) === false) { | ||
parsedModule.add(depModule.filePath); | ||
} | ||
traverse(depModule); | ||
}, | ||
@@ -56,1 +61,2 @@ }); | ||
}; | ||
exports.walk = walk; |
@@ -1,10 +0,13 @@ | ||
import { parse } from 'acorn'; | ||
import { visit, namedTypes } from 'ast-types'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parserCjs = void 0; | ||
const acorn_1 = require("acorn"); | ||
const ast_types_1 = require("ast-types"); | ||
// inspired by | ||
// https://github.com/dependents/node-detective-cjs | ||
// https://github.com/dependents/node-ast-module-types | ||
export const parserCjs = (requireFunctionNames = ['require']) => { | ||
const parserCjs = (requireFunctionNames = ['require']) => { | ||
// ${requireFunctionNames}('xxx') | ||
const isPlainRequire = (node) => { | ||
return (namedTypes.Identifier.check(node.callee) && requireFunctionNames.includes(node.callee.name)); | ||
return (ast_types_1.namedTypes.Identifier.check(node.callee) && requireFunctionNames.includes(node.callee.name)); | ||
}; | ||
@@ -14,9 +17,9 @@ // ${requireFunctionNames}.main.require('xxx') | ||
const { callee } = node; | ||
return (namedTypes.MemberExpression.check(callee) && | ||
namedTypes.MemberExpression.check(callee.object) && | ||
namedTypes.Identifier.check(callee.object.object) && | ||
return (ast_types_1.namedTypes.MemberExpression.check(callee) && | ||
ast_types_1.namedTypes.MemberExpression.check(callee.object) && | ||
ast_types_1.namedTypes.Identifier.check(callee.object.object) && | ||
requireFunctionNames.includes(callee.object.object.name) && | ||
namedTypes.Identifier.check(callee.object.property) && | ||
ast_types_1.namedTypes.Identifier.check(callee.object.property) && | ||
callee.object.property.name === 'main' && | ||
namedTypes.Identifier.check(callee.property) && | ||
ast_types_1.namedTypes.Identifier.check(callee.property) && | ||
callee.property.name === 'require'); | ||
@@ -26,6 +29,6 @@ }; | ||
const arg = node.arguments[0]; | ||
if (namedTypes.Literal.check(arg) || namedTypes.StringLiteral.check(arg)) { | ||
if (ast_types_1.namedTypes.Literal.check(arg) || ast_types_1.namedTypes.StringLiteral.check(arg)) { | ||
return arg.value; | ||
} | ||
if (namedTypes.TemplateLiteral.check(arg)) { | ||
if (ast_types_1.namedTypes.TemplateLiteral.check(arg)) { | ||
return arg.quasis[0].value.raw; | ||
@@ -38,4 +41,4 @@ } | ||
return ({ code, moduleProcessor }) => { | ||
const ast = parse(code, { ecmaVersion: 'latest' }); | ||
visit(ast, { | ||
const ast = (0, acorn_1.parse)(code, { ecmaVersion: 'latest' }); | ||
(0, ast_types_1.visit)(ast, { | ||
visitCallExpression(nodePath) { | ||
@@ -56,1 +59,2 @@ const { node } = nodePath; | ||
}; | ||
exports.parserCjs = parserCjs; |
@@ -1,1 +0,2 @@ | ||
export {}; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -1,8 +0,13 @@ | ||
import * as path from 'node:path'; | ||
import * as assert from 'power-assert'; | ||
import { walk } from './main'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const path = require("node:path"); | ||
const assert = require("power-assert"); | ||
const main_1 = require("./main"); | ||
const parser_cjs_1 = require("./parser-cjs"); | ||
// const __filename = fileURLToPath(import.meta.url); | ||
// const __dirname = path.dirname(__filename); | ||
describe("cjs", function () { | ||
it("should work for entry without dependency", function () { | ||
const entryPath = path.resolve(__dirname, "../test/cjs/a/a2.js"); | ||
const entryModule = walk({ | ||
const entryModule = (0, main_1.walk)({ | ||
entry: entryPath, | ||
@@ -19,3 +24,3 @@ onModule(module) { | ||
const countMap = new Map(); | ||
walk({ | ||
(0, main_1.walk)({ | ||
entry: entryPath, | ||
@@ -30,33 +35,48 @@ onModule(module) { | ||
}); | ||
it("should skip module if filter return false", function () { | ||
it("should skip parse module if filter return false", function () { | ||
const entryPath = path.resolve(__dirname, "../test/cjs/b/index.js"); | ||
walk({ | ||
const parser = (0, parser_cjs_1.parserCjs)(); | ||
const skippedFileName = 'b2a.js'; | ||
let onModuleDetectedSkipped = false; | ||
let afterModuleDetectedSkipped = false; | ||
(0, main_1.walk)({ | ||
entry: entryPath, | ||
filter(moduleInfo) { | ||
return !moduleInfo.filePath.endsWith("b2a.js"); | ||
return !moduleInfo.filePath.endsWith(skippedFileName); | ||
}, | ||
onModule(module) { | ||
assert.ok(!module.filePath.endsWith("b2a.js"), `should skip ${module.filePath}`); | ||
parser(moduleInfo) { | ||
assert.ok(!moduleInfo.filePath.endsWith(skippedFileName), `should skip parse ${moduleInfo.filePath}`); | ||
return parser(moduleInfo); | ||
}, | ||
onModule(moduleInfo) { | ||
if (moduleInfo.filePath.endsWith(skippedFileName)) { | ||
onModuleDetectedSkipped = true; | ||
} | ||
}, | ||
afterModule(moduleInfo) { | ||
if (moduleInfo.filePath.endsWith(skippedFileName)) { | ||
afterModuleDetectedSkipped = true; | ||
} | ||
} | ||
}); | ||
assert.equal(onModuleDetectedSkipped, true, 'skipped module should also processed by onModule'); | ||
assert.equal(afterModuleDetectedSkipped, true, 'skipped module should also processed by afterModule'); | ||
}); | ||
it("should place skipped module in parent's dependencies", function () { | ||
const entryPath = path.resolve(__dirname, "../test/cjs/c/c.js"); | ||
const entryModule = walk({ | ||
const skippedFileName = "cc.js"; | ||
const entryModule = (0, main_1.walk)({ | ||
entry: entryPath, | ||
filter(moduleInfo) { | ||
return !moduleInfo.filePath.endsWith("cc.js"); | ||
return !moduleInfo.filePath.endsWith(skippedFileName); | ||
}, | ||
onModule(module) { | ||
assert.ok(!module.filePath.endsWith("cc.js"), `should skip ${module.filePath}`); | ||
} | ||
}); | ||
assert.ok(entryModule.dependencies.some(dep => dep.filePath.endsWith("cc.js")), 'cc.js is required by c.js'); | ||
assert.ok(entryModule.dependencies.some(dep => dep.filePath.endsWith(skippedFileName)), 'cc.js is required by c.js'); | ||
assert.ok(entryModule.dependencies | ||
.filter(dep => !dep.filePath.endsWith("cc.js")) | ||
.every(dep => dep.dependencies.some(d => d.filePath.endsWith('cc.js'))), 'cc.js is required by cb.js and ca.js'); | ||
.filter(dep => !dep.filePath.endsWith(skippedFileName)) | ||
.every(dep => dep.dependencies.some(d => d.filePath.endsWith(skippedFileName))), 'cc.js is required by cb.js and ca.js'); | ||
}); | ||
it("should transform before parse", function () { | ||
const entryPath = path.resolve(__dirname, "../test/cjs/c/c.js"); | ||
const entryModule = walk({ | ||
const entryModule = (0, main_1.walk)({ | ||
entry: entryPath, | ||
@@ -137,3 +157,3 @@ transformer(moduleInfo) { | ||
]; | ||
const entryModule = walk({ | ||
const entryModule = (0, main_1.walk)({ | ||
entry: entryPath, | ||
@@ -140,0 +160,0 @@ onModule(module) { |
@@ -1,10 +0,12 @@ | ||
import * as path from "node:path"; | ||
import { walk } from "./main"; | ||
import * as assert from "power-assert"; | ||
import { parserCjs } from "./parser-cjs"; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const path = require("node:path"); | ||
const main_1 = require("./main"); | ||
const assert = require("power-assert"); | ||
const parser_cjs_1 = require("./parser-cjs"); | ||
describe("custom", function () { | ||
it("should work for entry without dependency", function () { | ||
const entryPath = path.resolve(__dirname, "../test/customRequire/a/a2.js"); | ||
const entryModule = walk({ | ||
parser: parserCjs(['customRequire', 'require']), | ||
const entryModule = (0, main_1.walk)({ | ||
parser: (0, parser_cjs_1.parserCjs)(['customRequire', 'require']), | ||
entry: entryPath, | ||
@@ -21,4 +23,4 @@ onModule(module) { | ||
const countMap = new Map(); | ||
walk({ | ||
parser: parserCjs(['customRequire', 'require']), | ||
(0, main_1.walk)({ | ||
parser: (0, parser_cjs_1.parserCjs)(['customRequire', 'require']), | ||
entry: entryPath, | ||
@@ -35,4 +37,4 @@ onModule(module) { | ||
const entryPath = path.resolve(__dirname, "../test/customRequire/b/index.js"); | ||
walk({ | ||
parser: parserCjs(['customRequire', 'require']), | ||
(0, main_1.walk)({ | ||
parser: (0, parser_cjs_1.parserCjs)(['customRequire', 'require']), | ||
entry: entryPath, | ||
@@ -49,4 +51,4 @@ filter(moduleInfo) { | ||
const entryPath = path.resolve(__dirname, "../test/customRequire/c/c.js"); | ||
const entryModule = walk({ | ||
parser: parserCjs(['customRequire', 'require']), | ||
const entryModule = (0, main_1.walk)({ | ||
parser: (0, parser_cjs_1.parserCjs)(['customRequire', 'require']), | ||
entry: entryPath, | ||
@@ -67,4 +69,4 @@ filter(moduleInfo) { | ||
const entryPath = path.resolve(__dirname, "../test/customRequire/c/c.js"); | ||
const entryModule = walk({ | ||
parser: parserCjs(['customRequire', 'require']), | ||
const entryModule = (0, main_1.walk)({ | ||
parser: (0, parser_cjs_1.parserCjs)(['customRequire', 'require']), | ||
entry: entryPath, | ||
@@ -145,4 +147,4 @@ transformer(moduleInfo) { | ||
]; | ||
const entryModule = walk({ | ||
parser: parserCjs(['customRequire', 'require']), | ||
const entryModule = (0, main_1.walk)({ | ||
parser: (0, parser_cjs_1.parserCjs)(['customRequire', 'require']), | ||
entry: entryPath, | ||
@@ -149,0 +151,0 @@ onModule(module) { |
{ | ||
"name": "dependency-walk", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "", | ||
"main": "dist/main.js", | ||
"type": "module", | ||
"repository": "https://github.com/shuizhongyueming/dependency-walk.git", | ||
@@ -8,0 +7,0 @@ "scripts": { |
@@ -24,3 +24,3 @@ ## Introduction | ||
- `transformer`: (optional) a custom transformer function for the module info | ||
- `filter`: (optional) a custom filter function to exclude certain modules | ||
- `filter`: (optional) a custom filter function to exclude certain modules from parse | ||
- `onModule`: (optional) a callback function to be called for each module | ||
@@ -27,0 +27,0 @@ - `afterModule`: (optional) a callback function to be called after processing each module |
23330
502
No