Skip to content

feat(js): generate types attribute on js_library package targets#208

Open
rdark wants to merge 1 commit intoaspect-build:mainfrom
cogna-public:feat/js-library-types-attribute-upstream
Open

feat(js): generate types attribute on js_library package targets#208
rdark wants to merge 1 commit intoaspect-build:mainfrom
cogna-public:feat/js-library-types-attribute-upstream

Conversation

@rdark
Copy link

@rdark rdark commented Mar 10, 2026

Summary

When js_library is used as a package target (via js_package_rule_kind directive), gazelle now generates a types attribute containing TypeScript source files (.ts, .cts, .mts, .tsx, .jsx) from the associated ts_project rule.

The types attribute propagates TypeScript source files through JsInfo.transitive_types, enabling downstream ts_project targets to type-check correctly in Bazel's sandbox without manual # keep comments on the types attribute.

Changes

  • language/js/kinds.go: Added "types": true to JsLibraryKind.MergeableAttrs so gazelle manages the attribute during merge
  • language/js/generate.go:
    • Pass the source rule.Rule to addPackageRule so it can inspect ts_project_info
    • Extract TypeScript source files from TsProjectInfo.sources and set as types on js_library package targets
  • Updated 6 test BUILD.out files to include expected types attribute

Behavior

  • Only applies when packageTargetKind == JsLibraryKind (not npm_package)
  • Only generates types when there is an associated source rule with TypeScript files
  • Pure JS packages (no srcRule) are unaffected
  • Follows the same file-list approach as srcs on ts_project

Motivation

In monorepos using js_library as the package target, the types attribute must be manually maintained with # keep comments since gazelle doesn't generate it. This is error-prone and creates maintenance burden.

@CLAassistant
Copy link

CLAassistant commented Mar 10, 2026

CLA assistant check
All committers have signed the CLA.

@aspect-workflows
Copy link

aspect-workflows bot commented Mar 10, 2026

Test

All tests were cache hits

4 tests (100.0%) were fully cached saving 321ms.


Test

language/js

118 test targets passed

