Parcel: Vue.js SASS Template Style Tag (`<style lang="sass">`) Incorrectly Parsed As SCSS

Created on 18 Apr 2018  路  10Comments  路  Source: parcel-bundler/parcel

馃悰 bug report

Some tickets reported similar issues but I have isolated the cause and effect which you can see in my repo https://gitlab.com/enom/parcel-vue-sass

馃帥 Configuration (.babelrc, package.json, cli command)

Run the following:

git clone [email protected]:enom/parcel-vue-sass.git
cd parcel-vue-sass
yarn && yarn dev

The <style lang="sass"> is being parsed as SCSS instead of SASS. This is seems like a Webpack configuration where it's not using the right loader rule.

I unfortunately don't have time to correct this myself.

馃 Expected Behavior

Parcel should parse Vue.js template <style lang="sass"> as SASS

馃槸 Current Behavior

The following error is displayed in console:

馃毃  /var/www/parcel-vue-sass/src/App.vue: Invalid CSS after "#": expected 1 selector or at-rule, was "#app"
    at options.error (/var/www/parcel-vue-sass/node_modules/node-sass/lib/index.js:291:26)

馃拋 Possible Solution

Seems like a missing or misconfigured Webpack loader / rule.

馃敠 Context

App development using Parcel, Vue.js, and SASS

馃捇 Code Sample

See https://gitlab.com/enom/parcel-vue-sass

馃實 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.7.1
| Node | 9.7.1
| npm/Yarn | 1.5.1 (Yarn)
| Operating System | Linux (below)

$ uname -a
Linux vm 4.13.0-38-generic #43-Ubuntu SMP Wed Mar 14 15:20:44 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 17.10
Release:        17.10
Codename:       artful
Bug

Most helpful comment

@DeMoorJasper let type will result in sass not .sass as this.options.rendition.type seems not to be a file extension.
Will adapt this to the following:

let type = this.options.rendition ? this.options.rendition.type : path.extname(this.name).toLowerCase().replace('.', '');
opts.indentedSyntax = typeof opts.indentedSyntax === 'boolean' ? opts.indentedSyntax : type === 'sass';

PR coming!

All 10 comments

I am having the same issue. Is there any way to pass parameter to node-sass while using parcel?

SCSS and SASS are both being run through node-sass.
If anyone with node-sass or sass experience could look into this would be nice

Interestingly enough, if you extract your sass into a separate sass file, and @include it, it works fine

<style lang="sass">
@import 'src/assets/styles/main.sass'
</style>

It just doesn't parse correctly when sass is inline.

It works fine because now the loader knows the file extension (sass) and correctly parse it as indented syntax (as individual sass files works too), so I believe this is Vue loader/Compiler issue.

How would I go isolating this issue further? I have time to dive deeper into this now so I'd like to get this working

Finding a way to use the correct filetype in the sass parser should fix this @enom-infini

Hi all, amazing project!!!!
I think I found a workaround for this, but I'm not so sure it's the correct place where to fix the issue.
Please see:
https://github.com/parcel-bundler/parcel/blob/master/src/assets/SASSAsset.js#L31
At this line opts.indentedSyntax is undefined and evaluates to false, as the file is .vue and not .sass so path.extname(this.name).toLowerCase() === '.sass' is not achieving the wanted result.
The workaround is to add the following if clause right after assigning opts.indentedSyntax (which evaluates always to false in single file vue components).

if (path.extname(this.name).toLowerCase() === '.vue') {
      opts.indentedSyntax = (this.options.rendition.type === 'sass') ? true : false
}

Apparently this.options.rendition.type resolves the correct sass/scss syntax type and I use that to set the correct value for opts.indentedSyntax.
This solved the problem for me, though I'm really new to parcel source code and I feel there's a better way to tackle this.
Happy to help further with a bit of guidance!!
馃摝馃

@MattAndDev Awesome! Seems like you've found the correct solution.

This can also happen on non vue assets (through plugins), that also allow inlining sass in the file.

Could you do a PR that changes this line?

opts.indentedSyntax = typeof opts.indentedSyntax === 'boolean' ? opts.indentedSyntax : path.extname(this.name).toLowerCase() === '.sass';

Into something like this:

let type = this.options.rendition ? this.options.rendition.type : path.extname(this.name).toLowerCase().substring(1);
opts.indentedSyntax = typeof opts.indentedSyntax === 'boolean' ? opts.indentedSyntax : type === 'sass';

@DeMoorJasper Sure, I'm more then happy to help!
Will take a look at your proposal and prepare the PR! 馃檶

@DeMoorJasper let type will result in sass not .sass as this.options.rendition.type seems not to be a file extension.
Will adapt this to the following:

let type = this.options.rendition ? this.options.rendition.type : path.extname(this.name).toLowerCase().replace('.', '');
opts.indentedSyntax = typeof opts.indentedSyntax === 'boolean' ? opts.indentedSyntax : type === 'sass';

PR coming!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

algebraic-brain picture algebraic-brain  路  3Comments

mnn picture mnn  路  3Comments

oliger picture oliger  路  3Comments

davidnagli picture davidnagli  路  3Comments

dotdash picture dotdash  路  3Comments