Search code examples
typescriptbazel

Using non '.ts' / '.tsx' files in 'ts_library' as dependencies


I'm trying to import a json file from typescript (yes, I'm using the resolveJsonModule flag in my tsconfig). The issue is, I don't know how can I give this json file to ts_library (this is also valid for any other non .ts & .tsx files, like a .env). ts_library is always telling me that he cannot find my json file.

For example if I have this ts_library in a BUILD.bazel:

ts_library(
    name = "src",
    srcs = glob(["*.ts"]),
    deps = [
        "@npm//:node_modules",
    ]
)

with this index.ts:

import test from './test.json';

console.log(test);

and this test.json:

{
  "foo": "bar"
}

it will throw me this:

index.ts:1:18 - error TS2307: Cannot find module './test.json'.

I think I need to somehow add the json file in the deps of my rule. But I don't know how to do it, because deps doesn't accept direct files like //:test.json.


Solution

  • You can add files to the ts_library rule via the data attribute (https://www.npmjs.com/package/@bazel/typescript#data). This is where you can add the reference to the JSON file.

    However, ts_library overrides the output module format, and resolveJsonModule can only be used with commonjs, amd, es2015 or esNext (ts_library overrides it to UMD)

    Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.
    

    You can do this though if you use the typescript compiler directly via Bazel, rather than through ts_library:

    load("@npm//typescript:index.bzl", "tsc")
    
    srcs = glob(["*.ts"])
    deps = ["@npm//@types/node"]
    data = ["test.json"]
    
    tsc(
        name = "src",
        data = srcs + deps + data,
        outs = [s.replace(".ts", ext) for ext in [".js", ".d.ts"] for s in srcs],
        args = [
            "--outDir",
            "$(RULEDIR)",
            "--lib",
            "es2017,dom",
            "--downlevelIteration",
            "--declaration",
            "--resolveJsonModule",
        ] + [
            "$(location %s)" % s
            for s in srcs
        ],
    )
    

    You can test that it works by using nodejs_binary:

    load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
    
    nodejs_binary(
        name = "src_bin",
        data = [
            ":src",
        ] + data,
        entry_point = "//src:index.ts",
    )
    

    More information about this using tsc rather than ts_library here: https://github.com/bazelbuild/rules_nodejs/blob/master/packages/typescript/docs/install.md