Detect global variables in JavaScript using acorn
npx @tessl/cli install tessl/npm-acorn-globals@6.0.0Acorn Globals is a JavaScript library that detects global variables in JavaScript code using the acorn parser. It analyzes JavaScript source code and identifies variables that are referenced but not declared locally, helping developers understand variable scope and detect potential issues with implicit global variable usage.
npm install acorn-globalsconst acornGlobals = require('acorn-globals');For accessing the parse function:
const acornGlobals = require('acorn-globals');
const parse = acornGlobals.parse;const acornGlobals = require('acorn-globals');
// Analyze JavaScript source code
const sourceCode = `
var x = 5;
console.log(y); // y is global
window.alert('test'); // window is global
`;
const globals = acornGlobals(sourceCode);
console.log(globals);
// Output: [
// { name: 'console', nodes: [Array] },
// { name: 'window', nodes: [Array] },
// { name: 'y', nodes: [Array] }
// ]
// Use with pre-parsed AST
const ast = acornGlobals.parse(sourceCode);
const globalsFromAST = acornGlobals(ast);Analyzes JavaScript code to identify variables that are referenced but not declared in the current scope.
/**
* Detect global variables in JavaScript source code or AST
* @param {string|object} source - JavaScript source code as string, or pre-parsed acorn AST object
* @param {object} [options] - Parsing options passed to acorn parser (only used when source is string)
* @returns {Array<GlobalVariable>} Array of global variables found, sorted alphabetically by name
* @throws {TypeError} If source is neither string nor valid AST
*/
function acornGlobals(source, options);
interface GlobalVariable {
/** Variable name (or "this" for ThisExpression) */
name: string;
/** Array of AST nodes where the global is referenced */
nodes: Array<ASTNode>;
}
interface ASTNode {
/** AST node type (e.g., "Identifier", "ThisExpression") */
type: string;
/** Variable name (for Identifier nodes) */
name?: string;
/** Array of parent AST nodes providing context */
parents: Array<object>;
/** Additional acorn AST properties */
[key: string]: any;
}Usage Examples:
const acornGlobals = require('acorn-globals');
// Basic detection
const code = 'var a = b + c;';
const result = acornGlobals(code);
// Result: [{ name: 'b', nodes: [...] }, { name: 'c', nodes: [...] }]
// With parsing options
const es6Code = 'const x = y => z;';
const globals = acornGlobals(es6Code, { ecmaVersion: 2015 });
// Handling complex scoping
const complexCode = `
function outer() {
var local = 1;
inner(); // global
function nested() {
console.log(local); // local to outer
undeclared = 5; // global assignment
}
}
`;
const complexGlobals = acornGlobals(complexCode);
// Finds: console, inner, undeclaredParses JavaScript source code using acorn with relaxed parsing options that allow non-standard JavaScript constructs.
/**
* Parse JavaScript source code using acorn with relaxed settings
* @param {string} source - JavaScript source code to parse
* @param {object} [options] - Parsing options (merged with default relaxed settings)
* @returns {object} Acorn AST object
*/
function parse(source, options);Default Relaxed Options:
allowReturnOutsideFunction: true - Allows return statements outside of functionsallowImportExportEverywhere: true - Allows import/export statements anywhere in the codeallowHashBang: true - Allows hash-bang (#!) directives at the start of filesUsage Example:
const { parse } = require('acorn-globals');
// Parse with relaxed options
const ast = parse(`
#!/usr/bin/env node
return "early exit";
import foo from 'bar';
`);
// Custom parsing options (merged with defaults)
const strictAST = parse('const x = 1;', {
ecmaVersion: 2020,
sourceType: 'module'
});The library performs sophisticated analysis to correctly identify global variables:
var are function-scopedlet/const are block-scopedarguments is automatically available in non-arrow functionsthis references are tracked as globals when not in function scopeundefined identifier is ignored as it's a special language constantconst {a, b} = obj creates local bindings for a and bconst [x, y] = arr creates local bindings for x and yconst {a, ...rest} = obj handles rest/spread syntaxconst {a = 1} = obj supports default assignment patternsconst acornGlobals = require('acorn-globals');
try {
const globals = acornGlobals(invalidInput);
} catch (error) {
if (error instanceof TypeError) {
// Source was neither string nor valid AST
console.log('Invalid input type');
} else {
// Parser error from acorn (syntax errors, etc.)
console.log('Parse error:', error.message);
}
}