Skip to main content
Version: 7.4.1

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 as import("./foo.js" as string), with import x = require() or with a type import, such as typeof 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:

Codeboundaries/dependency-nodes valuedependency.kind
require(`./foo.js`)requirevalue
require("./foo.js" as string)requirevalue
import foo = require("./foo.js")requirevalue
import type foo = require("./foo.js")requiretype
import(`./foo.js`)dynamic-importvalue
import("./foo.js" as string)dynamic-importvalue
typeof import("./foo.js"), import("./foo.js").Foodynamic-importtype

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/dependencies policy 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 app category to import the files of the forbidden category only with import():
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",
},
],
}