How to configure Dart Sass native executable (dart VM) in vue.config.js with sass-loader?

2.3k views Asked by At

I am working on a SPA application built using vue.js 2.6, bootstrap-vue 2.8, sass 1.34 (dart-sass) as preprocessor and sass-loader 10.2.

With the time the project is getting quite big and we've switched from Node-Sass to Dart-Sass (as node-sass is deprecated).

Unfortunately, we're now getting performance issues when building or developping on the project, as it now takes approximately 15 minutes to create a new built, and we're often encountering high memory usage in development.

After reading this article, I figure out using the speed-measure-webpack-plugin that 95% of the compilation time is due to css compilation purposes as most of the SMP stacktrace contains such several entries:

mini-css-extract-plugin, and 
css-loader, and 
vue-loader, and 
postcss-loader, and 
sass-loader, and 
cache-loader, and 
vue-loader took 2 mins, 40.68 secs

Removing the bootstrap imports on the main app.scss file really improve performance, and totally removing the sass compilation removes 95% of the time spent.

Reading this page on dart-sass Github, I understood that the dart Sass native executable is more powerful than the dart sass on node.js version.

Here is my vue.config.js:

process.env.VUE_APP_VERSION = require('./package.json').version
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')

module.exports = {
  runtimeCompiler: true,
  devServer: {
    disableHostCheck: true
  },
  css: {
    loaderOptions: {
      scss: {
        implementation: require('sass'), // This line must in sass option
        additionalData: `@import "@/assets/scss/app.scss";`
      }
    }
  },
  chainWebpack: config => {
    config.module
      .rule('eslint')
      .use('eslint-loader')
      .options({
        fix: false
      })

    config.plugin('speed-measure-webpack-plugin')
      .use(SpeedMeasurePlugin)
      .end()
  }
}

If I've well understand, using this configuration the Dart Sass on Node.js is used during compilation.

I've setup the dart-sass standalone version from this page and I can execute it on the command line, but I don't actually know if it's possible to run it in the webpack compilation instead of the Node.js version ? I've searched on the vue.js, webpack and sass-loader documentations but without success.

EDIT:

The compilation time issue described in this post was due to the import of a file containing the css of the whole app in additionalData (additionalData: @import "@/assets/scss/app.scss";). We did this to use Bootstrap variables in several components but it's clearly not the good way to do it. If you wish to use bootstrap variables in vue components the best option might be to import a file containing your custom and bootstrap variables on every components requiring it, like:

<style lang="scss" scoped>
@import '@/assets/scss/bootstrap';
</style>
1

There are 1 answers

2
Michal Levý On BEST ANSWER

Using Dart VM from webpack/sass-loader is probably not possible

I had a feeling (confirmed by comments) that you are including too much with additionalData: '@import "@/assets/scss/app.scss";'

additionalData is pre-pended to any style compilation - which in case of Vue + sass-loader means that everything inside @/assets/scss/app.scss is compiled every time there is a <style> block inside Vue SFC (as each <style> block is compiled separately)

additionalData is useful for variables you need inside most of the components. Things such primary color, text sizes etc. NOT to include some global/dependency styles!

Just move most of the SASS/CSS imports to your main.js or App.vue or simply remove additionalData and your app build time will improve considerably...