Traverse ECMAScript (JavaScript) files by their `import`/`require` chains
MIT License
(see also licenses for dev. deps.)
Allows traversing ECMAScript (JavaScript) files by their import
/require
chains, building a list of files and optionally executing a callback with
the file name, source and AST.
npm i es-file-traverse
This project is similar to imports-visitor,
but it uses @babel/eslint-parser
so as to report ESTree (ESLint) AST.
One of the motivations behind this library was to allow linting of code from third parties, not for stylistic purposes, but to avoid introducing serious vulnerabilities or globals and other intrusions.
While one can opt to lint node_modules
, this can be a heavy hammer, as:
node_modules
.es-file-traverse
lets you confine yourselfes-file-traverse
can be used with ESLint to target files for linting which
are actually used by your application (not the ESLint behavior of checking
all files in a directory unless ignored, but following imports/require
statements into (and possibly out of) node_modules
to find the files
used by your script(s)). For browser applications, it is recommended you
point es-file-traverse
to your HTML files to ensure the source type
(module or script) is set properly and automatically. For Node applications,
it is recommended you do not set --no-check-package-json
as this
wil allow you to detect source type properly for Node.
For an example, you can see that es-file-traverse
adds its own linting
of third party scripts, using the config .eslintrc-3rdparty.js
. Note that this is a small subset of the rules we use on our
own project, and is instead focused on checking for more serious
vulnerabilities or intrusive practices (e.g., no-eval
or no-global-assign
).
It is recommended that you use suitable ESLint's command-line flags. Here are the flags we are using with a quick summary of why:
--no-inline-config
- 3rd parties may disable rules you wish to check--no-ignore
- Don't apply our own .eslintignore
to the explicit--no-eslintrc
- We don't want to check the normal hierarchy of.eslintrc.*
files, as these are used by our and other projects' for--config
to indicate the rules--config
- Indicates the actual rules we want applied to third party--file
es-file-traverse
.We use the backticks to ensure that the list of files returned by
es-file-traverse
is passed on to eslint
.
eslint --no-inline-config --no-ignore --no-eslintrc --config .eslintrc-3rdparty.js `es-file-traverse --file ./bin/cli.js --node --cjs`
(Note that we actually use node ./bin/cli.js
instead of es-file-traverse
in our script as our own binary file is not available to us, but it is when
installed, so you can use es-file-traverse
with your own scripts.)
eslint-formatter-sourcemaps
In normal linting you typically wish to enforce stylistic checks on your project, so you will mostly want to target source files in such linting.
However, when linting third party code (e.g., to check for security
vulnerabilities or intrusive practices)--a compelling use case of
es-file-traverse
--distribution files are generally preferable as targets,
as they are the final authority on the code of your project that will be
executable (including any embedding or importing/requiring of 3rd party
code, e.g., within node_modules
). (Also note that if using --typescript
mode, es-file-traverse
will, as per the TypeScript module resolution
algorithm, follow .d.ts
declaration files rather than the resulting
.js
files, so if your source is TypeScript, this is another reason you
may not want to trouble parsing source.)
But the default ESLint formatter won't follow sourcemaps to tell you
where the original source file for the problematic code is, so you may, as
needed, report a problem to the third party or avoid its dependency.
You may therefore also wish to use
eslint-formatter-sourcemaps
with your es-file-traverse
-driven eslint
linting process in order to
get the original paths shown for any linting violations.
eslint-formatter-badger
Once we are linting files from our own projects, and particularly when we are linting third party dependencies, we may wish to inform consumers of our project of the degree to which we have looked out for weaknesses, such as by listing the number of rules passing or the types of rules (e.g., for vulnerabilities or intrusive code).
See eslint-formatter-badger
for more on how to do this, in particular the section
"Usage with `es-file-traverse`".
Note that while es-file-traverse
does not currently provide traces of the
routes, you might find --serial
(for consistent ordering) and
--format json
(for easy reading) helpful as when --serial
is applied, you
can at least see the order in which the files were processed, e.g., first
going through one file's imports, then another's, etc.
require
when Node's module.createRequire
module.createRequireFromPath
are used.require
(or define
?) (e.g., passfetch
or XMLHttpRequest
could be used with eval
but thatchild_process.spawn('node_mod_a')
->node_modules/.bin/node_mod_a
->node_modules/node_mod_a/cli/index.js
); could have linting to ensurenode_mod
which could conflictnode_mod_a
, should use fixed paths for child processes.baseUrl
; seeescope
and use for checking function calls/references.--ext
at command line.eslint-plugin-privileges
(and eslint-plugin-query
).eslint-plugin-jsdoc
in getting at defined variableseslint-plugin-jsdoc
to-doeslint-plugin-jsdoc
,/** @type */
and subsituting@typedef
.eslint-plugin-query
to-dosvar
const
/let
; can then use, e.g., forjsdoc/no-undefined-types
; as with no-unrestricted-properties
,window
or other globals are used,