bazelbuild / bazelbuild/rules_closure

CSS rewriting not working in JS templates

Open
#401 4 comments 0 reactions 0 assignees View on GitHub
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:
Screen Shot 2019-07-08 at 12 37 22 AM

Anybody have any ideas? Or, at least, is anyone seeing the same behavior?

Contributor guide

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.