Skip to content
This repository has been archived by the owner on Jan 18, 2022. It is now read-only.

Needs an extra plugin for .css/.scss/.sass (with Vue.js 3 beta) #364

Open
akauppi opened this issue Jun 28, 2020 · 21 comments
Open

Needs an extra plugin for .css/.scss/.sass (with Vue.js 3 beta) #364

akauppi opened this issue Jun 28, 2020 · 21 comments
Milestone

Comments

@akauppi
Copy link

akauppi commented Jun 28, 2020

Version

6.0.0-beta.6

Reproduction link

https://stackoverflow.com/questions/62384191/rollup-vue-and-buble-unexpected-token-in-scss-file/62625441#62625441

Steps to reproduce

6.0.0-beta.6. (was unable to fill that into the "version" field)

As @P-Seebauer mentions here,

the css needs an extra rollup css plugin, this is awkward because the css-only plugin seems like the wrong choice at first (“i have scss”),

That ticket is closed, but this anomaly remains. Thus the creation of this ticket, to track it.

Setup

Vue.js 3 (beta), e.g. 3.0.0-beta.15
Rollup 2.16.1
rollup-plugin-vue 6.0.0-beta.6

Expectation:

It is easy to build a Vue.js 3 (beta) project, using Rollup.

Actual:

One gets the following error message, and it is not clear a) what causes it, b) how to get rid of it:

$ npx rollup -c
[!] Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang.css (2:0)

First aid

The way around this was suggested by @P-Seebauer's comment (above). I added rollup-plugin-scss to the mix, and it seems to please Rollup. The build proceeds. It handles both .scss and .css files.

However, since Vue.js is expected to handle these, asking application developers to add such a plugin seems unnecessary.

Real fix

I cannot say, whether this falls to Vue.js 3 beta or the rollup-plugin-vue (also beta) domain. I do hope it gets ironed out, before the both are out of their betas.

What is expected?

Things "just work", without needing to add rollup-plugin-scss, to handle Vue styles.

What is actually happening?

One needs to add that plugin.


I can be of assistance in testing.

@akauppi
Copy link
Author

akauppi commented Jul 7, 2020

To reproduce:

$ git clone git@github.com:akauppi/GroundLevel-es6-firebase-web.git
$ cd GroundLevel*
  • Check the README for setting up the project
$ npm install
$ npm run build

That should pass. Now edit rollup.config.prod.js and switch off:

const scssHackNeeded = true;   // <-- make it false

Repeat.

$ npm run build
...
src/main.js → public/dist...
[!] Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang.css (2:0)
Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)

@XiongAmao
Copy link

Seems like vite can handle scss/sass correctly.

@znck znck added this to the Zero Issues milestone Oct 22, 2020
@kleinfreund
Copy link

Is there a workaround that allows one to process a Vue SFC just like before (i.e. prior to version 6 releases)? In my rollup.config.js, I have two build configurations:

  • using vuePlugin() without any options to keep the SFC’s style block contents as part of the generated JS bundle
  • using vuePlugin({ css: false }) and a custom rollup plugin to discard the style block contents entirely

Adding another plugin processor like the one from rollup-plugin-scss after the vuePlugin() step for scenario 1 doesn’t produce a desirable result as it generates a separate CSS file.

Also, the css option seems to be completely missing from rollup-plugin-vue now. Was it deprecated or replaced?

@NicolasRichel
Copy link

Hi @kleinfreund .

We recently face the same issue trying to make our Vue 2 component library "Vue 3 compliant".

Your problem looks very similar to this one, so I will reproduce my answer here as this issue is used as a tracker.

Using rollup-plugin-vue v6.0.0 we were able to inject CSS in Javascript by adding the rollup-plugin-postcss plugin with the following config:

...
import vue from 'rollup-plugin-vue'; // v6.0.0
import postcss from 'rollup-plugin-postcss'; // v4.0.0

export default {
  input: ...,
  output: ...,
  plugin: [
    ...
    vue({
      preprocessStyles: true
    }),
    postcss()
  ]
}

Notes: the rollup-plugin-postcss needs postcss as a peer dependecy.

Hope this helps. :-)

@jdfwarrior
Copy link

