Skip to content

Build file generation is provided as a plugin for gazelle

License

Notifications You must be signed in to change notification settings

benchsci/rules_nodejs_gazelle

Repository files navigation

Javascript & Typescript language support for Gazelle

Bazel Gazelle rule that generates BUILD file content for javascript/typescript code.

Setup

Example setup

examples/nextjs contains an end-to-end working example of BUILD file generation for an example next.js project. It may be helpful to reference when configuring your project

Gazelle

To use this extension in a project, you'll need to add Gazelle and its dependencies to your WORKSPACE file. Follow the instructions at https://github.com/bazelbuild/bazel-gazelle#running-gazelle-with-bazel

rules_js

Many of the rules generated by this extension also depend on rules_js, instructions for installing rules_js can be found at https://github.com/aspect-build/rules_js

Repository rule

Then add this repository to your WORKSPACE file:

http_archive(
    name = "com_github_benchsci_rules_nodejs_gazelle",
    sha256 = "c3734c1d4f18f58c74e1efb1ab83dd2bed84d0de2e0b26c8c0fcb649bdbb75a1",
    strip_prefix = "rules_nodejs_gazelle-0.5.0",
    urls = [
        "https://github.com/benchsci/rules_nodejs_gazelle/archive/refs/tags/v0.5.0.tar.gz",
    ],
)

Gazelle rule

Once you have set up a gazelle rule by following the installation instructions in Gazelle, you can add this extension as a language.

It should look something like this:

load("@bazel_gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle", "gazelle_binary")

gazelle(
    name = "gazelle",
    gazelle = ":gazelle_js",
)

gazelle_binary(
    name = "gazelle_js",
    languages = DEFAULT_LANGUAGES + [
        "@com_github_benchsci_rules_nodejs_gazelle//gazelle",
    ],
)

NPM setup

If you are using NPM for your project, you will probably want to add at least these directives (more on directives below) to your root BUILD file as well:

# gazelle:exclude **/node_modules
# gazelle:exclude tsconfig.json

# gazelle:js_package_file package.json :node_modules
# gazelle:js_web_asset .json,.css,.scss
# gazelle:js_collect_all_assets
# gazelle:js_root

Custom rule or macro implementations

If you have custom implementations of the rules generated by this extension, you may wish to re-map them with the map_kind directive:

# gazelle:map_kind js_library js_library @build_bazel_rules_nodejs
# gazelle:map_kind ts_project ts_project @my_local_repo

Directives

Gazelle can be configured with directives, which are written as top-level comments in build files.

Directive comments have the form # gazelle:key value. More information here

Directives apply in the directory where they are set and in subdirectories. This means, for example, if you set # gazelle:prefix in the build file in your project's root directory, it affects your whole project. If you set it in a subdirectory, it only affects rules in that subtree.

Example of most of these directives can be found in tests

The following directives are recognized by this plugin:

Directive Default value
# gazelle:js_extension enabled

Controls whether the JS extension is enabled or not. Sub-packages inherit this value. Can be either "enabled" or "disabled".

# gazelle:js_default_npm_label //:node_modules

Defines the label prefix for third npm dependencies. //:node_modules/ is default for Aspect's rules_js, @npm// is default for rules_nodejs

# gazelle:js_lookup_types true|false true

Causes Gazelle to try and find a matching "@types/pkg" dependency for each "pkg" dependency, including @types/node for Node.js builtins

# gazelle:js_package_file package.json :node_modules //:node_modules

Instructs Gazelle to use a package.json file to lookup imports from dependencies and devDependencies

# gazelle:js_import_alias some_folder other none

Specifies partial string substitutions applied to imports before resolving them. Eg. # gazelle:js_import_alias foo bar means that import "foo/module" will resolve to the package bar/module. This directive can be used several times.

# gazelle:js_visibility label none

By default, internal packages are only visible to its siblings. This directive adds a label internal packages should be visible to additionally. This directive can be used several times, adding a list of labels.

# gazelle:js_root workspace root

Specifies the current package (folder) as a JS root. Imports for JS and TS consider this folder the root level for relative and absolute imports. This is used on monorepos with multiple Python projects that don't share the top-level of the workspace as the root.

# gazelle:js_collect_all none

Stops recursion into subdirectories of the folder containing the directive, and collects all sources and tests into a single rule. Use this to reduce rule count for large repositories. See tests/folder_rules for usage.

# gazelle:js_collect_barrels true|false false

Generate 1 js_library, or ts_project rule per package when a index.ts or index.js file is found, rather than 1 per file. The js_root pkg cannot be a module

# gazelle:js_collect_web_assets true|false false

Causes Gazelle to generate 1 web_assets rule, rather than 1 per file

# gazelle:js_collect_all_assets true|false false

Generates a web_assets rule in the configured js_root that refers to all of the web_assets rules in child packages

# gazelle:js_web_asset .json,.css,.scss none

Files with a matching suffix will have web_assets rules created for them

# gazelle:js_quiet true|false false

Silence extension warnings about missing imports (overrides gazelle:js_verbose)

# gazelle:js_verbose true|false false

Print more information about missing imports (overrides gazelle:js_quiet)

# gazelle:js_jest_config :my_config none

Provide a default label for the config attribute of generated jest_test rules. This is required when using jest_test

# gazelle:js_jest_size none

Provide a default value for the size attribute of generated jest_test rules

# gazelle:js_jest_test_per_shard none

Provide a ratio of number of counted tests for each increment of the shard_count attribute of generated jest_test rules