Sapper/Svelte SASS preprocessing?

So I was checking out the realworld implementation of Sapper/Svelte: https://github.com/sveltejs/realworld

I've read a lot about SASS preprocessing, and it doesn't seem like it is fully supported, but there are some docs on it. From what I could put together, I should be able to preprocess my tags after I made the following modifications to my webpack.client.config.js file:

const svelte = require('rollup-plugin-svelte');
const sass = require('svelte-preprocess-sass').sass;

const config = require('sapper/webpack/config.js');
const webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
    entry: config.client.entry(),
    output: config.client.output(),
    resolve: {
        extensions: ['.js', '.html']
    },
    module: {
        rules: [
            {
                test: /\.html$/,
                exclude: /node_modules/,
                use: {
                    loader: 'svelte-loader',
                    options: {
                        hydratable: true,
                        emitCss: !config.dev,
                        cascade: false,
                        store: true
                    }
                }
            },
            config.dev && {
                test: /\.css$/,
                use: [
                    { loader: "style-loader" },
                    { loader: "css-loader" }
                ]
            },
            !config.dev && {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: [{ loader: 'css-loader', options: { sourceMap: config.dev } }]
                })
            }
        ].filter(Boolean)
    },
    plugins: [
    svelte({
      preprocess: {
        style: sass(),
      }
    }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'main',
            async: true,
            children: true
        }),
        config.dev && new webpack.HotModuleReplacementPlugin(),
        !config.dev && new ExtractTextPlugin('main.css'),
        !config.dev && new webpack.optimize.ModuleConcatenationPlugin(),
        !config.dev && new UglifyJSPlugin(),
    ].filter(Boolean),
    devtool: config.dev ? 'inline-source-map' : false
};

I keep getting the following error:

node server.js realworldsapper/node_modules/tapable/lib/Tapable.js:375 arguments[i].apply(this);

Any ideas on how to fix this?

2 answers

  • answered 2018-03-14 07:41 vibjerg

    You should add exclude: /node_modules/ to each of your rules:

    test: /\.css$/, exclude: /node_modules/, // <- Add this

    This ensures that transpilation is not applied to any of the files in the node_modules folder.

  • answered 2018-03-14 12:26 Rich Harris

    You're mixing and matching Rollup and webpack, which are two different module bundlers — you're adding rollup-plugin-svelte to a webpack config, and webpack doesn't know what to do with it so it throws an error.

    Instead, use svelte-preprocess-sass inside the svelte-loader config:

    use: {
      loader: 'svelte-loader',
      options: {
        hydratable: true,
        emitCss: !config.dev,
        cascade: false,
        store: true,
        style: sass()
      }
    }
    

    (Note that the style: sass() line will become preprocess: { style: sass() } in a future version of svelte-loader — see this issue).

    By the way, it looks like you're using an older version of Sapper — there have been some major improvements recently, so it's worth upgrading to 0.9. Unfortunately it does mean making some changes to your project structure (see the migration guide for the details, or reclone sapper-template and copy your routes folder over).