vuejs / vuepress

📝 Minimalistic Vue-powered static site generator
https://vuepress.vuejs.org
MIT License
22.45k stars 4.78k forks source link

Vuepress does not work with versions of vue-cli and vuetify that use sass 8 #2148

Open davydnorris opened 4 years ago

davydnorris commented 4 years ago

Bug report

The default options supplied for sass-loader break Sass 8, and cannot be overridden in config.js

Steps to reproduce

  1. Create a vuepress project and add the latest Vuetify, which will trigger webpack to use Sass.
  2. Execute npm run build
  3. The process will fail with the error:
    ValidationError: Invalid options object. Sass Loader has been initialised using an options object that does not match the API schema.
     - options has an unknown property 'indentedSyntax'. These properties are valid:
       object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }

What is expected?

The site builds without error

What is actually happening?

The default options set for sass-loader are no longer valid for Sass 8. Instead of { indentedSyntax: true } it is now { sassOptions: { indentedSyntax: true } }

No matter what you do in your config.js, the original property is set because the values in config.js are merged with the options object.

The problem is in @vuepress/core/lib/node/webpack/createBaseConfig.js, line 257: createCSSRule('sass', /\.sass$/, 'sass-loader', Object.assign({ /* indentedSyntax: true*/ }, siteConfig.sass)) Commenting out the offending property in this line (as above), fixes the problem. My suggestion is that instead of merging the config, replace it completely. Then you can use the config.js file to adjust to different Sass versions.

Other relevant information

pisandelli commented 4 years ago

I had a similar issue (I posted a question in stackoverflow with more details)

I was just trying to use the .sass syntax instead of .scss. But always got a blank page.

<template lang="pug">
  h1 Hello World!
</template>

<style lang="sass">
h1
  color: red
</style>

Using lang="scss" everything goes fine.

But when I set lang=sass the browser console shows the same error pointed by @davydnorris.
I tried everything in my config.js but without success. The same with @davydnorris.

After searching a lot, just found a workaround. Downgrade sass-loader from 8.0.2 to version 7.3.1 check here

Now everything renders fine, by I think is not a good solution.

Output of npx vuepress info

Environment Info:

  System:
    OS: Linux 5.3 Ubuntu 19.10 (Eoan Ermine)
    CPU: (8) x64 Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
  Binaries:
    Node: 13.7.0 - /usr/bin/node
    Yarn: 1.21.1 - /usr/bin/yarn
    npm: 6.13.6 - /usr/bin/npm
  Browsers:
    Chrome: Not Found
    Firefox: 72.0.1
  npmPackages:
    @vuepress/core:  1.2.0 
    @vuepress/theme-default:  1.2.0 
    vuepress: ^1.2.0 => 1.2.0 
  npmGlobalPackages:
    vuepress: Not Found

Package.json

"devDependencies": {
    "node-sass": "^4.13.1",
    "pug": "^2.0.4",
    "pug-plain-loader": "^1.0.0",
    "sass-loader": "7.3.1",
    "vuepress": "^1.2.0"
  }
davydnorris commented 4 years ago

Thanks for the reply - I was able to get my vuepress working with Vuetify by doing the following:

  sass: {
    sassOptions: {
      fiber: require('fibers'),
      indentedSyntax: true
    }
  }

After that everything worked perfectly.

EqualMa commented 4 years ago

Finally fix this by overwriting loader options:

module.exports = {
  // ...
  chainWebpack(config, isServer) {
    for (const lang of ["sass", "scss"]) {
      for (const name of ["modules", "normal"]) {
        const rule = config.module.rule(lang).oneOf(name);
        rule.uses.delete("sass-loader");

        rule
          .use("sass-loader")
          .loader("sass-loader")
          .options({
            implementation: require("sass"),
            sassOptions: {
              fiber: require("fibers"),
              indentedSyntax: lang === "sass"
            }
          });
      }
    }
  }
  // ...
}
Lionad-Morotar commented 4 years ago

Finally fix this by overwriting loader options:

module.exports = {
  // ...
  chainWebpack(config, isServer) {
    for (const lang of ["sass", "scss"]) {
      for (const name of ["modules", "normal"]) {
        const rule = config.module.rule(lang).oneOf(name);
        rule.uses.delete("sass-loader");

        rule
          .use("sass-loader")
          .loader("sass-loader")
          .options({
            implementation: require("sass"),
            sassOptions: {
              fiber: require("fibers"),
              indentedSyntax: lang === "sass"
            }
          });
      }
    }
  }
  // ...
}

Thanks, It works

Johnsoct commented 4 years ago

Still having this exact issue running:

Vuepress: 1.4.1 Node-sass: 4.13.1 Sass-loader: 8.0.2

mesqueeb commented 3 years ago

I still have this issue when trying to use sass out of the box. Should we add the official workaround to the documentation? Because now no one can use sass out of the box.

elibolonur commented 3 years ago

It took some time for me to figure out, how to use Vuetify with sass files and not with the build css files. Maybe it is useful for someone else. Thanks @EqualMa's for the solution.

Vuepress: 1.8.2 sass: 1.32.0 sass-loader: 10.1.1 vue: 2.6.12 vuetify: 2.4.3 vuetify-loader: 1.6.0

// config.js
// needed to load vuetify components
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')
module.exports = {

  chainWebpack(config, isServer) {
    // use vuetify-loader to load all vuetify components
    config.plugin('vuetify').use(VuetifyLoaderPlugin);

    // overwrite loader options
    for (const lang of ["sass", "scss"]) {
      for (const name of ["modules", "normal"]) {
        const rule = config.module.rule(lang).oneOf(name);
        rule.uses.delete("sass-loader");
        const end = lang === 'sass' ? "'" : "';"

        rule
          .use("sass-loader")
          .loader("sass-loader")
          .options({
            implementation: require("sass"),
            sassOptions: {
              fiber: require("fibers"),
              indentedSyntax: lang === "sass"
            },
            // here I needed to add a global variables files which also imports ~vuetify/src/styles/styles.sass inside,
            // for overwriting Vuetify framework variables
            additionalData: `
                @import '~@/styles/variables.scss${end}
            `
          });
      }
    }
  },
  head: [
    [
      'link',
      {
        rel: 'stylesheet',
        href: 'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900'
      }
    ]
  ]
}

enhanceApp.js

import Vuetify from 'vuetify/lib/framework'

export default ({
  Vue,
  options,
  router,
  siteData
}) => {
  Vue.use(Vuetify)
  options.vuetify = new Vuetify({
    theme: {
      ...
    },
    icons: {
      ...
    },
    etc.
  })
}
ikarosu commented 3 years ago

一路从11.x降到了7.x才能用,一年过去了也没解决,真的坑

BPerry24 commented 3 years ago

This is still not working. @elibolonur solution did not work for me. Installing fibers just completely prevented my app from starting. I'm not even sure why I need coroutines for this anyway??? Without fibers, the app started but I nothing loaded because Vuetify components could not find the required stylesheet to import:

SassError: Can't find stylesheet to import.
  ╷
2 │                     @import '~@/styles/variables.scss'
  │                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  ╵
  node_modules/vuetify/src/components/VCard/VCard.sass 2:29  root stylesheet

Maybe the above error is because I'm not using fibers but like I said, fibers literally prevented the app from starting so not really sure where to go from here.

Update, the only way I was able to get the aforementioned solution to work was to downgrade sass-loader to 7.3.1 - note that I've still been unable to get the default icons (from MDI) to render in my app.