Skip to content
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

Import with require does not work anymore for transpiled library #261

Open
rbsdc opened this issue Jan 31, 2025 · 4 comments
Open

Import with require does not work anymore for transpiled library #261

rbsdc opened this issue Jan 31, 2025 · 4 comments

Comments

@rbsdc
Copy link

rbsdc commented Jan 31, 2025

We have a Java library that is transpiled with j2cl to JavaScript, resulting in a "mylib.js". Until now, we were able to use the transpiled Java-classes and libraries as follows:

const MyUtils = require("mylib").MyUtils;
...
MyUtils.doSomething();

However, since a change in recent days (it seems to be this commit here: bazelbuild/rules_closure@b159f54), this kind of import does not work anymore. What now works is

import "mylib";
...
globalThis.MyUtils.doSomething();

We use browserify for bundling. I see now the following options:

  1. Replace all our imports and usages with globalThis like above.
  2. Add some post-processing for the transpiled mylib.js (most probably not future-proof)
  3. Find some transpiler argument or config that allows imports as before.

Is globalThis the way to go now? Or is there a reasonable and future-proof way to keep our require imports (e.g. some transpiler argument?) with the given setting (browserify)? Maybe, the way we use require was never intended like this for j2cl-transpiled libraries?

bazel version 7.4.0
bazelrc (like in the samples)

build --watchfs

build --spawn_strategy=local
build --strategy=J2cl=worker
build --strategy=Closure=worker
build --strategy=Javac=worker
build --strategy=JavaIjar=local
build --strategy=JavaDeployJar=local
build --strategy=JavaSourceJar=local
build --strategy=Turbine=local

# --experimental_inprocess_symlink_creation is used to workaround the missing
# support for paths with spaces https://github.com/bazelbuild/bazel/issues/4327.
# Remove the two flags after this issue is fixed in bazel new release.
build --enable_platform_specific_config
build:macos --experimental_inprocess_symlink_creation

test --test_output=errors

# Enable Java 11
build --java_language_version=11
build --java_runtime_version=11

# Enable Java 11 for J2CL compiler itself
build --tool_java_language_version=11
build --tool_java_runtime_version=11

BUILD

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library")
load("@com_google_j2cl//build_defs:rules.bzl", "j2cl_application")

package(
    licenses = ["notice"],  # Apache 2.0
)

closure_js_library(
    name = "lib",
    srcs = ["lib.js"],
    deps = [
        "//src/main/java/org/mylib/lib"
    ],
)

j2cl_application(
    name = "mylib",
    entry_points = [
        "org.mylib"
    ],
    deps = [":lib"],
    extra_production_args = [
        '--compilation_level=SIMPLE'
    ]
)

lib.js

goog.module('org.mylib.lib');

const MyClass = goog.require('org.mylib.lib.MyUtils');

goog.exportSymbol('MyUtils', MyClass);
goog.exportSymbol('MyUtils.doSometing', MyUtils.doSomething);
@gkdn
Copy link
Member

gkdn commented Jan 31, 2025

To double check; you are using the compiled output, not the dev bundle from j2cl_application target, right?

@rbsdc
Copy link
Author

rbsdc commented Jan 31, 2025

@gkdn. If you mean the transpiled library (above called mylib.js), then it is the one contained in bazel-bin/src/main/javascript/mylib.js after the build completed (The build command is bazel build src/main/javascript:mylib.)

@rbsdc
Copy link
Author

rbsdc commented Jan 31, 2025

More context: With the newest updates, the transpiled mylib.js contains the following function:

goog.global = globalThis;
goog.exportPath_ = function (a, b, c, d) {
    a = a.split(".");
    d = d || globalThis;
    ...
};

When I replace goog.global = globalThis; with goog.global = this || self; and d = d || globalThis; with d = d || goog.global; (as it was previously), then the require imports works as before.

@gkdn
Copy link
Member

gkdn commented Feb 1, 2025

Ah I see. It seems like the code is loaded in different context than globalThis in commonjs setup.

I'm talking Closure folks it will be ok with reverting this behavior back.

Do you know if there a good way to reproduce this problem in rules_closure without introducing new deps so we can add some tests?

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

No branches or pull requests

2 participants