-
Notifications
You must be signed in to change notification settings - Fork 232
Re-enable Javascript support #1347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Re-enable Javascript support #1347
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first pass. Have some concerns about the api of kt_js_library.
) | ||
|
||
# required with Bazel 8/workspace | ||
http_archive( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need rules_python
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was needed only for this example (not the root module) with Bazel 8 workspace. It appears related to this change with Bazel 8 bazelbuild/bazel#23043. Without this, I get the error
USE_BAZEL_VERSION=8.2.1 bazel query //... --enable_workspace --noenable_bzlmod
WARNING: WORKSPACE support will be removed in Bazel 9 (late 2025), please migrate to Bzlmod, see https://bazel.build/external/migration.
ERROR: /private/var/tmp/_bazel_smocherla/bfd93a74a834f9acb8d10b4323733a2c/external/rules_python/python/py_cc_link_params_info.bzl:6:84: name 'PyCcLinkParamsProvider' is not defined
ERROR: error loading package under directory '': error loading package '': Internal error while loading Starlark builtins: Failed to autoload external symbols: compilation of module 'python/py_cc_link_params_info.bzl' failed Most likely you need to upgrade the version of rules repository in the WORKSPACE file.
It gets fixed with
USE_BAZEL_VERSION=8.2.1 bazel query //... --enable_workspace --noenable_bzlmod --incompatible_autoload_externally=-@rules_python
WARNING: WORKSPACE support will be removed in Bazel 9 (late 2025), please migrate to Bzlmod, see https://bazel.build/external/migration.
//:.aspect_rules_js/node_modules/accepts@1.3.8
//:.aspect_rules_js/node_modules/accepts@1.3.8/dir
//:.aspect_rules_js/node_modules/accepts@1.3.8/pkg
//:.aspect_rules_js/node_modules/accepts@1.3.8/ref
...
I can add that flag as well (it appears some internal bazel repos rely on rules_python) and because this is WORKSPACE, it breaks unless it's already pulled in.
doc = "A list of other kt_js_library that this library depends on for compilation", | ||
providers = [_KtJsInfo], | ||
), | ||
"output_kind": attr.string( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the rationale of changing the outputs via attributes (output_kind
, sourcemap
)?
It's not a common pattern for bazel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was added to avoid creating .js
outputs on every kt_js_library
target as it's only really required in the final target when running it as Node binary (as an example) - only klibs are required for sharing between targets for compilation. The JS creation part seemed quite slow so I made it conditional to avoid slowing down the builds - I can remove it though and just have it generated by default if desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If generating the js outputs is too slow, the usual approach is to move them to a separate action. The outputs will only be generated if the artifact is used.
The problem with changing the outputs via attributes is that consumers of the library do not have the option to use the library in a different context without modifying the rule, or duplicating it. If the library is being consumed from a repository or, usually in large code bases, is not owned by the consumer, this becomes a problem.
Additionally, there is the additional cognitive load that developer must know the state of each library when adding them as dependencies. Given that Bazel already requires developers to understand and assemble the build graph in addition to writing code (and declaring dependencies again in the source), it's preferable to make the rules as simple and straight forward as possible.
So, let's generate all the outputs for the first pr -- then, optimize for build time by splitting the slow outputs from the fast in other pr. This will complicate the compile process, so some care will need to be taken to avoid increasing the maintenance burden and complexity of the optimization.
I'd almost prefer to start with a PR that adds kotlin native toolchain. When I last reviewed getting js working, it appeared to be saner to start with native and then add js as an output. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add starlark unittests, similar to the existing compile tests
I didn't do it because kotlinc-js is not part of that, it still seems bundled with the regular Kotlin compiler and there weren't any hooks to invoke the K2JS compiler with kotlin-native (they seem to be just sharing the klib infra for the most part). Specifically the flag required to create the JS outputs seemingly exists only with kotlinc-js from my understanding. I can create a separate PR for adding the kotlin-native toolchain though. |
As I understand it, the core build graph of non-jvm compilation produces klibs until a leaf node (js, native binary) is needed. I expect jvm compilation will eventually reach that state. Therefore, it makes more sense to ensure a simple klib pipeline, and then look at how the js and native "binaries" are produced. I'd like to see the native pr to understand how the underlying compilation will change, and see where things can be simplified or are fundamentally complex. |
Please hit the "Re-request review" button when you'd like another pass. |
I took a stab at bootstrapping support for the Kotlin/Native toolchain and producing klibs generically to potentially extend it to other platforms (like JS here) #1351. It's in draft because it has a couple of test failures (which I'm looking into it) but would be interested to see your thoughts on it and if that's the direction you were intending. |
JS support was dropped in #1185 due to Kotlin 2 switching to klibs from JARS for JS libraries and artifacts. This PR aims to re-enable the the JS rules in a way that works with the Kotlin 2 architecture (and the new IR compiler).
Implementation details:
kt_js_import
andkt_js_library
rules. The rules do not deal with JARs at all and klibs are the only way artifacts are passed is throughklibs
, and the final intended binary will bejs
rules_js
withjs_binary
instead ofnodejs_binary
that was being used earlier frombuild_bazel_rules_nodejs
(which is deprecated as it is switched torules_nodejs
where only the NodeJS toolchain exists)Note: I've not pulled in changes to add the kotlin-native toolchain so as to avoid increasing the scope of this PR.
Added an example that works with pnpm/kt_js_library with
express
withrules_js
/pnpm below.I've not tested with advanced/complex usecases yet, but this is a good start.
Additionally, Kotlin 2/js external deps in maven are solely published as klibs now and cannot be consumed with rules (I'm looking to fix that in rules_jvm_external here bazel-contrib/rules_jvm_external#1391)
Checklist:
js_binary
integration working withrules_js
.examples/