Rollup, Svelte, SCSS: how to build different bundles at once?

Viewed 2725

My Svelte project consists in three totally different views: admin, client and POS (point-of-sale).

| src/
|   admin/
|      index.js
|      admin.svelte
|      admin.scss
|   client/
|      index.js
|      client.svelte
|      client.scss
|   pos/
|      index.js
|      pos.svelte
|      pos.scss
| rollup.config.js

I need that all three Svelte files be built at once (with yarn build) and generating three different css files on public directory. CSS files under css/ and JS files under js/ like that:

| public/
|   css/
|      admin.css
|      client.css
|      pos.css
|   js/
|      admin.js
|      client.js
|      pos.js

āœ… What I could achieve so far:

  • Each JS file (from Svelte) is built in public (but not js)
  • Every css from Svelte is built in public/css

What I couldn't do:

  • SCSS files are not being built
  • JS files are not inside js/
  • JS files are all named 'index.js'
  • Livereload in localhost

That's the rollup.config.js:

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import {terser} from 'rollup-plugin-terser';
import {sass} from 'svelte-preprocess-sass';
import scss from 'rollup-plugin-scss'
import svg from 'rollup-plugin-svg-import';
import json from '@rollup/plugin-json';

const production = !process.env.ROLLUP_WATCH;

function plugins(name, index) {
    return [
        svg({stringify: true}),
        json({}),
        scss({
            output: `css/scss-${name}.css`
        }),
        svelte({
            preprocess: {
                style: sass({all: true}, {name: 'scss'}),
            },
            // enable run-time checks when not in production
            dev: !production,
            // we'll extract any component CSS out into
            // a separate file - better for performance
            css: css => {
                css.write(`css/svelte-${name}.css`);
            }
        }),

        // If you have external dependencies installed from
        // npm, you'll most likely need these plugins. In
        // some cases you'll need additional configuration -
        // consult the documentation for details:
        // https://github.com/rollup/plugins/tree/master/packages/commonjs
        resolve({
            browser: true,
            dedupe: ['svelte']
        }),
        commonjs(),

        // In dev mode, call `npm run start` once
        // the bundle has been generated
        !production && serve(),

        // If we're building for production (npm run build
        // instead of npm run dev), minify
        production && terser({
            compress: {
                keep_fnames: true,
                keep_classnames: true,
            }
        }),

        // Watch the `public` directory and refresh the
        // browser on changes when not in production
        !production && livereload({
            watch: `public/${name}.*`,
            port: 3000 + index
        }),
    ]
}

function serve() {
    let started = false;

    return {
        writeBundle() {
            if (!started) {
                started = true;

                require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
                    stdio: ['ignore', 'inherit', 'inherit'],
                    shell: true
                });
            }
        }
    };
}

const views = [
    'admin',
    'client',
    'pos',
];


// Code author:
// https://github.com/rollup/rollup/issues/703#issuecomment-508563770
export default views.map((name, index) => ({
    input: `src/${name}/index.js`,
    output: {
        sourcemap: true,
        format: 'iife',
        name: name,
        dir: 'public',
    },
    plugins: plugins(name, index),
    watch: { clearScreen: false }
}));
1 Answers

For the filenames: you should just use output.file, output.dir is only usefull if you generate multiple chunks in the same run, but you are generating one bundle in three different runs. That will also fix the directory issue at the same time.

output: {
  sourcemap: true,
  format: 'iife',
  name: name,
  file: `public/js/${name}.js`,
},

I am not sure about the scss and livereload, that code looks ok to me

Related