'bazel rules_nodejs can't resolve modules using custom package.json location
Bazel rules_nodejs can't resolve modules using custom package.json location.
Can someone help explain how to fix it?
Ideally I'd like to use a single tsconfig.json
in third_party/npm
instead.
bazel build //demo/node:bin
Gives error:
demo/node/src/lib.ts(1,19): error TS2307: Cannot find module 'chalk' or its corresponding type declarations.
Gist: https://gist.github.com/sbussard/9110d1bdcc784ca0a9303d4393e82f49
Folder structure
(repo root)
↳ WORKSPACE
↳ third_party
↳ npm
↳ package.json
↳ yarn.lock
↳ demo
↳ node
↳ BUILD
↳ tsconfig.json
↳ src
↳ lib.ts
WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "2b2004784358655f334925e7eadc7ba80f701144363df949b3293e1ae7a2fb7b",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.4.0/rules_nodejs-5.4.0.tar.gz"],
)
load("@build_bazel_rules_nodejs//:repositories.bzl", "build_bazel_rules_nodejs_dependencies")
build_bazel_rules_nodejs_dependencies()
load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories", "yarn_install")
node_repositories()
yarn_install(
name = "npm",
package_json = "//third_party/npm:package.json",
yarn_lock = "//third_party/npm:yarn.lock",
)
BUILD
load("@npm//@bazel/typescript:index.bzl", "ts_project")
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
ts_project(
name = "lib",
srcs = glob(["src/*.ts"]),
deps = [
"@npm//@types/chalk",
"@npm//@types/node",
"@npm//chalk",
],
)
nodejs_binary(
name = "bin",
data = [":lib"],
entry_point = "src/lib.js",
)
lib.ts
import chalk from 'chalk';
const { blue, red, green, yellow } = chalk;
const colors = [blue, red, yellow, blue, green, red];
console.log(
'Google'
.split('')
.map((c, i) => colors[i % colors.length](c))
.join('')
);
package.json (inside dependencies)
"@types/chalk": "^2.2.0",
"chalk": "^5.0.1",
tsconfig.json
{
"include": ["src", "types"],
"compilerOptions": {
"module": "es2020",
"target": "esnext",
"moduleResolution": "node",
"baseUrl": "./",
"rootDir": "./",
"paths": {
"src/*": ["src/*"]
},
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"importsNotUsedAsValues": "error"
}
}
Solution 1:[1]
According to Chalk:
IMPORTANT: Chalk 5 is ESM. If you want to use Chalk with TypeScript or a build tool, you will probably want to use Chalk 4 for now. Read more.
There are a few fixes for this issue.
1. Use Chalk 4 (recommended for TypeScript)
The first solution is to use Chalk 4. You will not be missing out on many features by downgrading to Chalk 4.
To do this, you need to first change your versions in package.json
. Change them to this.
{
"dependencies": {
"chalk": "4.1.2"
}
}
Note: TypeScript types (@types/chalk
) aren't required, as Chalk has built-in TypeScript declarations.
After that, you can delete the node_modules
folder to remove all of the packages.
Then, we can run the installation command again to reinstall chalk
, as well as the other packages that you have.
$ npm install
Then, as Chalk 4 doesn't use import
, you need to change your import
to use require()
.
const chalk = require("chalk");
This should correctly install Chalk 4.
2. Change type
to module
The second solution is to change the type
to module
in package.json
. This will allow ESM imports in your files.
{
"type": "module"
}
You do not need to change anything else in your files. However, you can't use CommonJS imports (e.g. require()
) with this set.
3. Use the import()
function
Another solution is to use the import()
function, without adding the type: module
in the package.json
file.
To do this, you first need to make sure that this line of code isn't in your package.json
file.
{
"type": "module"
}
Then, you need to change the import
statement for chalk
to the following.
const chalk = await import("chalk");
This function allows both the CommonJS module setting set, as well as an ESM-like import
statement. You just need to make sure that you are using the LTS version of Node.js, which supports top-level await
.
In conclusion, these solutions should help solve your issue. However, the first solution is recommended for TypeScript.
Solution 2:[2]
TL;DR
1. chalk
package
Run
npm uninstall chalk
and
npm install chalk@"<5"
to down grade the chalk
package.
2. BUILD
file
Remove this line "@npm//@types/chalk",
under ts_project -> deps -> []
1. chalk
package issue
I have faced the same issue with my Webpack setup.
This was a problem caused by TypeScript and chalk
.
From NPM: chalk
:
IMPORTANT: Chalk 5 is ESM. If you want to use Chalk with TypeScript or a build tool, you will probably want to use Chalk 4 for now. Read more.
Following the above warning, we can find that
You are currently using:
"chalk": "^5.0.1",
Please re-install and replace it:
"chalk": "<5",
And here is an example NPM script:
npm uninstall chalk
npm install chalk@"<5"
Currently, the latest version smaller than 5 is v4.1.2
.
2. BUILD
file
Hover on the TS icon
of the chalk
package in NPM: chalk
. It will show the following message:
This package contains built-in TypeScript declarations
Which means it does not need @type/chalk
package. And that's why it caused BUILD file not found in directory '@types/chalk'
error.
So that, go to BUILD
file and delete this line "@npm//@types/chalk",
under ts_project -> deps -> []
new BUILD
file
load("@npm//@bazel/typescript:index.bzl", "ts_project")
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
ts_project(
name = "lib",
srcs = glob(["src/*.ts"]),
deps = [
"@npm//@types/node",
"@npm//chalk",
],
)
nodejs_binary(
name = "bin",
data = [":lib"],
entry_point = "src/lib.js",
)
After the above, you script will works fine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |