Registry / devops / scope-analyzer

scope-analyzer

JSON →
library2.1.2jsnpmunverified

scope-analyzer is a JavaScript library designed for performing basic scope analysis on JavaScript Abstract Syntax Trees (ASTs). It tracks variable scopes and collects references to variables within a given AST, enabling tasks like refactoring, renaming, and understanding variable usage patterns. The current stable version is 2.1.2. The package has seen consistent minor and patch releases, indicating active maintenance, though its stability badge still labels it as "experimental." A key differentiator is its focus on simplicity and direct manipulation of AST nodes, providing methods to crawl the tree, create, delete, and inspect scopes, and retrieve bindings and references. It is particularly useful for tools that need to understand the lexical environment of JavaScript code. It expects AST nodes to have a `.parent` property, often requiring a pre-processing step with utilities like `estree-assign-parent`.

npm install scope-analyzer
INSTALL
IMPORT
SIG · SCOPE-ANALYZER
S
scope-analyzer
devopsjavascriptv2.1.2
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

scan
const scan = require('scope-analyzer')
import scan from 'scope-analyzer'
This library primarily exposes its API via a CommonJS module export. Direct ESM `import` statements are not officially supported or documented and may lead to issues without proper tooling.
crawl
scan.crawl(ast)
crawl(ast)
`crawl` is a method accessed on the default export object, typically assigned to a variable like `scan`.
createScope
scan.createScope(node, bindings)
createScope(node, bindings)
`createScope` is a method for initializing new scopes, often used for global or predefined variables, and is accessed via the default export.
getBinding
scan.getBinding(node, name)
getBinding(node, name)
`getBinding` is a method for retrieving a specific binding by name from a given AST node's scope, accessed via the default export.

This quickstart demonstrates how to parse a JavaScript string into an AST using Acorn, prepare it for `scope-analyzer` (potentially by assigning parent nodes), then define global variables with `createScope` and analyze the AST with `crawl`. It illustrates how to retrieve a specific binding (e.g., `exports`) and iterate over its references, as well as how to find undeclared names within a given scope.

const parse = require('acorn').parse; const scan = require('scope-analyzer'); // Example JavaScript source code const code = ` function greet(name) { const message = 'Hello, ' + name; console.log(message); exports.greeting = message; // Example of an 'exports' reference } greet('World'); var globalVar = 10; `; // Parse the code into an AST. 'acorn' is a common choice. // Ensure to specify ecmaVersion and sourceType for accurate parsing. const ast = parse(code, { ecmaVersion: 2020, sourceType: 'script' }); // IMPORTANT: scope-analyzer expects AST nodes to have a `node.parent` property. // Most parsers (like Acorn) do not add this by default. // Uncomment the following line and install 'estree-assign-parent' if your AST lacks parent pointers: // require('estree-assign-parent')(ast); // Initialize the root scope with common Node.js global variables // This makes 'exports' a known binding for analysis. scan.createScope(ast, ['module', 'exports', '__dirname', '__filename', 'console']); // Crawl the AST to analyze all scopes and collect variable references. scan.crawl(ast); // Example 1: Find all references to the 'exports' binding const exportsBinding = scan.getBinding(ast, 'exports'); if (exportsBinding) { console.log('--- References to "exports" ---'); exportsBinding.getReferences().forEach(function (reference) { // Assuming references like `exports.property = value` if (reference.parent && reference.parent.type === 'MemberExpression' && reference.parent.property) { console.log(`- Exported property: '${reference.parent.property.name}' at line ${reference.loc.start.line}`); } else { console.log(`- General reference at line ${reference.loc.start.line}`); } }); } else { console.log('No binding found for "exports".'); } // Example 2: Find undeclared names in the root scope const rootScope = scan.scope(ast); if (rootScope) { const undeclared = rootScope.getUndeclaredNames(); if (undeclared.length > 0) { console.log('\n--- Undeclared names in root scope ---'); console.log(`- ${undeclared.join(', ')}`); } else { console.log('\nNo undeclared names found in root scope.'); } }
Debug
Known issues
gotchaThe library critically relies on AST nodes having a `.parent` property for correct traversal and scope resolution. Most standard parsers (e.g., Acorn, Esprima) do not automatically provide this, requiring manual preprocessing of the AST.
fix
Before passing your AST to `scope-analyzer`, use a utility like `estree-assign-parent` to add parent references to all nodes. Example: `require('estree-assign-parent')(ast);`
affects: *
breakingVersion 2.1.2 introduced a change making `.parent` and `[kScope]` properties non-enumerable. While this resolves compatibility issues with `recast`, it can lead to a significant performance regression of 20-30% in analysis speed compared to v2.1.1.
fix
If `recast` compatibility is not a concern and performance is critical, consider pinning your dependency to version `2.1.1`. Otherwise, be aware of the potential performance impact when using or upgrading to `>=2.1.2`.
affects: >=2.1.2
gotchaThe package's stability badge labels it as "experimental." This implies that while actively maintained, its API or internal behavior might still undergo changes in future versions, potentially without strict adherence to semantic versioning for minor changes.
fix
Exercise caution when relying on specific internal implementations or undocumented features. Regularly review release notes for updates and potential breaking changes, even in minor versions.
affects: *
breakingAs of version 2.0.0, `scan.getBinding()` will now return a `Binding` object even for undeclared identifiers. In such cases, the `binding.definition` property will be `undefined`.
fix
When using `scan.getBinding()`, always check `binding.definition` if you need to distinguish between formally declared variables and implicitly used (undeclared) identifiers.
affects: >=2.0.0
gotchaThis library is published as a CommonJS module and does not officially support or document direct ES Module (`import`) syntax. Attempting to import it directly in an ESM context might result in errors or unexpected behavior depending on your bundler or Node.js version.
fix
In ES Module projects, use dynamic `import()` (e.g., `const scan = await import('scope-analyzer');`) or ensure your build tooling correctly transpiles CommonJS `require` statements if you are using static `import` syntax.
affects: *
Errors
Common errors & fixes
TypeError: Cannot read property 'parent' of undefined
The AST nodes passed to `scope-analyzer` do not have a `.parent` property, which is required for its internal traversal logic.
fix
Preprocess your AST using a utility like `estree-assign-parent` to add the `.parent` property to all nodes. Example: `require('estree-assign-parent')(ast);`
ReferenceError: require is not defined
You are attempting to use the CommonJS `require` function in an ES Module environment (e.g., a `.mjs` file or a project with `"type": "module"` in `package.json`).
fix
If in an ESM context, consider using dynamic `import()` (`const scan = await import('scope-analyzer');`) or configure your bundler/Node.js environment to properly handle CommonJS modules.
TypeError: scan.crawl is not a function
The `scope-analyzer` module was imported incorrectly, preventing the `scan` variable from holding the expected object with its API methods. This often happens with incorrect destructuring or ES Module imports.
fix
Ensure you are using the correct CommonJS import: `const scan = require('scope-analyzer');`. Avoid named imports (`import { crawl } from 'scope-analyzer';`) as the package exports a single object.
Upgrade
Version history
2.1.2latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
2 hits · last 30 days
node
2
Resources