jdfwarrior commented Jan 5, 2021

I'm running into the same issue. I'm trying to compile a component or plugin into a standalone piece that I can import without needing to go through a bundler. I'm attempting to make a way to load extensions into an electron app built with vue 3. I'm using an absolutely bare minimal component. It's just a template with a single paragraph tag and a style tag that sets the background of that paragraph tag. the vue plugin seems to (according to the docs) support parsing the style tag but when I try it, I get:

[!] Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)

and it points at the opening curly in the css.

Using the postcss plugin as mentioned above does seem to make it work though.

@mnlipp
Copy link

mnlipp commented Feb 28, 2021

I've been sorting out the [!] Error: Unexpected token problem for a day now. I think the root cause for this issue is described in #410 (despite its title still valid for 6.0.0).

@DaanDL
Copy link

DaanDL commented Mar 29, 2021

@NicolasRichel Unfortunately, this doesn't seem to work for scoped scss style blocks in SFC's. It requires rollup-plugin-scss, but that plugin generates a .css and all scoping gets lost..

@SvenBudak
Copy link

I struggle with the same problem. I tryed also the solution from NicolasRichel but no way. Its important to keep the css inside the component scoped. And an aditional main css file is needed which contains scss variables and functions they have to be used inside the vue components. But this file should get loaded only one time. i have really no idea how to start here.

@DaanDL
Copy link

DaanDL commented Apr 7, 2021

@SvenBudak
I gave up, and ditched rollup for Vite 2 (which uses rollup with a specific set of plugins in the background). It all works now as intended without much config.

@mnlipp
Copy link

mnlipp commented Apr 7, 2021

@DaanDL
But Vite 2 is so much more (and complex). I never figured out how to get it working. Do you have a simple configuration that only does what rollup-plugin-vue is supposed to do (in my case: create a browser-module with the Vue 3 components, triggered by some simple node.js script invocation).

@SvenBudak
Copy link

Dear god... Sience 2 weeks i try to generate a library for vue that is just working 😂 I have experiance with this in angular. but i cant find any helpfull for vue. Its a mess...

@DaanDL
Copy link

DaanDL commented Apr 8, 2021

@DaanDL
But Vite 2 is so much more (and complex). I never figured out how to get it working. Do you have a simple configuration that only does what rollup-plugin-vue is supposed to do (in my case: create a browser-module with the Vue 3 components, triggered by some simple node.js script invocation).

I purely use Vite for library builds, since I'm building a component library. My vite.config looks like this:

`import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
// Make sure we can do @/components/xxx style imports
alias: [
{
find: '@',
replacement: path.resolve(__dirname, 'src')
}
],
// Enable library mode: only create ES builds
build: {
sourcemap: true,
lib: {
entry: path.resolve(__dirname, 'bundler/entry.js'),
name: 'GalleryComponentLibrary',
formats: ['es']
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: ['vue'],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
vue: 'Vue'
}
}
}
}
});`

@mnlipp
Copy link

mnlipp commented Apr 8, 2021

@DaanDL Thanks. Going to try this in one of my next projects. Currently (only using CSS, not SCSS or SASS) things work for me with "plain" rollup.

@plinionaves
Copy link

Thanks @NicolasRichel , it worked perfectly for me!

Just complementing, for those who need to add something from SCSS in all components it looks like this:

...
import vue from 'rollup-plugin-vue'; // v6.0.0
import postcss from 'rollup-plugin-postcss'; // v4.0.0

export default {
  input: ...,
  output: ...,
  plugin: [
    ...
    vue({
      preprocessStyles: true,
      preprocessOptions: {
        scss: {
          additionalData: `@import 'src/styles/abstract/mixins';`,
        },
      }
    }),
    postcss()
  ]
}

@SvenBudak
Copy link

SvenBudak commented Apr 14, 2021

@plinionaves i have this config:

// rollup.config.js
import fs from 'fs';
import path from 'path';
import vue from 'rollup-plugin-vue';
import alias from '@rollup/plugin-alias';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import babel from '@rollup/plugin-babel';
import {terser} from 'rollup-plugin-terser';
import postcss from 'rollup-plugin-postcss'; // v4.0.0
import minimist from 'minimist';

