zodern / melte

Svelte compiler for Meteor with built in tracker integration and HMR
MIT License
33 stars 14 forks source link

Static CSS not included in build #12

Closed arggh closed 2 years ago

arggh commented 3 years ago

If I set css: false in zodern:melte's svelte:compiler settings, then all (Svelte components') CSS gets discarded completely.

I would expect that CSS to be included as part of the merged stylesheets. If I set css: true, the styles get included in the JS bundle as expected.

The meaning of css: true vs. css: false in the Svelte's compiler logic is whether to include to CSS in JS code or not, in which case it gets passed to CSS output, which in my understanding, zodern:melte should include in the app's CSS bundle.

From https://svelte.dev/docs#svelte_compile

If true, styles will be included in the JavaScript class and injected at runtime. It's recommended that you set this to false and use the CSS that is statically generated, as it will result in smaller JavaScript bundles and better performance.

zodern commented 3 years ago

I'm not sure if Meteor's build system supports this - non-lazy stylesheets are always added to the app regardless of if it is imported, and lazy stylesheets are only added if imported but are added to the js bundle so they can be dynamically imported.

To work as desired, we would have to add the stylesheet as non-lazy within the lazy finalizer for the js resource so it is added to the css bundle only if the svelte file is imported. I have never tried that, so I don't know if it is supported. If it isn't, we will need to look into modifying Meteor's build system to support scenarios like this.

arggh commented 3 years ago

To work as desired, we would have to add the stylesheet as non-lazy within the lazy finalizer for the js resource so it is added to the css bundle only if the svelte file is imported

I'm not sure I follow 100%, since I haven't yet fully figured out what the CachingCompiler inner flow is, but I think I already did what you are thinking of here and it seemed to work:

compileOneFileLater(file, getResult) {
    // Search for top-level head and body tags. If at least one of these tags
    // exists, the file is not processed with the Svelte compiler. Instead, the
    // inner HTML of the tags is added to the respective section in the HTML
    // output generated by Meteor.
    const sections = this.getHtmlSections(file);

    if (sections) {
      sections.forEach(section => file.addHtml(section));
    } else {
      file.addJavaScript({
        path: file.getPathInPackage()
      }, async () => {
        const { js, css } = await getResult();

        if (css) {
          file.addStylesheet(css);
        }

        return js;
      });
    }
  }
zodern commented 3 years ago

That is what I meant. If this works, it opens up many possibilities!

arggh commented 3 years ago

I just created a PR with what I've got so far, so you can take a better look: https://github.com/zodern/melte-compiler/pull/2