Skip to content
Advertisement

Rollup : single html output

I’m trying to package my Svelte app into a single Html file output. I’ve managed to get the desired output with a configuration based on that answer : Output Single HTML File from Svelte Project

With “npm run dev” everything is fine with the first build, but I’m having issues following (live-reload) builds: bundle['bundle.css'] is not filled in my inlineSvelte‘s generateBundle function.

I didn’t manage to change the rollup-plugin-css-only for rollup-plugin-embed-css, which seemed to have an appropriate name for my needs.

Here’s my rollup.config.js :

import svelte from 'rollup-plugin-svelte';
import livereload from 'rollup-plugin-livereload';
import css from 'rollup-plugin-css-only';
...

function inlineSvelte(templatePath, dest) {
  return {
    name: 'Svelte Inliner',
    generateBundle(opts, bundle) {
      const file = path.parse(opts.file).base;
      const jsCode = bundle[file].code;
      const cssCode = bundle['bundle.css'].source;
      const template = fs.readFileSync(templatePath, 'utf-8');
      bundle[file].code = template
        .replace('%%script%%', jsCode)
        .replace('%%style%%', cssCode);
    }
  }
}

export default {
  input: 'src/main.js',
  output: {
    format: 'es',
    file: outputDir + 'index.html',
    name: 'app'
  },
  plugins: [
    svelte({
        compilerOptions: {
            dev: !production
        }
    }),
    css({ output: 'bundle.css' }),
    resolve({
        browser: true,
        dedupe: ['svelte']
    }),
    commonjs(),
    !production && livereload(outputDir),
    inlineSvelte('./src/template.html')
  ],
  watch: {
    clearScreen: false
  }
};

Advertisement

Answer

It is surely possible to embed the produced CSS file in your HTML, at least with some reasonably simple custom plugin.

However, if you only have CSS in your Svelte components, that is you don’t have import 'whatever.css' anywhere in your code, you can just rely on Svelte injecting CSS from compiled JS code and be done with it.

This loses a little in terms of performance because such injected CSS will never be cached by the browser, but it avoids the added complexity / risk / coupling associated with a custom build step… And this kind of performance is often not so important in scenarios where you want all your app in a single HTML file.

To enable this, set emitCss: false on the Svelte plugin:

  plugins: [
    svelte({
      emitCss: false,
      ...
    }),
    ...
  ],
  ...

You won’t need any Rollup plugin for CSS in this case.

1 People found this is helpful
Advertisement