// Get browserslist config and remove ie from es build targets
const esbrowserslist = fs.readFileSync('./.browserslistrc')
    .toString()
    .split('\n')
    .filter((entry) => entry && entry.substring(0, 2) !== 'ie');

const argv = minimist(process.argv.slice(2));

const projectRoot = path.resolve(__dirname, '..');

const baseConfig = {
    input: 'src/entry.ts',
    plugins: {
        preVue: [
            alias({
                entries: [
                    {
                        find: '@',
                        replacement: `${path.resolve(projectRoot, 'src')}`,
                    },
                ],
            }),
        ],
        replace: {
            'process.env.NODE_ENV': JSON.stringify('production'),
        },
        vue: {
            // css: true,
            preprocessStyles: true,
            preprocessOptions: {
                scss: {
                    additionalData: `@import 'src/styles';`,
                },
            },
            template: {
                isProduction: true,
            },
        },
        postcss,
        postVue: [
            resolve({
                extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
            }),
        ],
        babel: {
            exclude: 'node_modules/**',
            extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
            babelHelpers: 'bundled',
        },
    },
};

// ESM/UMD/IIFE shared settings: externals
// Refer to https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
const external = [
    // list external dependencies, exactly the way it is written in the import statement.
    // eg. 'jquery'
    'vue',
];

// UMD/IIFE shared settings: output.globals
// Refer to https://rollupjs.org/guide/en#output-globals for details
const globals = {
    // Provide global variable names to replace your external imports
    // eg. jquery: '$'
    vue: 'Vue',
};

// Customize configs for individual targets
const buildFormats = [];
if (!argv.format || argv.format === 'es') {
    const esConfig = {
        ...baseConfig,
        input: 'src/entry.esm.ts',
        external,
        output: {
            file: 'dist/mrm-vue-ui.esm.js',
            format: 'esm',
            exports: 'named',
        },
        plugins: [
            replace(baseConfig.plugins.replace),
            ...baseConfig.plugins.preVue,
            vue(baseConfig.plugins.vue),
            ...baseConfig.plugins.postVue,
            babel({
                ...baseConfig.plugins.babel,
                presets: [
                    [
                        '@babel/preset-env',
                        {
                            targets: esbrowserslist,
                        },
                    ],
                ],
            }),
            commonjs(),
        ],
    };
    buildFormats.push(esConfig);
}

if (!argv.format || argv.format === 'cjs') {
    const umdConfig = {
        ...baseConfig,
        external,
        output: {
            compact: true,
            file: 'dist/mrm-vue-ui.ssr.js',
            format: 'cjs',
            name: 'MrmVueUi',
            exports: 'auto',
            globals,
        },
        plugins: [
            replace(baseConfig.plugins.replace),
            ...baseConfig.plugins.preVue,
            vue({
                ...baseConfig.plugins.vue,
                template: {
                    ...baseConfig.plugins.vue.template,
                    optimizeSSR: true,
                },
            }),
            ...baseConfig.plugins.postVue,
            babel(baseConfig.plugins.babel),
            commonjs(),
        ],
    };
    buildFormats.push(umdConfig);
}

if (!argv.format || argv.format === 'iife') {
    const unpkgConfig = {
        ...baseConfig,
        external,
        output: {
            compact: true,
            file: 'dist/mrm-vue-ui.min.js',
            format: 'iife',
            name: 'MrmVueUi',
            exports: 'auto',
            globals,
        },
        plugins: [
            replace(baseConfig.plugins.replace),
            ...baseConfig.plugins.preVue,
            vue(baseConfig.plugins.vue),
            ...baseConfig.plugins.postVue,
            babel(baseConfig.plugins.babel),
            commonjs(),
            terser({
                output: {
                    ecma: 5,
                },
            }),
        ],
    };
    buildFormats.push(unpkgConfig);
}

// Export config
export default buildFormats;

And i get this error:

 error  in ./src/lib-components/content-wrapper.vue?vue&type=style&index=0&id=41cf14b2&scoped=true&lang=scss&

Syntax Error: TypeError: this.getOptions is not a function


 @ ./node_modules/vue-style-loader??ref--8-oneOf-1-0!./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/c
