watch-dependency-graph
Advanced tools
Comparing version 2.1.1 to 2.2.0-beta.1
100
index.js
@@ -6,5 +6,4 @@ const fs = require('fs') | ||
const filewatcher = require('filewatcher') | ||
const acorn = require('acorn-loose') | ||
const walker = require('acorn-walk') | ||
const { transformSync } = require('@babel/core') | ||
const parser = require('@babel/parser') | ||
const traverse = require('@babel/traverse').default | ||
@@ -171,32 +170,80 @@ function emitter () { | ||
const raw = fs.readFileSync(id, 'utf-8') | ||
const { code } = transformSync(raw, { | ||
filename: id, | ||
presets: [require.resolve('@babel/preset-env')] | ||
const ast = parser.parse(raw, { | ||
sourceType: 'module', | ||
plugins: ['jsx', 'typescript', 'dynamicImport'] | ||
}) | ||
const ast = acorn.parse(code, { | ||
ecmaVersion: 2015, | ||
sourceType: 'module' | ||
const nextIds = [] | ||
traverse(ast, { | ||
enter (path) { | ||
if (path.node.type === 'CallExpression') { | ||
const callee = path.get('callee') | ||
const isDynamicImport = callee.isImport() | ||
if (callee.isIdentifier({ name: 'require' }) || isDynamicImport) { | ||
const arg = path.node.arguments[0] | ||
if (arg.type === 'StringLiteral') { | ||
nextIds.push(arg.value) | ||
} else { | ||
nextIds.push(src.slice(arg.start, arg.end)) | ||
} | ||
} | ||
} else if ( | ||
path.node.type === 'ImportDeclaration' || | ||
path.node.type === 'ExportNamedDeclaration' || | ||
path.node.type === 'ExportAllDeclaration' | ||
) { | ||
const { source } = path.node | ||
if (source && source.value) { | ||
nextIds.push(source.value) | ||
} | ||
} | ||
} | ||
}) | ||
for (const node of ast.body) { | ||
// get deps of current file | ||
const nextIds = getFileIdsFromAstNode(node, { | ||
parentFileId: id, | ||
const resolvedNextIds = nextIds | ||
.map(moduleId => { | ||
const req = createRequire(id) | ||
let resolved | ||
try { | ||
resolved = req.resolve(moduleId) | ||
} catch (e1) { | ||
try { | ||
resolved = req.resolve(resolveAliases(moduleId, alias)) | ||
} catch (e2) { | ||
try { | ||
resolved = require.resolve(moduleId) | ||
} catch (e3) { | ||
if (e1) { | ||
throw e1 | ||
} | ||
if (e2) { | ||
throw e2 | ||
} | ||
if (e3) { | ||
throw e3 | ||
} | ||
} | ||
} | ||
} | ||
// same same, must be built-in module | ||
return resolved === moduleId ? undefined : resolved | ||
}) | ||
.filter(Boolean) | ||
// walk each dep | ||
for (const _id of resolvedNextIds) { | ||
walk(_id, { | ||
ids, | ||
tree, | ||
entryPointer, | ||
parentPointer: pointer, | ||
visitedLeaf, | ||
events, | ||
alias | ||
}) | ||
// walk each dep | ||
for (const _id of nextIds) { | ||
walk(_id, { | ||
ids, | ||
tree, | ||
entryPointer, | ||
parentPointer: pointer, | ||
visitedLeaf, | ||
events, | ||
alias | ||
}) | ||
} | ||
} | ||
} catch (e) { | ||
debug('walk error', e) | ||
// on syntax errors, just watch file and exit walk | ||
@@ -287,2 +334,3 @@ if (e instanceof SyntaxError) return | ||
debug('diff', { addedIds, removedIds }) | ||
debug('tree', tree) | ||
@@ -289,0 +337,0 @@ for (const id of addedIds) { |
{ | ||
"name": "watch-dependency-graph", | ||
"version": "2.1.1", | ||
"version": "2.2.0-beta.1", | ||
"description": "", | ||
@@ -35,7 +35,6 @@ "main": "index.js", | ||
"dependencies": { | ||
"@babel/core": "^7.12.10", | ||
"@babel/parser": "^7.13.15", | ||
"@babel/preset-env": "^7.12.11", | ||
"@babel/traverse": "^7.13.15", | ||
"acorn-jsx": "^5.3.1", | ||
"acorn-loose": "^8.0.1", | ||
"acorn-walk": "^8.0.1", | ||
"debug": "^4.2.0", | ||
@@ -42,0 +41,0 @@ "filewatcher": "^3.0.1" |
@@ -846,2 +846,61 @@ const fs = require('fs-extra') | ||
test('all', async () => { | ||
const files = { | ||
a: { | ||
url: './all/a.js', | ||
content: ` | ||
import * as a_b from './a_b.js' | ||
import { a_c } from './a_c.js' | ||
const a_d = require('./a_d.js') | ||
let lazy = null | ||
if (true) lazy = import('./a_e.js') | ||
export default '' | ||
` | ||
}, | ||
a_b: { | ||
url: './all/a_b.js', | ||
content: ` | ||
export const a_b = () => {} | ||
` | ||
}, | ||
a_c: { | ||
url: './all/a_c.js', | ||
content: ` | ||
export const a_c = () => {} | ||
` | ||
}, | ||
a_d: { | ||
url: './all/a_d.js', | ||
content: ` | ||
module.exports = { a_d() {} } | ||
` | ||
}, | ||
a_e: { | ||
url: './all/a_e.js', | ||
content: ` | ||
export const a_e = () => {} | ||
` | ||
} | ||
} | ||
const fsx = fixtures.create(files) | ||
const w = graph({ cwd: fixtures.getRoot() }) | ||
w.add([fsx.files.a]) | ||
await wait(DELAY) | ||
const tree = w.tree | ||
assert(!!tree[fsx.files.a_b]) | ||
assert(!!tree[fsx.files.a_c]) | ||
assert(!!tree[fsx.files.a_d]) | ||
assert(!!tree[fsx.files.a_e]) | ||
w.close() | ||
fsx.cleanup() | ||
}) | ||
!(async function () { | ||
@@ -848,0 +907,0 @@ console.time('test') |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
244181
6
17
6484
1
1
6
1
+ Added@babel/parser@^7.13.15
+ Added@babel/traverse@^7.13.15
- Removed@babel/core@^7.12.10
- Removedacorn-loose@^8.0.1
- Removedacorn-walk@^8.0.1
- Removedacorn-loose@8.4.0(transitive)
- Removedacorn-walk@8.3.4(transitive)