Targets
//tests:bad_build_test [k8-fastbuild]68ms
//tests:bad_package_json_test [k8-fastbuild]165ms
//tests:bad_ts_syntax_test [k8-fastbuild]183ms
//tests:declare_module_test [k8-fastbuild]203ms
//tests:declare_module_types_test [k8-fastbuild]191ms
//tests:dynamic_import_test [k8-fastbuild]174ms
//tests:gazelle_disable_conflict_test [k8-fastbuild]92ms
//tests:gazelle_disable_test [k8-fastbuild]165ms
//tests:gazelle_exclude_directive_test [k8-fastbuild]204ms
//tests:gazelle_generate_build_test [k8-fastbuild]238ms
//tests:gazelle_generation_mode_legacy_test [k8-fastbuild]53ms
//tests:gazelle_ignore_directive_test [k8-fastbuild]189ms
//tests:gazelle_keep_test [k8-fastbuild]228ms
//tests:gazelle_map_kind_directive_test [k8-fastbuild]187ms
//tests:groups_add_remove_rules_test [k8-fastbuild]103ms
//tests:groups_configs_test [k8-fastbuild]120ms
//tests:groups_deps_test [k8-fastbuild]180ms
//tests:groups_simple_files_test [k8-fastbuild]183ms
//tests:ignore_config_files_test [k8-fastbuild]296ms
//tests:ignore_import_directive_test [k8-fastbuild]225ms
//tests:incremental_lazy_lockdir_test [k8-fastbuild]276ms
//tests:incremental_lazy_test [k8-fastbuild]232ms
//tests:node_native_test [k8-fastbuild]188ms
//tests:npm_changed_deps_test [k8-fastbuild]216ms
//tests:npm_link_all_packages_test [k8-fastbuild]78ms
//tests:npm_package_deps_lib_test [k8-fastbuild]244ms
//tests:npm_package_deps_test [k8-fastbuild]300ms
//tests:npm_package_deps_tsconfig_test [k8-fastbuild]195ms
//tests:npm_package_lib_target_name_test [k8-fastbuild]204ms
//tests:npm_package_target_enabled_test [k8-fastbuild]187ms
//tests:npm_package_target_name_test [k8-fastbuild]130ms
//tests:npm_package_target_referenced_test [k8-fastbuild]150ms
//tests:npm_simple_deps_test [k8-fastbuild]205ms
//tests:npm_types_package_test [k8-fastbuild]233ms
//tests:parse_errors_test [k8-fastbuild]205ms
//tests:pnpm_project_refs_lock5_test [k8-fastbuild]229ms
//tests:pnpm_project_refs_lock6_test [k8-fastbuild]185ms
//tests:pnpm_project_refs_lock9_test [k8-fastbuild]160ms
//tests:pnpm_workspace-incremental_test [k8-fastbuild]192ms
//tests:pnpm_workspace_rerooted_subdir_test [k8-fastbuild]147ms
//tests:pnpm_workspace_rerooted_test [k8-fastbuild]251ms
//tests:pnpm_workspace_test [k8-fastbuild]229ms
//tests:resolve_directive_test [k8-fastbuild]215ms
//tests:resolve_order_test [k8-fastbuild]223ms
//tests:rules_conflicting_name_mapped_kind_test [k8-fastbuild]112ms
//tests:rules_conflicting_name_nojs_test [k8-fastbuild]82ms
//tests:rules_conflicting_name_test [k8-fastbuild]84ms
//tests:rules_ordering_test [k8-fastbuild]204ms
//tests:simple_dts_only_test [k8-fastbuild]190ms
//tests:simple_empty_test [k8-fastbuild]99ms
//tests:simple_extra_files_test [k8-fastbuild]179ms
//tests:simple_file_exts_test [k8-fastbuild]329ms
//tests:simple_globs_keep_test [k8-fastbuild]189ms
//tests:simple_globs_test [k8-fastbuild]227ms
//tests:simple_import_disabled_test [k8-fastbuild]233ms
//tests:simple_imports_cjs_test [k8-fastbuild]219ms
//tests:simple_imports_dynamic_test [k8-fastbuild]219ms
//tests:simple_imports_test [k8-fastbuild]380ms
//tests:simple_json_import_test [k8-fastbuild]266ms
//tests:simple_module_test [k8-fastbuild]175ms
//tests:simple_new_file_test [k8-fastbuild]229ms
//tests:source_no_target_err_test [k8-fastbuild]103ms
//tests:tests_initial_test [k8-fastbuild]221ms
//tests:tests_new_test [k8-fastbuild]198ms
//tests:tests_nolib_test [k8-fastbuild]193ms
//tests:tests_simple_test [k8-fastbuild]105ms
//tests:tests_subdir_test [k8-fastbuild]188ms
//tests:ts_proto_library_deps_test [k8-fastbuild]107ms
//tests:ts_proto_library_error_test [k8-fastbuild]96ms
//tests:ts_proto_library_ignore_test [k8-fastbuild]65ms
//tests:ts_proto_library_imported_test [k8-fastbuild]210ms
//tests:ts_proto_library_test [k8-fastbuild]217ms
//tests:tsconfig_composite_test [k8-fastbuild]204ms
//tests:tsconfig_custom_file_name_test [k8-fastbuild]291ms
//tests:tsconfig_declaration_dir_test [k8-fastbuild]198ms
//tests:tsconfig_disabled_manual_test [k8-fastbuild]99ms
//tests:tsconfig_emit_declaration_only_test [k8-fastbuild]227ms
//tests:tsconfig_incremental_test [k8-fastbuild]134ms
//tests:tsconfig_invalid_test [k8-fastbuild]215ms
//tests:tsconfig_manual_test [k8-fastbuild]193ms
//tests:tsconfig_nomore_configs_test [k8-fastbuild]157ms
//tests:tsconfig_optout_test [k8-fastbuild]265ms
//tests:tsconfig_outdir_genfiles_test [k8-fastbuild]202ms
//tests:tsconfig_outdir_test [k8-fastbuild]173ms
//tests:tsconfig_paths_test [k8-fastbuild]288ms
//tests:tsconfig_pnpm_ref-incremental_test [k8-fastbuild]100ms
//tests:tsconfig_pnpm_ref_rerooted_test [k8-fastbuild]87ms
//tests:tsconfig_pnpm_ref_test [k8-fastbuild]103ms
//tests:tsconfig_rootdir_test [k8-fastbuild]157ms
//tests:tsconfig_rootdirs_test [k8-fastbuild]218ms
//tests:tsconfig_tsbuildinfo_configdir_test [k8-fastbuild]176ms
//tests:tsconfig_tslib_test [k8-fastbuild]181ms
//tests:tsx_css_not-found_test [k8-fastbuild]198ms
//tests:tsx_css_opt-out_test [k8-fastbuild]258ms
//tests:tsx_css_outdir_test [k8-fastbuild]204ms
//tests:tsx_css_test [k8-fastbuild]261ms
//tests:validate_import_statements_off_test [k8-fastbuild]231ms
//tests:validate_import_statements_test [k8-fastbuild]104ms
//tests:validate_import_statements_warn_test [k8-fastbuild]203ms
//tests:visibility_test [k8-fastbuild]237ms
+ 18 other targets

