sarsamurmu/reboost

Unable to import css files

GHNewbiee opened this issue ยท 12 comments

After import cssStyles from './styles.module.css' and <div>${JSON.stringify(cssStyles)}</div> I get an empty object.

Do I miss something?

I tested it with the React playground and it's working fine. Did you customize the CSSPlugin?

I have kept the default values.

Here it is an example. It is based on Lit Element template.

package.json

{
  "name": "reboost-test",
  "version": "0.0.1",
  "description": "",
  "scripts": {
    "dev": "node reboost"
  },
  "license": "MIT",
  "devDependencies": {
    "reboost": "^0.16.2"
  },
  "dependencies": {
    "lit-element": "^2.4.0",
    "lit-html": "^1.3.0"  <- `Additional`
  }
}

reboost.js

const {
  start,
  builtInPlugins: {   // `Additional`
    CSSPlugin,        // `Additional`
    esbuildPlugin     // `Additional`
  }
} = require('reboost');

start({
  entries: [
    ['./src/index.js', './public/dist/index.js']
  ],
  contentServer: {
    root: './public',
    open: { app: '/usr/bin/waterfox-current' }  // Modified
  },
  plugins: [                                    // Additional
    esbuildPlugin({ target: 'es2015' }),        // Additional
    CSSPlugin()                                 // Additional
  ]
});

./public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>reboost-test</title>
    <script type="module" src="./dist/index.js"></script>
  </head>

  <body>
    <my-element></my-element>
  </body>
</html>

./src/index.js

import { LitElement, customElement, css, html } from 'lit-element';
import cssStyles from './styles.module.css';

@customElement('my-element')
export class MyElement extends LitElement {
  render() {
    return html`
      <div>${JSON.stringify(cssStyles)}</div>   <!-- !!!Additional!!! -->
      <div class="background"></div>
      <div class="main">
        <p>
          Get started by editing
          <code>src/index.js</code> and <code>public/index.html</code>
        </p>
      </div>
    `
  }
}

./src/styles.module.css

.main {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 2.2rem;
  text-align: center;
  font-family: sans-serif;
  color: white;
  background-color: #2a2938;
  padding: 20px;
}

Browser

{"main":"_main_0_"}

Get started by editing src/index.js and public/index.html

Q1: Is this what I should expect?

In addition, I would like to write something like:

  static get styles() {
    return css`${Function(cssStyles)}`;
  }

where Function(cssStyles) == styles.module.css i.e. I would like to get back the content of the styles.module.css file.

Q2: How can I do that?

I am aware that I can create a new file like:

myStyles.js

import { css } from 'lit-element';

export const myStyles = css`
  .main {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 2.2rem;
    text-align: center;
    font-family: sans-serif;
    color: white;
    background-color: #2a2938;
    padding: 20px;
  }
`;

and write:

import { myStyles } from './myStyles.js'
...
  static get styles() {
    return [myStyles];
  }

I will think about it.

Update to v0.17.0. The syntax to get the CSS content is -

import styles from "./file.css";

const cssContent = styles.toString();

Just FYI, I have observed the following issues:

  • 1st - Both cssStyles and cssStyles.toString() give the same result
import { LitElement, customElement, css, unsafeCSS, html } from 'lit-element';
import cssStyles from './styles.css';

@customElement('my-element')
export class MyElement extends LitElement {
  render() {
    return html`
      <div>${cssStyles}</div>
      <div>${cssStyles.toString()}</div>
      <div class="background"></div>
      <div class="main">
        <p>
          Get started by editing
          <code>src/index.js</code> and <code>public/index.html</code>
        </p>
      </div>
    `
  }
}

then browser displays

