Upgrading to v7.4.1
Overview
v7.4.1 is a patch release, and most projects can upgrade without any change. However, it fixes a bug that may report new errors:
- Newly checked dependencies: dependencies written with a template literal, such as
import(`./foo.js`), inside a TypeScript assertion, such asimport("./foo.js" as string), withimport x = require()or with a type import, such astypeof import("./foo.js"), were not checked.
This page explains how to check whether your project is affected, and how to adapt your configuration if it is.
Newly checked dependencies
Before v7.4.1, the plugin checked require() and import() only when their source was a string written directly in the call, such as import("./foo.js"). From v7.4.1, it also checks these dependencies, because their source is known without running the code:
| Code | boundaries/dependency-nodes value | dependency.kind |
|---|---|---|
require(`./foo.js`) | require | value |
require("./foo.js" as string) | require | value |
import foo = require("./foo.js") | require | value |
import type foo = require("./foo.js") | require | type |
import(`./foo.js`) | dynamic-import | value |
import("./foo.js" as string) | dynamic-import | value |
typeof import("./foo.js"), import("./foo.js").Foo | dynamic-import | type |
The TypeScript assertions as, satisfies, <T> and ! are all checked, nested or not, around a string or a template literal without substitutions.
Dependencies whose source is built at runtime are still not checked, such as import(`./${name}.js`), import("./" + "foo.js") or import(path as string).
Who is affected
Your project is affected only if both of these conditions are true:
- Your code has dependencies written in one of the ways of the table above. The TypeScript ones are only checked in the files parsed as TypeScript, for example with
@typescript-eslint/parser. - Your configuration disallows some of them. For example, a
boundaries/dependenciespolicy disallows the element or the file that they import.
After upgrading, the rules may report these dependencies, like they report the same dependencies written with a string. This applies to every rule that checks dependencies, such as boundaries/dependencies or boundaries/no-unknown-dependencies.
Find the affected dependencies
Search your code for these dependencies, for example:
grep -rnE '(require|import)\((\s*[`<]|[^)]*\b(as|satisfies)\b|[^)]*!\))|import\s+(type\s+)?\w+\s*=\s*require\(|typeof import\(|import\([^)]*\)\.' src
The search also lists dependencies that were already checked, such as import("./foo.js").then(), and dependencies that are still not checked, such as template literals with substitutions. It misses the calls split across lines, as Prettier writes the long ones.
To list exactly the affected dependencies, lint your project before and after upgrading, and compare the errors.
Adapt your configuration
Review the new errors after upgrading. They break the same policies as the dependencies written with a string, so:
- Fix the dependency, if it should not exist.
- Allow it with a policy, if it is expected. Policies are processed in order, and the last one that matches wins. For example, to allow the files of the
appcategory to import the files of theforbiddencategory only withimport():
policies: [{from: { file: { categories: "app" } },disallow: { to: { file: { categories: "forbidden" } } },},{from: { file: { categories: "app" } },allow: {to: { file: { categories: "forbidden" } },dependency: { nodeKind: "dynamic-import" },},},]
If you added boundaries/additional-dependency-nodes selectors to check these dependencies, remove them. Otherwise, each dependency is reported twice:
settings: {"boundaries/additional-dependency-nodes": [{selector: "ImportExpression > TSAsExpression > Literal",kind: "value",name: "dynamic-import",},],}