Guidance on linking TypeScript packages together in a repo #801
Replies: 13 comments
-
I think pnpm workspaces is still the best option and should work with ts. It's not merged yet but here's an example: aspect-build/bazel-examples#114 |
Beta Was this translation helpful? Give feedback.
-
@jbedard Interesting - I'll take a look at your PR for inspiration here, thanks for that. One other disadvantage I was thinking about with pnpm workspaces though is keeping all of the 3rd party dependency versions in sync. Upgrading a commonly-used dependency across the repo will result in hundreds of package.json file changes showing up in a pull request. Having a single root-level package.json solves this issue. Any thoughts on that? |
Beta Was this translation helpful? Give feedback.
-
You can avoid repeating the version everywhere doing |
Beta Was this translation helpful? Give feedback.
-
@jbedard I'm familiar with doing |
Beta Was this translation helpful? Give feedback.
-
Right... for third-party deps I think |
Beta Was this translation helpful? Give feedback.
-
^ nope, I don't think |
Beta Was this translation helpful? Give feedback.
-
The example @jbedard referenced solves just that. The |
Beta Was this translation helpful? Give feedback.
-
Let me know if you encounter a specific use-case wrt. internal or external dependencies that doesn't work you. The approach when publishing packages to NPM requires a bit more "stuff" than what the aforementioned example contains. |
Beta Was this translation helpful? Give feedback.
-
@BeyondEvil Ah, yes, we will be publishing these packages to npm so we can't simply inherit the dependencies from the repo's directory tree. My current setup actually involves not having any That being said, if pnpm workspaces are "the way", then I might do this a little differently |
Beta Was this translation helpful? Give feedback.
-
@gregjacobs I think you might have to just put those into the root package.json and not specify them in each workspace package. Each workspace package will still specify the fine grained deps in the BUILD but no longer in each package.json. This is what @BeyondEvil mentioned and is used in aspect-build/bazel-examples#114 |
Beta Was this translation helpful? Give feedback.
-
@jbedard @gregjacobs can this be closed? |
Beta Was this translation helpful? Give feedback.
-
I think it can be closed with pnpm workspaces as the common solution. aspect-build/rules_js#818 will also help when depending on 3rd-party packages (without having to repeat them in every package.json in a workspace). |
Beta Was this translation helpful? Give feedback.
-
#313 landed which is a better alternative to aspect-build/rules_js#818. non-dev npm packages in I'll tag this issue as documentation since I think we needed better docs on how this should work. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hey there. I think the docs need some guidance on linking packages together in a repo.
Just for quick context: we have a monorepo of about 200 packages that we publish to npm. Some of these packages rely on each other, and need to refer to their dependencies by package name:
We can't import using relative paths like in some of the examples because then the imports wouldn't work correctly when the packages are npm installed by our users.
Some attempts at linking packages in our Bazel repo so far:
pnpm workspaces
: This is recommended on therules_js
readme but doesn't seem to work for typescript packages because it links to the source folders rather than Bazel's output folders. So when we want to buildpackage-2
, we really need it to build against the output ofpackage-1
(i.e.bazel-bin/package-1
) rather than the source of package-1.npm_link_package
: I thought that this would solve my issue but observed some weird effects. Package-2 didn't actually need to declare//:node_modules/package-1
as a dependency for it to be available at build time (worker), and thuspackage-1
's output could be stale when buildingpackage-2
. Unfortunately, it's too easy to miss declaring all first party deps like this in a large repo when there is no build error for it. Also it isn't exactly desirable to put 200npm_link_package
entries into the root BUILD file (although I would if the stale package issue didn't exist!).paths
: I added:ts_project
use package-1'sts_project
rule in itsdeps
, but sadly fails at runtime ofpackage-2
because Node.js can't find the runtime files forpackage-1
(since 'package-1' doesn't exist in thenode_modules
tree for package-2).NODE_PATH
: Total hack to get case 3 working, I setNODE_PATH=path/to/bazel-out
so that Node.js can find the "node_modules" (i.e. Node treats these as "global node modules" in this case). However, the problem I'm having with this now is that our directory structure doesn't match our package names, soNODE_PATH
won't work for the package atcomponents/alert/react
because its package name is@uitoolkit-react/alert
. (Just as an fyi, our directory structure optimizes the developer experience and code reviews because we have 'common' code that relates to the angular/react packages, and we can place those folders physically close together under a common directory)As for one more point: if I'm recalling correctly, it's best for two
ts_project
rules to rely directly on each other to optimize the build graph between them since package-2 shouldn't need to rebuild if the.d.ts
files for package-1 haven't changed. If so, I guess option 2 wouldn't be good since it would have the extranpm_package
andnpm_link_package
rules in its graph such as the following?Anyway, looking for recommendations. Thanks!
Beta Was this translation helpful? Give feedback.
All reactions