bazelbuild / bazelbuild/rules_closure
CSS rewriting not working in JS templates
- Dominant language
- Java
- Stars
- 159
- Forks
- 111
- PR merge metrics
- No merged PRs in 30d
Description
**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`**:
```soy
{namespace sample.tpl}
{template .sample}
hi
{/template}
```
**`sample.css`**:
```css
.hello {
background: blue;
}
```
**`sample.js`**:
```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`**:
```python
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:
```js
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`):
```js
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?
Contributor guide
Research direction
Reproduce the sample using sample.soy, sample.css, sample.js, and BUILD.bazel, then compare the generated template, the sample.css.js mapping, and the final output JS. Start at the closure_js_template_library and closure_js_binary wiring and trace how goog.getCssName is handled. Done means the rendered class names match the rewritten CSS names.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, javascript
- Domain
- build-system, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100