Vue-cli: Add a vue-cli Configure Sass-Resources-Loader Example

Created on 21 Mar 2018  ·  16Comments  ·  Source: vuejs/vue-cli

What problem does this feature solve?

I read the vue-cli docs about sass-resources-loader section and can not understand how to configure the vue-cli project for this.
After some codes reading,I write these codes for that loader to work out:

//vue.config.js
var path = require('path');
module.exports = {
    chainWebpack: config => {
        config.module
            .rule('vue')
            .use('vue-loader')
            .tap(options => {
                var scssResourceLoader = {
                    loader: 'sass-resources-loader',
                    options: {
                        resources: path.resolve(__dirname, 'src/assets/_variables.scss')
                    }
                };
                options.loaders.scss.push(scssResourceLoader);
                return options;
            });
    }
}

I hope this will help others.

What does the proposed API look like?

...

Most helpful comment

// vue.config.js
module.exports = {
  css: {
    loaderOptions: {
      // 给 sass-loader 传递选项
      sass: {
        // @/ 是 src/ 的别名
        // 所以这里假设你有 `src/variables.scss` 这个文件
        data: `@import "@/variables.scss";`
      }
    }
  }
}

All 16 comments

Thanks! Soon it will be a lot easier with the next version of vue-loader. 😉

Yeah,I hope the wiki for webpack config could be a bit more easier for new user.Because of the webpack is a bit complex to use and it will make the vue-cli complex to use too.

sorry to hijack this issue, but it seems like there is a lot of confusion about how to configure stuff in the new vue-cli.

i thought it would be relatively easy to configure a new project the same way i had the old one configured with cssSourceMap: true, but i can't get it to work properly. maybe someone can point me in the right direction...

// vue.config.js
var merge = require('webpack-merge')

module.exports = {
  chainWebpack: config => {

    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options =>
        merge(options, {
          cssSourceMap: true,
          extractCSS: true,
        })
      )
  }
}

i tried a bunch of other configuration options on the loaders, but it all resulted in css still included via style tags.

Maybe it works, when you add a "return options" after your merge, like @vaxilicaihouxian did.

@Akryum Will it then be possible to set / overwrite file names and paths for the different file types?
Currently I like to adjust the paths for css, font, image, media and html files to something different than "css", "font", "img" and "media". Additionally I would like to remove the hashes of the names, because I want to use the generated codes inside a cms system with its special naming conventions and not for a SPA.

@mediaessenz the return is implicit, it's also working, i can see that by checking the diff of vue inspect > config_template.js

I got some similar running with this syntax:

module.exports = {
    chainWebpack: config => {
        config.module.rule('images').use('url-loader')
            .tap(options =>
                Object.assign({}, options, { name: 'Images/[name].[ext]' })
            )
        config.module.rule('svg').use('file-loader')
            .tap(options =>
                Object.assign({}, options, { name: 'Images/[name].[ext]' })
            )
        config.module.rule('media').use('url-loader')
            .tap(options =>
                Object.assign({}, options, { name: 'Media/[name].[ext]' })
            )
        config.module.rule('fonts').use('url-loader')
            .tap(options =>
                Object.assign({}, options, { name: 'Fonts/[name].[ext]' })
            )
        config.plugin('extract-css')
            .tap(([options, ...args]) => [
                Object.assign({}, options, { filename: 'Css/[name].css' }),
                ...args
            ])
    }
}

Maybe this help you @phoet in any kind.
The problem I've not already fixed is, that this configuration is assigned in development and production mode.
If you enter vue inspect in the console, you will get the configuration for development mode, I think.
If you enter vue inspect --mode productionfrom production.

@phoet
or you just try this official parameters:

module.exports = {
    productionSourceMap: true,
    css: {
        // extract CSS in components into a single CSS file (only in production)
        extract: true,

        // enable CSS source maps?
        sourceMap: true
    }
}

You can found more options here:
@vue/cli-service/lib/options.js

@phoet @mediaessenz

The cssSourceMap depends on the plugin * optimize-css-assets-webpack-plugin * in vue-cli project.
see @vue/cli-service/lib/config/prod.js :

//optimize CSS (dedupe)
      webpackConfig
        .plugin('optimize-css')
        .use(require('optimize-css-assets-webpack-plugin'), [{
          cssProcessorOptions: options.productionSourceMap && options.cssSourceMap
            ? { safe: true, map: { inline: false } }
            : {safe: true }
        }])

options.cssSourceMap can not set via the vue.config.js file.So it always return {safe:true}

Then there is no css sourcemap in the output file.

PS:
If you set options.cssSourceMap=true ,it will just generate a sourcemap for you base on the Extract-Text-Plugin output. I think the vue-cli use this optimize plugin it's that they don't need source map for css on the production env.

@mediaessenz @vaxilicaihouxian

Hello guys, very good your demonstrations I have a doubt how I could make the project when it is generated to production does not put as relative path to the root because in the server where I will upload it will be a subfolder e tested with baseUrl: './' it works so that the files js, css and images remain with "./" but the error is now generated in the final css file because it puts the paths of the fonts and background images as './' and I want that I stay as in development ../ because I need a folder to be returned

any update ?

@andercard baseUrl is what webpack will use at compile time to generate the path to your assets in the built code. For example, you can put /my-subfolder/ and in the code loaded in the user browser, assets will be loaded from the /my-subfolder/<path-to-asset> URL. You can also put an origin (useful when using a CDN): baseUrl: 'https://my-cdn.com/assets/'.

@andercard If you have an issue which isn't related to this thread please open a new one.

We'll close this for now because we are upgrading to vue-loader 15 soon, which will make this a lot easier.

// vue.config.js
module.exports = {
  css: {
    loaderOptions: {
      // 给 sass-loader 传递选项
      sass: {
        // @/ 是 src/ 的别名
        // 所以这里假设你有 `src/variables.scss` 这个文件
        data: `@import "@/variables.scss";`
      }
    }
  }
}

// note: in sass-loader v8
prependData: @import "~@/variables.sass"

Was this page helpful?
0 / 5 - 0 ratings