Total test execution time was 22s. 6 tests (4.8%) were fully cached saving 937ms.


Test

language/kotlin

All tests were cache hits

19 tests (100.0%) were fully cached saving 5s.


Test

language/orion

All tests were cache hits

52 tests (100.0%) were fully cached saving 9s.


Test

runner

14 test targets passed

Targets
//pkg/git/tests:ignore_config_files_test [k8-fastbuild]241ms
//tests:bad_build_test [k8-fastbuild]271ms
//tests:branded-directives_test [k8-fastbuild]357ms
//tests:buf_test [k8-fastbuild]266ms
//tests:cc_test [k8-fastbuild]337ms
//tests:crossresolve-js_test [k8-fastbuild]201ms
//tests:crossresolve-pnpm-names-lazy_test [k8-fastbuild]449ms
//tests:crossresolve-pnpm-names_test [k8-fastbuild]385ms
//tests:crossresolve-pnpm_test [k8-fastbuild]313ms
//tests:golang_test [k8-fastbuild]249ms
//tests:imports-missing_test [k8-fastbuild]318ms
//tests:js_binary-main_test [k8-fastbuild]294ms
//tests:npm_bin_wrapper_test [k8-fastbuild]421ms
//tests:python-simple_test_test [k8-fastbuild]276ms

Total test execution time was 4s. 16 tests (53.3%) were fully cached saving 1s.


Test

runner/e2e/bin

All tests were cache hits

1 test (100.0%) was fully cached saving 93ms.


Buildifier      Gazelle      Gazelle [language/js]      Gazelle [language/kotlin]      Gazelle [language/orion]      Gazelle [runner]      Gazelle [runner/e2e/bin]

When a js_library package target wraps a ts_project source rule
that contains TypeScript source files (.ts, .tsx, etc.), generate
a `types` attribute listing those files. This ensures TypeScript
sources propagate through JsInfo.transitive_types so downstream
ts_project targets can type-check in Bazel's sandbox without
manual `# keep` annotations.

Only js_library (not npm_package) package targets receive the
types attribute, and only when the associated source rule has
transpilable TypeScript files.

- Use isTranspiledSourceFileType (not isTranspiledSourceFileExt)
  to exclude .d.ts declaration files from types
- Incremental test (pnpm_workspace-incremental) only targets app/
  dir, so lib/c/BUILD.out must match BUILD.in (no types)
- Add types expectation to runner/tests/crossresolve-pnpm-names
@rdark rdark force-pushed the feat/js-library-types-attribute-upstream branch from 5c1ccee to ae45b19 Compare March 10, 2026 13:28
@jbedard
Copy link
Member

jbedard commented Mar 12, 2026

I don't think we'd want this when the types are already in the js_library(deps)? For example most of the changed tests in the PR probably shouldn't have any changes.

Shouldn't this also only include .d.ts files and not .ts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants