rules_closure
rules_closure copied to clipboard
CSS rewriting not working in JS templates
tl;dr CSS rewriting does not seem to be working, at least in terms of JS' invocation of getCssName
.
Given the following setup (WORKSPACE
and related wiring omitted):
sample.soy
:
{namespace sample.tpl}
{template .sample}
<div class="{css('hello')}">
<b>hi</b>
</div>
{/template}
sample.css
:
.hello {
background: blue;
}
sample.js
:
goog.provide('sample');
const soy = goog.require('goog.soy');
const tpl = goog.require('sample.tpl');
const docFrag = document.createDocumentFragment();
const el = soy.renderAsElement(
docFrag,
tpl.sample,
{},
{});
document.body.appendChild(docFrag);
BUILD.bazel
:
closure_css_library(
name = "sample-css",
srcs = ["sample.css"],
)
closure_js_template_library(
name = "sample-tpl",
srcs = ["sample.soy"],
deps = [":sample-css"],
)
closure_css_binary(
name = "sample-styles",
deps = [":sample-css"],
)
closure_js_library(
name = "sample-js",
srcs = ["sample.js"],
deps = [
":sample-tpl",
"@io_bazel_rules_closure//closure/library/soy:soy",
]
)
closure_js_binary(
name = "sample",
debug = False,
entry_points = ["sample"],
deps = [":sample-js"],
css = ":sample-styles",
)
When I build and run the resulting JS, the template renders, but it renders with the original CSS names, whereas, the CSS has been rewritten. This breaks styles, of course.
Digging into the intermediates:
bazel-out/darwin-fastbuild/bin/.../sample.js-0.params
:
external/com_google_javascript_incremental_dom/.../lots.js
external/com_google_javascript_incremental_dom/.../of.js
external/com_google_javascript_incremental_dom/.../sources.js
...
...
...
bazel-out/darwin-fastbuild/bin/.../sample.css.js
--define=now=true
--define=some=true
--define=defines=true
The last entry in the set of input files, is a file that ends in css.js
. Examining that file, it looks like we're on the money:
goog.setCssNameMapping({
"material": "a",
"icons": "b",
"hidden": "c",
"mdl": "d",
"button": "e",
"no": "f",
"select": "g",
"numeric": "h",
// ...
In the generated template file, it seems to know what's going on (as in, it's using goog.getCssName
):
incrementalDom.attr('action', '#');
incrementalDom.attr('class', goog.getCssName('page-welcome--form-module') + ' ' + goog.getCssName('page-welcome--form-account'));
But, in the final output JS, it uses the original classes:
Anybody have any ideas? Or, at least, is anyone seeing the same behavior?
Did some digging and it definitely seems like rules_closure is doing what it should. Cross-filed with GCC at google/closure-compiler#3427.
after some discussion on google/closure-compiler#3427, and a sample repo at sgammon/css-rewrite-bug, it has been determined it isn't the compiler, which of course was likely.
it now seems like it might be an issue inside J2CL, because i can't get rules_closure
to build the sample at all without wrapping it in j2cl_application
. more to come, if anybody is hitting this same issue
btw if you are getting issues with symbols-already-defined for goog.soy
or soy
, try building through j2cl_application
. i have no idea why it works but it does.
The issue is that you set dependency_mode = "STRICT"
, which will eliminate all files that are not in the transitive closure of entry_points
(i.e. not in entry_points
and never goog.require
d). As a workaround, you can
- set
dependency_mode = "PRUNE_LEGACY"
which will include all files withoutgoog.{module,provide}
as entry points (https://github.com/google/closure-compiler/blob/445fdf3f31d848d955d71d10f4794b45c0f4d1a6/src/com/google/javascript/jscomp/CommandLineRunner.java#L805), or - add
src/sample-styles.css.js
as entry point
We should probably automatically add the css rewrining map as an entry point.
Also, dependency_mode = "STRICT"
is deprecated. You should switch to dependency_mode = "PRUNE"
which has the same effect:
https://github.com/google/closure-compiler/blob/445fdf3f31d848d955d71d10f4794b45c0f4d1a6/src/com/google/javascript/jscomp/CommandLineRunner.java#L145