question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

add `prebuild` option for our typescript setup like we have in npm eco system

See original GitHub issue

Description of the feature request:

In our yarn workspace Typescript monorepo we have the option before building anything, to mangle some files. I would like to have the same feature in our bazel build file, or if not possible inside for example js_library (from load("@build_bazel_rules_nodejs//:index.bzl", "js_library")) to mangle our package.json before/after creating its package.

What underlying problem are you trying to solve with this feature?

During development we have other pointers in our package(s) to point the module (and its typings) to the sources and have Typescript path mapping point to the packages its sources. Our package.json per module is our contract.

So in an npm ecosystem (jest/webpack/vite/whetever) everything works as implemented, you have the option to look at sources or packaged/compiled files. This is based on the Typescript feature path mapping to be there (sources) or not (compiled). And during the creation of the package you have the option during pre-build stage to adjust things inside its package.json (for example remove dev dependencies, and alter module location).

In bazel setup this is not possible. By design. So you cant use sed/jq/etc to mangle a file its content and output it to the same file before you inject it. That will throw a cycle error. So genrule isn’t helpful for this usecase.

I tried post_install_patches option with our workspace yarn install, but then it seems we have to create a patch per own package and we have lots of them, thats not scalable (so didnt look further) edit: and didnt seem to work for local packages (file content stayed the same). But otherwise im completely lost in options. I also tried to first archive the adjusted file and then strip the path and use it as source, but thats also detected as a cycle (so really good design of Bazel!)

Which operating system are you running Bazel on?

osx and linux

What is the output of bazel info release?

release 5.3.0

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What’s the output of git remote get-url origin; git rev-parse master; git rev-parse HEAD ?

private

Have you found anything relevant by searching the web?

github issue: https://github.com/bazelbuild/bazel/issues/7311

Any other information, logs, or outputs that you want to share?

We have a yarn workspace monorepo

Packages currently have the following setup, which always exports the package its content from an src/index, example package:

{
  "name": "@mpth-ui/page",
  "version": "1.0.0",
  "main": "./src/index.ts",
  "description": "Generic page component",

This index file just exports what can be consumed by consumers, so for this example it’s:

export { Page } from './Page'
export { PageWithRefresh } from './PageWithRefresh'
export type { PageMaxWidth, PageOptions, PageWithRefreshOptions } from './types'

During local development we spinup a webpack server for the application we are working on (also part of the monorepo) and use workspace path mappings. So everything works lightning fast. When we had lerna as tooling we just used the npm prebuild hook for every package. Every components extends its tsconfig on the root’s one.

Our basic workspace ./tsconfig.json looks like:

{
  "compilerOptions": {
    "baseUrl": "./packages",
    "paths": {
      "@mpth/page": ["ui-components/page/src/*"],

This file is not used in our Bazel workflow (empty file is copied from our WORKSPACE), so package references will always look at their compiled (so cached) versions. Thats the whole thing what makes bazel (and any distributed cache implementation) fast. The reason to have this root config is also to let our editor understand how to find/import stuff.

The things i tried was using genrule, or first archive and replace prefix, but they all led to the circulair workflow which bazel prevents.

genrule(
    name = "transform",
    srcs = ["package.json"],
    outs = ["tmp/package.json"],
    local = 1,
    cmd = '''
        sed "s|./src/index.ts|./esm/index.ts|" "$<" > "$@"
    '''
)

I know by design you don’t want two processes mutating stuff (because who will win/dictate the truth), that makes it not deterministic. But the approach followed in a pure typescript project is a common pattern (using path references and mutating a package its package.json in prebuild stage). So i’m really hoping we can have a feature with an option i know what im doing, and do not cycle it 😃

mangling is only meant for ci, not for anything local so i can’t use generic postinstall script for it as well.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
alexeaglecommented, Sep 7, 2022

There are several people who can help with this, usually such issues are filed in a ruleset rather than in the bazelbuild/bazel repo though. Someone with permissions could transfer this issue to bazelbuild/rules_nodejs Alternatively you can come ask in #javascript on slack.bazel.build where we do a bunch of user support.

In bazel setup this is not possible. By design. So you cant use sed/jq/etc to mangle a file its content and output it to the same file before you inject it.

This is not correct - we use jq on a package.json file in the source folder to write a modified package.json file to the output folder. This is just a limitation of genrule. Example: https://github.com/aspect-build/bazel-examples/blob/cc80020f1bfe748e909fae4241c60dc64d098143/angular/defs.bzl#L167-L172

0reactions
maaptehcommented, Sep 8, 2022

So for people finding this thread. With the:

load("@aspect_bazel_lib//lib:repositories.bzl", "register_jq_toolchains")

you will be able to overwrite a file its content by using the same name as the file.

jq(
    name = "package",
    srcs = ["package.json"],
    filter = """
        del(.devDependencies) | 
        del(.scripts) | 
        .main |= "esm/index.js"
    """,
)

But when using out to set the name that will throw an error Error in _jq_rule: rule 'package' has file 'package.json' as both an input and an output". So just use the name as the file name. Credits to the given example 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Setup a TypeScript + Node.js Project | Khalil Stemmler
Starts the app in production by first building the project with npm run build , and then executing the compiled JavaScript at build/index.js...
Read more >
How to set up a TypeScript project - freeCodeCamp
by David Piepgrass How to set up a TypeScript project A thorough guide for beginners making web apps with React Photo by Artem...
Read more >
Publishing Node modules with TypeScript and ES modules
We can do this by making two tsconfig.json files, one that targets ES modules and another for CommonJS. Rather than duplicate all our...
Read more >
Documentation - Integrating with Build Tools - TypeScript
Right-Click -> Manage NuGet Packages · Search for Microsoft.TypeScript.MSBuild · Hit Install · When install is complete, rebuild!
Read more >
Setting Up a Node & TypeScript Project - Configure Tooling
First we need to install our dev dependencies. With eslint/prettier there are quite a few. Refer to the provided table for explanation of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found