bennypowers/lit-css

CSS Modules / Import Assertions

bennypowers opened this issue · 3 comments

Users should be able to opt-in to polyfilling css modules / import assertions, rather than getting the css-tagged-literal version

A later breaking version would switch it to opt-out (i.e., users would then have to opt-in to what is now current behaviour)

I tried Import Assertions like this:

  • I set compilerOptions.module = "esnext" in tsconfig.json so tsc allows that syntax
  • I defined the import this way:
     import styles from './styles.css' assert {type: 'css'};
  • I gave it a try with only tsc and it worked fine In Chrome. I had to convince others:
    <!-- @support: Safari, Firefox. It doesn't yet have the Import assertions -->
    <script async src="https://unpkg.com/es-module-shims@0.13.1/dist/es-module-shims.js"></script>
    <script async src="https://unpkg.com/construct-style-sheets-polyfill@3.1.0/dist/adoptedStyleSheets.js"></script>
    <script>
      window.esmsInitOptions = { polyfillEnable: ['css-modules' ] }
    </script>
    <!-- END -->

But Rollup (with plugin) didn't work very well with just rollup-plugin-lit-css - it threw from Module.tryParse. rollup-plugin-import-assert added as described.

I tried 2 orders:

  1. rollup-plugin-import-assert, then rollup-plugin-lit-css
  2. rollup-plugin-lit-css, then rollup-plugin-import-assert

First one worked on dev build (obviously for Chrome, with some struggle, helped by polyfill in Safari), but for build with rollup if produced invalid CSSResult in which cssText contained this wrapper:

https://github.com/calebdwilliams/rollup-plugin-import-assert/blob/32ba2605f21401f7941145539fe3a2cfef8c53f6/src/import-assert.ts#L102-L104

Second attempt made the imported object not a CSSResult but CSSStyleSheet in Chrome and triggered Illegal constructor error in Safari because this time it was rollup-plugin-lit-css what got already wrapped piece, this time wrapped in wrapper of rollup-plugin-lit-css, which is also not a valid CSS, that's why it failed.

I think the right order is the first one (assertions, then litcss), so I gave it a try with with transform option and I naively unwrapped the content from what rollup-plugin-import-assert left:

const naivelyUnwrapFromWhatAssertionsPluginProduced = css => {
  if (css.includes('CSSStyleSheet')) {
    return css
      .replace('const sheet = new CSSStyleSheet();sheet.replaceSync(`', '')
      .replace('`);export default sheet;', '')
  }

  return css;
}

Aaaaand... that worked.
It's definitely not a sustainable option as it will likely break when there's any change in package rollup-plugin-import-assert, but it unblocked me with my experiments.

yes @jrencz that tracks, so I'd like to implement the plan from OP now and make a boolean config option like native: false or something like that which removes the template tag import altogether in favour of native constructors.

Once tooling and browser support matures, I'd switch the default to true in a breaking change. and probably shortly afterwards cease maintenance on the library because who'd need it?