aspect-build / aspect-build/rules_js

[FR]: Standardized support for non-relative import paths of libraries

Open
#706 23 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Starlark
Stars
378
Forks
183
Avg merge
1d 11h
Merged PRs (30d)
29

Description

### What is the current behavior?

As far as I know, JavaScript doesn't standardize a way to associate a fully qualified import path with a module. (Unlike Go and Java.) However, having a canonical, non-relative import path for libraries is useful, and JS-related tools find a way to support this.

Different tools (node, TypeScript, browsers?) seem to have different ways of being configured to handle "absolute" imports. For example, `tsconfig.json` has a [`paths`](https://www.typescriptlang.org/tsconfig#paths) option that can be used. esbuild I believe supports the `tsconfig.json` paths.

It is currently up to the rules_js user to manipulate the configuration objects passed to bazel-run tools (esbuild, tsc, node, ...) and the IDE such that global imports work correctly.

### Describe the feature

Should associating an absolute import path with a module or set of modules be given some sort of standardized support by rules_js?

I'm looking for something like rules_go's [import_path](https://github.com/bazelbuild/rules_go/blob/master/docs/go/core/rules.md#go_library-importpath) arg. I want to have a TypeScript file in a project called "lib.ts" (with corresponding js file "lib.js"). I would like to import "lib.js" using an import path of my choosing, such as `"@proj/foo/lib"`. `@proj/foo` may have no relationship to my workspace name.

My actual use case is so I can generate protobuf code that is imported like `import {Timestamp} from "@protos/google/type/timetamp_pb.js"` using a build rule like

```starlark
ts_proto_library(
name = "timestamp",
proto = "@com_google_protobuf//:timestamp_proto",
import_path = "@protos/google/type/timestamp_pb",
)
```

`ts_proto_library` would be either a rule or a macro. One of the outputs of the rule would be something that keeps track of this global "@protos/google/type/timestamp_pb" module name and its association with some generated JS/TS files. When tools are called, they would be made aware of the import mappings within all transitive dependencies.

I'm not sure the recommended way to do this is, if it is not recommended, or what. Perhaps there is a way to do this using [`npm_package`](https://docs.aspect.build/aspect-build/rules_js/v1.0.0-beta.0/docs/npm_package-docgen.html).

### Fund our work

- [ ] Sponsor our open source work by donating a [feature bounty](https://opencollective.com/aspect-build/)

Contributor guide

Open the contributing guide

Research direction

Start with the tsconfig.json paths option, the npm_package documentation, and the proposed ts_proto_library shape. Clarify how an import_path such as @protos/google/type/timestamp_pb would be recorded and propagated through transitive dependencies, and define done as consistent support for the relevant tools and IDE configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
build-system, developer-experience, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.