1

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"
  }
}
Stephen
  • 7,994
  • 9
  • 44
  • 73
  • Could you please provide more details on `package.json`? – Edwin Apr 28 '22 at 05:14
  • It's just an "all in one" file to hold all dependencies for all projects. It hasn't been cleaned up at all at this point. https://gist.github.com/sbussard/6d28031130c9fdeceda75edefc9c2e32 – Stephen Apr 28 '22 at 05:54
  • Thanks. Can you try add this line into your `package.json` as see does it works? `"type": "module",` – Edwin Apr 28 '22 at 06:24
  • Yep. Doesn't work. Bazel is hard – Stephen Apr 29 '22 at 06:29

3 Answers3

1

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.

Edwin
  • 395
  • 2
  • 12
  • Thanks you for your participation. Unfortunately it provides this error: `BUILD file not found in directory '@types/chalk'` – Stephen Apr 29 '22 at 02:17
  • After reinstalling chalk and @types/chalk it gives this error `error TS2307: Cannot find module 'chalk' or its corresponding type declarations.` – Stephen Apr 29 '22 at 02:25
  • I have updated the answer. Thank you for your further information. Feel free to let me know when you have any more issue. ;) – Edwin Apr 29 '22 at 05:10
  • It still fails with the same error. I think it might be a tsconfig issue. Ideally there would be one tsconfig file for the whole repo, ideally in the third_party/npm folder. Thanks for continuing to look into this! – Stephen Apr 29 '22 at 06:32
  • I just trying to share my experience. IC, I also came up with this when I setting up the `webpack` with `typescript`. Try to change `"module": "CommonJS",`. I guess it could help and if so I will update my answer. – Edwin Apr 29 '22 at 06:42
  • A little more thing, if `"module": "CommonJS",` still does not work. Would you mind to share your setup or a [`reprex`](https://stackoverflow.com/help/minimal-reproducible-example) on something like github please? That would be easier for debugging. – Edwin Apr 29 '22 at 12:21
  • IIRC Bazel doesn't have an online equivalent to codesandbox.io, so this is the best I can do https://gist.github.com/sbussard/9110d1bdcc784ca0a9303d4393e82f49 – Stephen Apr 30 '22 at 02:12
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.

Arnav Thorat
  • 3,078
  • 3
  • 8
  • 33
1

I faced the same kind of error when package.json wasn't at the root of the folder.

Setting package_path = "/" in yarn_install fixed the problem.

piarston
  • 1,685
  • 1
  • 13
  • 25