/* src/styles.css */ .main { position: fixed; top: 0; left: 0; bottom: 0; right: 0; display: flex; justify-content: center; align-items: center; font-size: 2.2rem; text-align: center; font-family: sans-serif; color: white; background-color: #2a2938; padding: 20px; } /*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9zdHlsZXMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi5tYWluIHtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIGJvdHRvbTogMDtcbiAgcmlnaHQ6IDA7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBmb250LXNpemU6IDIuMnJlbTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBmb250LWZhbWlseTogc2Fucy1zZXJpZjtcbiAgY29sb3I6IHdoaXRlO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMmEyOTM4O1xuICBwYWRkaW5nOiAyMHB4O1xufSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiJyZWJvb3N0Oi8vLyJ9 */
/* src/styles.css */ .main { position: fixed; top: 0; left: 0; bottom: 0; right: 0; display: flex; justify-content: center; align-items: center; font-size: 2.2rem; text-align: center; font-family: sans-serif; color: white; background-color: #2a2938; padding: 20px; } /*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9zdHlsZXMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi5tYWluIHtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIGJvdHRvbTogMDtcbiAgcmlnaHQ6IDA7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBmb250LXNpemU6IDIuMnJlbTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBmb250LWZhbWlseTogc2Fucy1zZXJpZjtcbiAgY29sb3I6IHdoaXRlO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMmEyOTM4O1xuICBwYWRkaW5nOiAyMHB4O1xufSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiJyZWJvb3N0Oi8vLyJ9 */

Get started by editing src/index.js and public/index.html

Both cssStyles and cssStyles.toString() give the same result.

  • 2nd - When css module is used then cssStyles.main does not exist but another class with name _main_0_.
import { LitElement, customElement, css, unsafeCSS, html } from 'lit-element';
import cssStyles from './styles.module.css';       /* !!! "module." added !!! */

@customElement('my-element')
export class MyElement extends LitElement {
  render() {
    return html`
      <div>${cssStyles}</div>
      <div>${cssStyles.toString()}</div>
      <div class="background"></div>
      <div class="main">
        <p>
          Get started by editing
          <code>src/index.js</code> and <code>public/index.html</code>
        </p>
      </div>
    `
  }
}

then browser displays

/* src/styles.css */ ._main_0_ { position: fixed; top: 0; left: 0; bottom: 0; right: 0; display: flex; justify-content: center; align-items: center; font-size: 2.2rem; text-align: center; font-family: sans-serif; color: white; background-color: #2a2938; padding: 20px; } /*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9zdHlsZXMubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTtFQUNFLGVBQWU7RUFDZixNQUFNO0VBQ04sT0FBTztFQUNQLFNBQVM7RUFDVCxRQUFRO0VBQ1IsYUFBYTtFQUNiLHVCQUF1QjtFQUN2QixtQkFBbUI7RUFDbkIsaUJBQWlCO0VBQ2pCLGtCQUFrQjtFQUNsQix1QkFBdUI7RUFDdkIsWUFBWTtFQUNaLHlCQUF5QjtFQUN6QixhQUFhO0FBQ2YiLCJzb3VyY2VzQ29udGVudCI6WyIubWFpbiB7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgdG9wOiAwO1xuICBsZWZ0OiAwO1xuICBib3R0b206IDA7XG4gIHJpZ2h0OiAwO1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZm9udC1zaXplOiAyLjJyZW07XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWY7XG4gIGNvbG9yOiB3aGl0ZTtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzJhMjkzODtcbiAgcGFkZGluZzogMjBweDtcbn0iXSwic291cmNlUm9vdCI6InJlYm9vc3Q6Ly8vIn0= */
/* src/styles.css */ ._main_0_ { position: fixed; top: 0; left: 0; bottom: 0; right: 0; display: flex; justify-content: center; align-items: center; font-size: 2.2rem; text-align: center; font-family: sans-serif; color: white; background-color: #2a2938; padding: 20px; } /*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9zdHlsZXMubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTtFQUNFLGVBQWU7RUFDZixNQUFNO0VBQ04sT0FBTztFQUNQLFNBQVM7RUFDVCxRQUFRO0VBQ1IsYUFBYTtFQUNiLHVCQUF1QjtFQUN2QixtQkFBbUI7RUFDbkIsaUJBQWlCO0VBQ2pCLGtCQUFrQjtFQUNsQix1QkFBdUI7RUFDdkIsWUFBWTtFQUNaLHlCQUF5QjtFQUN6QixhQUFhO0FBQ2YiLCJzb3VyY2VzQ29udGVudCI6WyIubWFpbiB7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgdG9wOiAwO1xuICBsZWZ0OiAwO1xuICBib3R0b206IDA7XG4gIHJpZ2h0OiAwO1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZm9udC1zaXplOiAyLjJyZW07XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWY7XG4gIGNvbG9yOiB3aGl0ZTtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzJhMjkzODtcbiAgcGFkZGluZzogMjBweDtcbn0iXSwic291cmNlUm9vdCI6InJlYm9vc3Q6Ly8vIn0= */

Get started by editing src/index.js and public/index.html

The class name has changed from main to _main_0_ and, I suspect that

document.body.backgroundColor = cssStyles.main.backgroundColor;

does not work as expected.

  • 3rd - When unsafeCSS function has been removed then white screen is displayed
import { LitElement, customElement, css, unsafeCSS, html } from 'lit-element';
import cssStyles from './styles.css';

@customElement('my-element')
export class MyElement extends LitElement {
  static get styles() {
    return css`${cssStyles}`;  /* or -    unsafeCSS function has been removed */
    return css`${cssStyles.toString()}`;
  }

  render() {
    return html`
      <div>${cssStyles}</div>
      <div>${cssStyles.toString()}</div>
      <div class="background"></div>
      <div class="main">
        <p>
          Get started by editing
          <code>src/index.js</code> and <code>public/index.html</code>
        </p>
      </div>
    `
  }
}

then browser displays white screen.

I suspect it has to do with LitElement css tag function, although only valid CSS literals are used.

  1. It looks like JavaScript uses Object.prototype.toString() to convert objects into a string. The exported object has the toString() property that's why it's showing the CSS content, for this case just use JSON.stringify(cssStyles).

  2. That's how CSS modules are supposed to work.
    Assume your CSS module is like this

    /* styles.module.css */
    .main { color: black }

    It will transform into a JavaScript module like this

    // ... other generated codes, not related to this
    
    export const toString = () => `
      ._main_0_ { color: black }
    `;
    export default {
      main: '_main_0_',
      toString
    }

    As you can see, CSS modules transform your CSS and modify your class names, and exports an object that maps your original class names to the generated ones.

  3. It looks like when unsafeCSS is not used, lit-element thinks that the source map comments are malicious, that's why it just declines the CSS and you see a blank screen.

I think this is what you need - Lit CSS Plugin for Reboost

After providing Lit CSS Plugin officially, you could ask, both Reboostand plugin, to be added in:

Nice!