no-unpublished-require
UnreleasedConfiguration
Disallow requiring unpublished files and development dependencies from published files.
Rule details
The rule checks require() and require.resolve(), including aliases,
destructured methods, optional calls, and constant arguments. It uses the
nearest valid package.json, its files list, and applicable .npmignore or
.gitignore files to decide which files are published. Unpublished source
files and, by default, private packages are skipped.
In a published file, a call is reported if its target is outside the package
or excluded from publication, or its package is listed only in
devDependencies. Packages also listed in dependencies, peerDependencies,
or optionalDependencies are accepted. Development dependencies need not be
installed to be reported. Workspace ancestors do not supply production
dependencies for this check.
For a package with files: ['lib'] and devDependencies: { dev: '*' }, these
calls in lib/index.js are incorrect:
These calls are correct when lib/helper.js exists:
CommonJS resolution checks directory entries and package main fields, with
the node and require export conditions. Local bindings that shadow
require and dynamic arguments such as require(packageName) are ignored.
Ordinary imports and TypeScript import value = require('package')
declarations are outside this rule. There are no fixes or suggestions.
Use node/no-missing-require to check missing targets and
node/no-extraneous-require to check undeclared packages.
Options
allowModulesaccepts package roots, including scoped andvirtual:names. Allowingdevalso allowsdev/subpath. It does not exempt local files.ignorePrivatedefaults totrue. Set it tofalseto check packages withprivate: true, for example before deployment.convertPathmaps both the requiring file and local targets from source paths to published paths, relative to the package directory. It accepts an object such as{ 'src/**': ['^src/(.*)\\.ts$', 'lib/$1.js'] }, or an ordered array of{ include, exclude?, replace }entries. The first matching entry wins. Omit this option instead of usingnull, which the upstream schema also rejects.resolvePathssupplies extra resolution base directories before the requiring file's directory. Relative values use the working directory orsettings.cwdwhen configured.tryExtensionsdefaults to['.js', '.json', '.node', '.mjs', '.cjs']. An empty array disables extension guessing.resolverConfigsupportsmodules,alias,fallback,fullySpecified,extensions,extensionAlias,conditionNames,mainFields,mainFiles, andaliasFields, as described for no-missing-require.
Except for ignorePrivate, these options can also be supplied through
settings.node. Rule options take precedence; legacy settings.n takes
precedence over settings.node. Explicit empty lists override shared lists.
TypeScript extension mappings and path aliases affect local target resolution.
A package alias does not exempt a development dependency.
Differences from upstream
Compared with eslint-plugin-n v18.3.0:
- Subdirectory ignore files affect publication; upstream only uses the package root's ignore file.
README.jsis treated as published even withfiles: []. Included files such aslib/..hidden.jsare also treated as published.- On case-insensitive filesystems,
mainmatches filenames regardless of case; upstream can skip checking those files. - In
files,[!b]excludesb,\*matches a literal*, and whitespace is significant. Upstream may select different files for these patterns. - Overlapping object-form
convertPath,resolverConfig.alias, andresolverConfig.fallbackentries use alphabetical priority instead of declaration order. Use arrays to set priority. - Absolute
convertPathreplacements stay absolute; targets outside the package are reported. - An invalid
convertPathregex in shared settings skips the check instead of failing lint. resolverConfigoptions not listed above, includingsymlinks, are not supported.