Search code examples
node.jswebpackvuejs2webpack-2node-sass

Webpack-simple + vue-cli with SASS - Can't compile?


I set up a simple project with vue-cli and webpack-simple using the default CLI settings and made sure that 'Y' was selected when asked whether I wanted to use SASS.

First, folder structure pic:

enter image description here

I created a main.scss file in the ./src/scss directory and added the following simple scss syntax to the file:

$primary-color: rgb(173, 16, 16);

Then, in my App.vue template, I have it like so:

<style lang="scss" scoped>

h1, h2 {
  font-weight: normal;
  color: $primary-color;
}

</style>

In my main.js file, I made sure to import the main.scss file like so:

import './scss/main.scss'

When running npm run dev, I get the following compiling error:

Failed to compile.

./node_modules/css-loader!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-04c2046b","scoped":true,"hasInlineConfig":false}!./node_modules/sass-loader/lib/loader.js!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/App.vue
Module build failed: 
undefined
        ^
      Undefined variable: "$primary-color".



    in D:\Users\medranns\Desktop\sasswebpack\src\App.vue (line 46, column 10)
 @ ./node_modules/vue-style-loader!./node_modules/css-loader!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-04c2046b","scoped":true,"hasInlineConfig":false}!./node_modules/sass-loader/lib/loader.js!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/App.vue 4:14-316 13:3-17:5 14:22-324
 @ ./src/App.vue
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js

Here's what my webpack.config.js file looks like:

var path = require('path')
var webpack = require('webpack')

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ],
      },
      {
        test: /\.scss$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader'
        ],
      },
      {
        test: /\.sass$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader?indentedSyntax'
        ],
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
            // the "scss" and "sass" values for the lang attribute to the right configs here.
            // other preprocessors should work out of the box, no loader config like this necessary.
            'scss': [
              'vue-style-loader',
              'css-loader',
              'sass-loader'
            ],
            'sass': [
              'vue-style-loader',
              'css-loader',
              'sass-loader?indentedSyntax'
            ]
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true,
    overlay: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}

And package.json snippet:

"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"node-sass": "^4.7.2",
"sass-loader": "^6.0.6",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1"

}

I've followed the docs and still did a bit of searching around, but I am still unsure how to fix. Thanks for any leads!


Solution

  • i use scss in a vue project that is growing from webpack-simple boilerplate

    vue-init webpack-simple test-scss
    

    Try below steps to setup scss in vue project

    After installing a basic setup using above command, install below npm packages

    npm install sass-loader node-sass style-loader --save-dev 
    

    In webpack.config.js under rules array include below loaders

    rules:[ 
    ...,
    ...,
    {
       test: /\.scss$/,
       use: [{
           loader: "style-loader" // creates style nodes from JS strings
       }, 
       {
           loader: "css-loader" // translates CSS into CommonJS
       }, 
       {
           loader: "sass-loader" // compiles Sass to CSS
       }]
    }
    ]
    

    What was done upto this point? Configurations that will enable compiler to convert scss to css are done.

    Now import .scss into main.js

    import Vue from 'vue';
    import App from './App.vue';
    
    import './style.scss';
    
    new Vue({
      el: '#app',
      render: h => h(App)
    });
    

    This is my folder structure

    enter image description here

    You are now ready to compile the object oriented css code in style.scss to CSS

    To use scss in component level scope lang="scss" must be specified in <style> tag

    App.vue
    <style lang="scss">
        $override-color : green;
    
        div {
            color: $override-color;
        }
    </style>
    

    Refer this manual for more insights on this topic . Looking forward for your feedback.