js.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/lib-components/content-wrapper.vue?vue&type=style&index=0&id=41cf14b2&scoped=true&lang=scss& 4:14-470 15:3-20:5 16:22-478
 @ ./src/lib-components/content-wrapper.vue?vue&type=style&index=0&id=41cf14b2&scoped=true&lang=scss&
 @ ./src/lib-components/content-wrapper.vue
 @ ./src/lib-components/index.ts
 @ ./src/entry.esm.ts
 @ ./dev/serve.ts
 @ multi (webpack)-dev-server/client?http://192.168.188.61:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./dev/serve.ts

He dont like the scss in: <style scoped lang="scss"> how did you solved this?

@plinionaves
Copy link

plinionaves commented Apr 14, 2021

Hi @SvenBudak

I noticed that in your baseConfig it was missing to call postcss as a function:

         vue: {
            // css: true,
            preprocessStyles: true,
            preprocessOptions: {
                scss: {
                    additionalData: `@import 'src/styles';`,
                },
            },
            template: {
                isProduction: true,
            },
        },
        postcss(), // <-- here
        postVue: [
            resolve({
                extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
            }),
        ],

If you need it too, here's the complete config that worked for me: rollup.cofig.js

@SvenBudak
Copy link

SvenBudak commented Apr 14, 2021

Thanks @plinionaves

But unfortunately it still doesn't work even with your config. I still get the same error:

error in ./src/lib-components/content-wrapper.vue?vue&type=style&index=0&id=41cf14b2&scoped=true&lang=scss&

It is a very simple component:

<template>
  <section :id="addId" :class="[addClass, gradient, theme]" :style="{backgroundColor: backgroundColor}">
    <div class="inner" :style="{maxWidth: maxWidth + 'px', 'padding': disablePadding ? '0' : null}">
      <slot></slot>
    </div>
  </section>
</template>

<script lang="ts">
import Vue from "vue";

export default /*#__PURE__*/Vue.extend({
  name: 'ContentWrapper',
  props: {
    addId: {
      type: String
    },
    addClass: {
      type: String
    },
    theme: {
      type: String
    },
    backgroundColor: {
      type: String
    },
    gradient: {
      type: String
    },
    maxWidth: {
      type: Number
    },
    disablePadding: {
      type: Boolean,
      default: false
    }
  }
});
</script>

<style scoped lang="scss">

.light {
  color: blue;
}

.dark {
  color: red;
}

</style>

@973782523
Copy link

Thanks @plinionaves

But unfortunately it still doesn't work even with your config. I still get the same error:

error in ./src/lib-components/content-wrapper.vue?vue&type=style&index=0&id=41cf14b2&scoped=true&lang=scss&

It is a very simple component:

<template>
  <section :id="addId" :class="[addClass, gradient, theme]" :style="{backgroundColor: backgroundColor}">
    <div class="inner" :style="{maxWidth: maxWidth + 'px', 'padding': disablePadding ? '0' : null}">
      <slot></slot>
    </div>
  </section>
</template>

<script lang="ts">
import Vue from "vue";

export default /*#__PURE__*/Vue.extend({
  name: 'ContentWrapper',
  props: {
    addId: {
      type: String
    },
    addClass: {
      type: String
    },
    theme: {
      type: String
    },
    backgroundColor: {
      type: String
    },
    gradient: {
      type: String
    },
    maxWidth: {
      type: Number
    },
    disablePadding: {
      type: Boolean,
      default: false
    }
  }
});
</script>

<style scoped lang="scss">

.light {
  color: blue;
}

.dark {
  color: red;
}

</style>

Did you solve it in the back? I also meet this problem, do not know how to solve it

@SvenBudak
Copy link

SvenBudak commented Jun 8, 2021

No i was not able to solve it... But i asked in the vue Issue Board for a documentation for this: vuejs/docs#1060

@973782523
Copy link

No i was not able to solve it... But i asked in the vue Issue Board for a documentation for this: vuejs/docs-next#1060

rollup-plugin-styles
Is the JS import form can be solved, I solved

@bowencool
Copy link

bowencool commented Jul 7, 2021

here is my config

    plugins: [
      vue(),
      postcss({
        extract: true,
      }),
    ],

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests