Giter Club home page Giter Club logo

fast-sass-loader's Introduction

fast-sass-loader

Node.js CI

Blazingly fast sass loader for webpack.

Tips: using with fast-css-loader you will get more than 10 times css build performance

Features:

fast sass loader for webpack. 5~10 times faster than sass-loader, and support url resolve.

version 2.x notes

Since libsass has been deprecated, fast-sass-loader will use sass instead of node-sass, you can use options.implement to specify any compatible sass compiler.

vs sass-loader

Features fast-sass-loader sass-loader
Performance Fast (5~10 times) Slow
Sass Dedupe ×
Url Resolve × (need resolve-url-loader, it's buggy)
Loader Config ×
Source Map ×
Internal Cache ×

Performance

performance benchmark (run npm run perf):

image

Since the sass-loader doesn't dedupe repeated sass files, the result will be very very large (6.95MB!!!), and the total compile time takes 64.9 seconds (nearly 6 times longer than fast-sass-loader).

Why fast-sass-loader is faster than sass-loader ?

  1. Support sass file dedupe, so node-sass won't compile same file repeatedly, the performance improvement is s ignificant when your sass files number grows very large.
  2. Before node-sass compile, fast-sass-loader will merge all sass files into a single file, so node-sass only need to compile one large file, it's faster than @importer of libsass.
  3. The internal cache will store all result for every entry, only compile sass when related file changed.

Install

install by npm:

npm install fast-sass-loader --save-dev

and you need install node-sass and webpack as peer dependencies.

Configuration

webpack 2, 3 and 4:

{
  module: {
    rules: [
      {
        test: /\.(scss|sass)$/,
        use: [
          'css-loader',
          {
            loader: 'fast-sass-loader',
            options: {
              includePaths: [ ... ]
            }
          }
        ]
      },
      // other loaders ...
    ]
  }
}

webpack 1:

{
  module: {
    loaders: [
      {
        test: /\.(scss|sass)$/,
        loader: 'css!fast-sass'
      },
      // other loaders ...
    ]
  }
}

Options

implementation

since version 2.x, fast-sass-loader use dart-sass (npm sass) instead of original node-sass, if you want use node-sass please use this options to modify.

{
  loader: 'fast-sass-loader',
  options: {
    implementation: require('node-sass')
  }
}

includePaths:

An array of paths that node-sass can look in to attempt to resolve your @import declarations. When using data, it is recommended that you use this.

data:

If you want to prepend Sass code before the actual entry file, you can set the data option. In this case, the loader will not override the data option but just append the entry's content. This is especially useful when some of your Sass variables depend on the environment:

{
    loader: "fast-sass-loader",
    options: {
        data: "$env: " + process.env.NODE_ENV + ";"
    }
}

Please note: Since you're injecting code, this will break the source mappings in your entry file. Often there's a simpler solution than this.

transformers:

If you want to import files that aren't basic Sass or css files, you can use the transformers option. This option takes an array of transformer entries, each with a list of file extensions and a tranform function. If an imported file's extension matches one of the transformers' extensions, the file contents will be passed to the corresponding transform function. Your transform function should return a sass string that will be directly written into your compiled Sass file. This is especially useful if you use .json files to share your basic styles across platforms and you'd like to import your .json files directly into your Sass.

{
    loader: "fast-sass-loader",
    options: {
        transformers: [
            {
                extensions: [".json"],
                transform: function(rawFile) {
                    return jsonToSass(rawFile);
                }
            }
        ]
    }
}

outputStyle:

The outputStyle option is passed to the render method of node-sass. See node-sass OutputStyle. This can be used to create smaller css files if set to "compressed".

resolveURLs:

By default fast-sass-loader resolves and rewrites paths inside url(). This behavior can be turned off with resolveURLs: false option so all URLs will remain intact.

Warning

Mixing import .scss and.sass file is not allowed

Since fast-sass-loader will parse @import and merge all files into single sass file, you cannot import .scss file from .sass (or opposite).

For example:

// file: entry.scss
@import "path/to/file.sass";  // cannot import `path/to/file.sass` in a `.scss` file

body {
  background: #FFF;
}

Avoid same variable name in different sass files

Since fast-sass-loader will dedupe sass file, later imported file will be ignored. Using same variable name in different sass fill would produce unexpected output.

For example (compile entry.scss with fast-sass-loader):

// a.scss
$foobar: #000;
// b.scss
@import "a.scss";
$foobar: #AAA;

h1 { color: $foobar; }
// entry.scss
@import "b.scss";
@import "a.scss"; // this file will be ignore: $foobar === #AAA

h2 { color: $foobar; }

// will output:
// h1 { color: #AAA; }
// h2 { color: #AAA; }

You can use variable prefix to bypass.

Avoid nested @import in sass rules

fast-sass-loader doesn't support @import statement in sass rules, for example:

.a {
  @import 'group'
}

.b {
  @import 'group'
}

you should wrap the rules that you want to import with mixin, then include them in your .a { ... } or .b { ... }

License

MIT

fast-sass-loader's People

Contributors

andreyvolokitin avatar bd041556 avatar extempl avatar hugmanrique avatar jan-rycko avatar mnasyrov avatar ngryman avatar nrueckmann avatar ryanwholey avatar yibn2008 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fast-sass-loader's Issues

How to add resolve paths (webpack 2)

What would be the equivalent with fast-sass-loader than the includePaths option in sass-loader?

{
    loader: 'sass-loader',
    options: {
        sourceMap: settings['source-maps'],
        includePaths: [bourbon, neat]
    }
}

Unable to load node_modules lib with import

Sass loader works when doing @import "~bulma" with following webpack4 config:
{ test: /\.(sass|css)$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'sass-loader' } ] },

fast-sass-loader does not, switching out sass-loader with fast-sass-loader ends up with fast-sass-loader not being able to resolve ~bulma.

Bug or am I missing some config? I've tried added options includePaths with path.resolve('node_modules') but still same result in fast-sass-loader.

Trying to get Fast Sass Loader working

I'm using react-static site generator which extends webpack's config. Was hoping you could give me some insight as to what would need to change here to use this loader.

function getStyleLoader (stage) {
  let loader;
  if (stage === 'dev') {
    loader = {
      test: /\.(sc|sa|c)ss$/,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            importLoaders: 2,
            autoprefixer: false,
            minimize: false,
            sourceMap: true
          }
        },
        'sass-loader'
      ]
    };
  } else {
    loader = {
      test: /\.(sc|sa|c)ss$/,
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2,
              autoprefixer: false,
              minimize: true,
              sourceMap: true
            }
          },
          'sass-loader'
        ]
      })
    };
  }
  return loader;
}

Wrong path converted in Windows environment.

Hi yibn2008,

I got a issues with a setup like this:

const devServerPort = 8100;
const extractCSS =  new ExtractTextPlugin('[name].[chunkhash].css');
const config = {
      context: this.context,
      entry: {app: 'index.js'},
      output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: env === 'development' ? `http://localhost:${devServerPort}/` : this.publicPath,
        filename: '[name].[hash].js',
        chunkFilename: '[name].[chunkhash:8].js'
      },
      resolve: {
        extensions: ['.js', '.jsx'],
        modules: ['node_modules', '/app/vendors'],
        alias: {}
      },
      profile: true,
      cache: true,
      module: {
        rules: [
          {
            test: /\.jsx?$/,
            use: [
              {
                loader: 'babel-loader'
              }
            ],
            exclude: /(node_modules|bower_components|vendors)/
          }, {
            test: /\.jsx?$/,
            use: [
              {
                loader: 'babel-loader'
              }
            ],
            include: /estoolbox/
          }, {
            test: /\.scss$/,
            loader: extractCSS.extract({
                fallback: 'style-loader,
                loader: [
                    {loader: 'css-loader'},
                    {loader: 'fast-sass-loader'}
                ]
            })
          }, {
            test: /\.(ttf|otf|eot|svg|woff(2)?)(\?v=\d+\.\d+\.\d+)?$/,
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext]'
            },
            exclude: /(node_modules|bower_components|vendors)/
          }, {
            test: /\.(ttf|otf|eot|svg|woff(2)?)(\?v=\d+\.\d+\.\d+)?$/,
            loader: 'file-loader',
            options: {
              name: '/assets/fonts/vendor/[name].[ext]'
            },
            include: /(node_modules|bower_components|vendors)/
          }, {
            test: /\.htaccess$/,
            loader: 'file-loader',
            options: {
              name: '/fonts/[name].[ext]'
            }
          }, {
            test: /\.(jpg|JPG|png|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext]'
            },
            exclude: /(node_modules|bower_components|vendors)/
          }, {
            test: /\.(jpg|JPG|png|gif)$/,
            loader: 'file-loader',
            options: {
              name: '/assets/images/vendor/[name].[ext]'
            },
            include: /(node_modules|bower_components|vendors)/
          }, {
            test: /\.hbs$/,
            loader: 'handlebars-loader'
          }, {
            test: /\.html$/,
            loader: 'html-loader'
          }]
      },
      plugins: [
        new HtmlWebpackPlugin({
           template: './index.html'
       }),
        new webpack.NamedModulesPlugin(),
        extractCSS
      ]
    }

and the part of the source code with issue is this:

.hello {
  color: yellow;
  background-image: url("../../assets/images/BITHM_Module00_Background.jpg");
}

The issues is that when I apply this configuration in MacOS environment, everything works fine. But when I was using this configuration under Windows environment, it pops error like this:

ERROR in ../~/css-loader!../~/fast-sass-loader/lib!./scss/app.scss
Module not found: Error: Can't resolve './../assetsimages♂ITHM_Module00_Background.jpg' in 'D:\Git\npm-webpack2\app\scss'
 @ ../~/css-loader!../~/fast-sass-loader/lib!./scss/app.scss 2:249947-250009
 @ ./scss/app.scss
 @ ./js/index.js
 @ multi ./js/index.js

Seems that under the Windows environment, it couldn't read the background images path right. If you see through the error, you can see that there is '/' missing. Some of it just disappear and some of it be convert in to a weird symbol '♂'. However, when I was using sass-laoder + resolve-url-loader, it works in both environment.

Please let me know if there is anything wrong in my configuration or any solution for this, thank you!

How to use in vue-cli 3.x or webpack-chain

vue.config.js

module.exports = {
  chainWebpack: config => {
    config.module
      .rule('.scss')
      .use('fast-sass-loader')
      .loader('fast-sass-loader')
      .tap(options => {
        return options
      })
  }
}

It's error.

您好,关于缓存命中的问题

您好,关于缓存命中问题,有以下疑惑想请教您:
image
image
假设一个经典场景:
C文件 import B文件,B文件import A文件,
1、当修改了C文件,在第一个判断被认为是没缓存
2、当修改A或B文件,在依赖那个循环体中被认为没缓存。

那它缓存命中的时机是什么时候呢?或者说什么样的规则才能最大化使用到缓存呢?

Overzealous dedupe

The deduplication algorithm is also deduping nested imports, resulting in broken/wrong CSS.

Full description of the problem Let's say we have two SCSS files: `style.scss` which is our main file and `group.scss` which contains a bunch of generic rules. We now want those rules to be imported under a class:
.a {
  @import 'group'
}

This will work as expected and the resulting file will look for ex. like this:

.a .c {
  color: red
}

Unfortunately if we try to do it in more than one place, the dedupe algorithm will wrongly assume we don't need to import the same file multiple times and silently break our CSS:

.a {
  @import 'group'
}

.b {
  @import 'group'
}

The above code will result in broken:

.a .c {
  color: red
}
/* .b is missing because it didn't contain any rules */

I've created a repository from above example. I believe deduping @import should only work if it's in root of the document and not when it's nested.

How to use this with Rails Webpacker 4.0

Hello. I'm trying to figure out how to use the with Rails and Webpacker. I was assuming it was a direct replacement for the sass-loader and resolve-url-helper but i can't seem to get it to rewrite/resolve url(..) tags in my scss files.

Here is how I've added it to the loaders.

const fastSassLoader = {
  test: /\.(scss|sass)$/,
  use: [
    'css-loader', 'sass-loader', 'postcss-loader',
    {
      loader: 'fast-sass-loader',
      options: {
        includePaths: [
          path.resolve(__dirname, '../../../app/javascript'),
          path.resolve(__dirname, '../../../vendor/assets/stylesheets'),
          path.resolve(__dirname, '../../../node_modules')
        ]
      }
    }
  ]
}

environment.loaders.prepend('fastSass', fastSassLoader)

Output from the speed measure webpack plugin tells me that it is being used in the chain, although the order is a bit curious

css-loader, and
sass-loader, and
postcss-loader, and
fast-sass-loader, and
mini-css-extract-plugin, and
css-loader, and
postcss-loader, and
sass-loader took 4.081 secs
  module count = 7

I've also tried without the includePaths. Additionally, I've completely removed the sass loader form package.json yet same thing. Seeing these types of errors:

Module build failed (from ./node_modules/@rails/webpacker/node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleNotFoundError: Module not found: Error: Can't resolve '../fonts/glyphicons-halflings-regular.eot' in '/Users/jhirn/src/piq/daisy/app/javascript'```

Would love to get this working so I don't have continue using `resolve-url-loader` it's really slowing down my build time by a lot. 

Allow option for sourcemaps

what

Allow ?sourceMaps or option: { sourceMaps : true }

why

I realize source maps make performance take a hit, but it's still nice for evaluation, at least allow an option for source maps to be enabled?

Glob importer

Hello,

In my sass file I have

@import helpers/*

how can I make this work with fast-sass-loader?

Thanks

Files with double extensions are not resolved

If a file has double extensions, e.g. theme.default.scss, then it is not resolved by @import 'dir/theme.default' directive.

A resolver should try to append default extensions (scss, sass, css) and find the file in this case.

DeprecationWarning: loaderUtils.parseQuery() received a non-string value

DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic, see https://github.com/webpack/loader-utils/issues/56
parseQuery() will be replaced with getOptions() in the next major version of loader-utils.

When I've installed this loader, I'm getting this log above.
I'm using webpack 2.3.2
Nice work with this loader! 👍

Problem with alias-resolve-loader

I am using alias-resolve-loader to pull a directory that exists outside of package.json directory tree, and then importing that file into style.scss. This works fine with sass-loader, but fails using fast-sass.

aliasesResolve: {
    "@siteStyle" : SITES_PATH + process.env.TSJ_SITE + '/static/scss'
},

@import "@siteStyle/style.scss";

'ERROR in ./~/css-loader!./~/fast-sass-loader!./~/alias-resolve-loader!./bootstrap4/static/tsj_core/scss/style.scss
Module build failed: Error: import file cannot be resolved: "@import "../../../tsj-mt/sites/bs4transition/static/scss/style.scss";" @/home/vagrant/.virtualenvs/tsj-mt/src/tsj-ui/tsj_ui/bootstrap4/static/tsj_core/scss/style.scss
    at Object.importReplacer (/home/vagrant/.virtualenvs/tsj-mt/src/tsj-ui/tsj_ui/node_modules/fast-sass-loader/index.js:131:19)
    at throw (native)
    at onRejected (/home/vagrant/.virtualenvs/tsj-mt/src/tsj-ui/tsj_ui/node_modules/co/index.js:81:24)
 @ ./bootstrap4/static/tsj_core/scss/style.scss 4:14-196 13:2-17:4 14:20-202'

Any help would be greatly appreciated!

Proposal / request: Gulp plugin

Would it be possible and make sense to provide this as Gulp plugin too?
Also I think this could be a good standalone solution (not required to use with webpack).

fast-sass-loader support importer

i love fast-sass-loader! it's exactly what we needed for our design system with a ton of sass files. We were using sass-loader which exposes an option to set a loader to load different types of files but fast-sass-loader doesn't expose an option for this.

Specifically we were using sass-loader with a json importer. To get fast-sass-loader to work for us I've written a script to run on a webpack build hook to compile our .json files into .sass files so fast-sass-loader can read them properly. It would be really great if we could encapsulate that behavior into our sass loading process!

Is this something that fast-sass-loader would be interested in adding? Thanks!

docs for reference https://www.npmjs.com/package/node-sass-json-importer

loaders should use the webpack exposed filesystem (fs) object

Webpack does some caching already against the filesystem, and plugins have the ability to change or augment the fs that webpack uses, to do things like store generated files in memory where appropriate. fast-sass-loader uses the node fs which circumvents any of these possibilities. I think ideally the loader should pass through the fs from the loader context.

Please provide a performance test

HI yibn2008

thanks for providing an alternative solution. I'm one of the maintainers of sass-loader and I think it's great to see where we can get better. Could you please provide a performance test that proves your performance numbers? I would like to see where sass-loader is slower than fast-sass-loader.

I would also like to understand why fast-sass-loader's cache is better than webpack's cacheable(). As far as I could tell by reading the code it's currently working exactly the same but maybe I've missed something.

Comments in scss can cause errors

Having three simple scss files for an example:

_Colors.scss:

$lightGray: #efefef;

_Random.scss:

// Random comment
$width: 620px;

Common.scss:

@import "./Colors";
@import "./Random";

webpack.config.js:

        rules: [
            {
                test: /\.(scss|sass)$/,
                use: [
                    'css-loader',
                    {
                        loader: 'fast-sass-loader'
                    }
                ]
            }
        ]

With this setup, it will fail during webpack:

Module build failed: Error: Invalid CSS after "...tGray: #efefef;": expected 1 selector or at-rule, was "// Random comment"
    at options.error (D:\Investigations\webpack_fast-sass_repro_slim\node_modules\node-sass\lib\index.js:291:26)
 @ ./src/index.js 2:0-40```

依赖的node-sass版本问题

我看下在peerDependencies中node-sass的版本是

"node-sass": "~3.10.0"

可否改成

"node-sass": "^3.10.0"

按照语义化的版本,应该用下面的这个也是可以的

Support imports

Hi i'm trying to use fast-sass-loader in favor of sass-loader

Currently sass-loader support imports using an alias: https://github.com/webpack-contrib/sass-loader#imports

Example:

// file.scss
@import ~custom-palette

webpack.config.js

alias: {
    '$custom-palette': path.resolve(__dirname, "./mycustom-palette.scss")
}

is this something that fast-sass-loader supports? since i didn't manage to find any docs

loader doesn't seem to work with Yarn workspaces

Just tried switching from sass-loader to fast-sass-loader but all of my imports are causing errors because, I assume, they refer to package @import "~@lwc-comps/core-styles"; which is a module in my mono-repo. This works fine with sass-loader but here I get the error Error: import file cannot be resolved: "@import "~@lwc-comps/core-styles";". I assume this is because Yarn has lifted all of my package modules to the root node_modules folder. Normally, a simple path.resolve would find this, but it seems fast-sass-loader isn't using this to resolve paths?

Actually 0.2 - 0.5 seconds slower in my case

It seems this loader does not produce much faster builds in the current webpack 4 version.

https://travis-ci.com/DanielRuf/sass-loader-benchmark/jobs/180129808#L506
https://travis-ci.com/DanielRuf/sass-loader-benchmark/jobs/180129809#L506

https://travis-ci.com/DanielRuf/sass-loader-benchmark/jobs/180129171#L506
https://travis-ci.com/DanielRuf/sass-loader-benchmark/jobs/180129172#L506

In fact there is only an advantage when someone falsely reimports files instead of importing them at the root or proper level. So I guess this is not an option for us.

includePaths do not work as expected

When working with the includePaths options I encounter some issues.

Let's say I'd like to use the styles of a library loaded via npm dependency. I'd write an import statement like this, knowing that ther is a file located in node_modules/super-duper-library/_index.scss;

@import 'super-duper-library/index';

To make this work with node-sass, I'd add node_modules as an includePath.

includePaths: ['./node_modules']

Somehow the concept of includePaths of your library is different. I couldn't figure out the idea behind it by just looking at the code. Anyways, I'll create a pull request, that's solving this issue. Looking forward to get your opinion on this.

Allow some sass options to be set, i.e. precision

Currently there is no way to set the precision option like you would with sass-loader. A lot of projects using bootstrap will experience some measurements being off by 1px because the default line-height has 9 precision digits. node-sass defaults to 5 precision digits.

Example: 14px font-size * 1.428571429 line-height would end up as 20px but 14px font-size * 1.42857 line-height would be 19px.

Support data like node-sass

node-sass and sass-loader allow the data option which adds extra SASS code at the beginning of a file. It would be neat to have the same option here, as it provides an option to always import some files or define enviroment variables through the webpack config. Example:

{
  loader: 'fast-sass-loader',
  options: {
    data: '@import: "_variables.scss";'
  }
}

And it would create the following output for a SASS file:

@import "_variables.scss";

.container {
  background-color: $background;
}

sass-loader docs

'Invalid CSS'-errors on compilation when swapping `sass-loader` for `fast-sass-loader`

Hello! I'm trying to swap out sass-loader for fast-sass-loader, however I get this error message trying to doing so:

ERROR in ./assets/stylesheets/importer.scss
    Module build failed: ModuleBuildError: Module build failed: Error: Invalid CSS after "}": expected 1 selector or at-rule, was '@charset "UTF-8";'
        at options.error (C:\Projects\LerniaSE\src\LerniaSE.EpiserverCMS\node_modules\node-sass\lib\index.js:291:26)
        at runLoaders (C:\Projects\LerniaSE\src\LerniaSE.EpiserverCMS\node_modules\webpack\lib\NormalModule.js:244:20)
        at C:\Projects\LerniaSE\src\LerniaSE.EpiserverCMS\node_modules\loader-runner\lib\LoaderRunner.js:364:11
        at C:\Projects\LerniaSE\src\LerniaSE.EpiserverCMS\node_modules\loader-runner\lib\LoaderRunner.js:230:18
        at context.callback (C:\Projects\LerniaSE\src\LerniaSE.EpiserverCMS\node_modules\loader-runner\lib\LoaderRunner.js:111:13)
        at co.then.err (C:\Projects\LerniaSE\src\LerniaSE.EpiserverCMS\node_modules\fast-sass-loader\lib\index.js:301:5)
        at <anonymous>
     @ ./assets/scripts/app.ts 3:0-30
     @ multi babel-polyfill ./assets/scripts/app.ts

My webpack.config.js looks like this:

const webpack = require('webpack');
const WebpackCleanupPlugin = require('webpack-cleanup-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const SriPlugin = require('webpack-subresource-integrity');
require("babel-polyfill");

function getConfiguration(environment, chunkName, entry, dest, plugins = []) {
    return {
        entry: {
            [chunkName]: ['babel-polyfill', entry]
        },
        output: {
            filename: '[name].[hash].js',
            path: path.resolve(__dirname, dest),
            publicPath: '/',
            crossOriginLoading: 'anonymous'
        },
        module: {
            rules: [
                {
                    test: /\.scss$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: { sourceMap: !environment.isProduction }
                        },
                        {
                            loader: 'postcss-loader',
                            options: {
                                plugins: function() {
                                    return [
                                        require('postcss-flexbugs-fixes'),
                                        require('autoprefixer'),
                                        require('cssnano')({ zindex: false })
                                    ];
                                }
                            }
                        },
                        {
                            loader: "fast-sass-loader",
                            options: { sourceMap: !environment.isProduction }
                        }
                    ]
                },
                // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
                { test: /\.tsx?$/, loader: "ts-loader" },
                {
                    test: /\.(jpe?g|png|gif|svg)$/i,
                    exclude: /fonts/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                hash: 'sha512',
                                digest: 'hex',
                                name: '[name].[hash].[ext]',
                                outputPath: 'images/',
                                publicPath: 'images/'
                            }
                        },
                        {
                            loader: 'image-webpack-loader',
                            options: {
                                bypassOnDebug: true
                            }
                        }
                    ]
                }, {
                    test: /\.(eot|ttf|woff|woff2|otf|svg)$/,
                    exclude: /images/,
                    use: [{
                        loader: 'file-loader',
                        options: {
                            name: '[name].[hash].[ext]',
                            outputPath: 'fonts/',
                            publicPath: 'fonts/'
                        }
                    }]
                }
            ]
        },
        devtool: 'source-map',
        resolve: {
            extensions: ['.webpack.js', '.web.js', '.js', '.scss', '.ts'],
            modules: [
                path.resolve('./assets'),
                path.resolve('./node_modules')
            ],
            alias: {
                vue: 'vue/dist/vue.common.js'
            }
        },
        plugins: [
            new WebpackCleanupPlugin({
                exclude: ['fonts/**/*', 'images/**/*']
            }),
            new MiniCssExtractPlugin({
                filename: "[name].[hash].css"
            }),
            ...plugins
        ]
    };
}

module.exports = function (env) {
    const environment = {
        isProduction: env && env.production,
        isDevelopment: !env || !env.production
    };

    const nodeEnv = environment.isProduction ? JSON.stringify('production') : JSON.stringify('development');

    return [
        getConfiguration(environment, 'main', './assets/scripts/app.ts', 'dist', [
            new SriPlugin({
                hashFuncNames: ['sha256'],
                enabled: environment.isProduction
            }),
            new HtmlWebpackPlugin({
                inject: false,
                template: 'Views/Shared/StaticAssets/ScriptsTemplate.cshtml',
                filename: '../Views/Shared/StaticAssets/Scripts.cshtml'
            }),
            new HtmlWebpackPlugin({
                inject: false,
                template: 'Views/Shared/StaticAssets/StylesTemplate.cshtml',
                filename: '../Views/Shared/StaticAssets/Styles.cshtml'
            }),
            new BrowserSyncPlugin({
                // browse to https://localhost:3000/ during development
                proxy: {
                    target: 'https://lerniase.local'
                },
                files: 'Views/**/*.cshtml'
            }),
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery"
            }),
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: nodeEnv
                }
            })
        ]),
        getConfiguration(environment, 'editor', './assets/scripts/editor.ts', 'Static/css/editor')
    ];
};

unable to resolve @import paths in scss files.

because of poor performance in sass-loader i decided to switch to fast-sass-loader. but i am unable to make it work.
my build fails because it cannot resolve paths which were originally resolved by sass-loader.
i am using webpack 4 and AntdScssThemePlugin
here is a piece of code from my webpack config

   {
          test: /\.scss$/,
          use: [
            !isProd ? 'style-loader' : MiniCssExtractPlugin.loader,
            {
              loader: 'css-loader',
              options: {
                sourceMap: false,
                include: path.resolve(__dirname, '../', './src'),
              },
            },
            {
              loader: 'postcss-loader',
              options: {
                sourceMap: false,
                include: path.resolve(__dirname, '../', './src'),
                plugins() {
                  return [autoprefixer('last 2 versions', 'ie 10')];
                },
              },
            },
            AntdScssThemePlugin.themify({
              loader: 'sass-loader',
              options: {
                sourceMap: false,
                include: path.resolve(__dirname, '../', './src'),
                data: '@import "./src/Styles/themes/core";@import "./src/Styles/themes/anttheme";',
              },
            }),
          ],
        },

this loader works fine when i am using sass-loader. but same will fail if i switch to fast-sass-loader

   {
          test: /\.scss$/,
          use: [
            !isProd ? 'style-loader' : MiniCssExtractPlugin.loader,
            {
              loader: 'css-loader',
              options: {
                sourceMap: false,
                include: path.resolve(__dirname, '../', './src'),
              },
            },
            {
              loader: 'postcss-loader',
              options: {
                sourceMap: false,
                include: path.resolve(__dirname, '../', './src'),
                plugins() {
                  return [autoprefixer('last 2 versions', 'ie 10')];
                },
              },
            },
            AntdScssThemePlugin.themify({
              loader: 'fast-sass-loader',
              options: {
                sourceMap: false,
                include: path.resolve(__dirname, '../', './src'),
                data: '@import "./src/Styles/themes/core";@import "./src/Styles/themes/anttheme";',
              },
            }),
          ],
        },

here is the error which i get

ERROR in ./src/App/Common/ErrorHandler/ErrorHandler.styles.scss (./node_modules/css-loader??ref--9-1!./node_modules/postcss-loader/lib??ref--9-2!./node_modules/fast-sass-loader/lib??ref--9-3!./src/App/Common/ErrorHandler/ErrorHandler.styles.scss)
Module build failed (from ./node_modules/fast-sass-loader/lib/index.js):
Error: import file cannot be resolved: "@import "./src/Styles/themes/core";" @/Users/akashtalreja/Hannad/Apps/front end project/client/src/App/Common/ErrorHandler/ErrorHandler.styles.scss
    at Object.importReplacer (/Users/akashtalreja/Hannad/Apps/front end project/client/node_modules/fast-sass-loader/lib/index.js:206:19)
    at importReplacer.throw (<anonymous>)
    at onRejected (/Users/akashtalreja/Hannad/Apps/front end project/client/node_modules/co/index.js:81:24)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:160:7)
 @ ./src/App/Common/ErrorHandler/ErrorHandler.styles.scss 2:14-236 21:1-42:3 22:19-241
 @ ./src/App/Common/ErrorHandler/ErrorHandler.component.jsx
 @ ./src/App/Common/index.js
 @ ./src/App/Router/index.jsx
 @ ./src/App/Layout/index.jsx
 @ ./src/App/index.jsx
 @ ./src/App.hot.js
 @ ./src/index.jsx
 @ multi (webpack)-dev-server/client?http://localhost:9000 (webpack)/hot/dev-server.js react-hot-loader/patch ./src/index.jsx

Webpack 4 support

I just tried to experiment with the simplest setup -- i assume this error is the same as in many other plugins on webpack 4 :)

Module build failed: TypeError: Cannot read property 'context' of undefined
    at getLoaderConfig (/Users/pavel/projects/xx/node_modules/fast-sass-loader/lib/index.js:72:29)
    at Object.module.exports (/Users/pavel/projects/xx/node_modules/fast-sass-loader/lib/index.js:224:17)
 @ ./src/app.scss 4:14-127
 @ ./src/app.js

Webpack 3 Support

Hello!

Does fast-sass-loader support Webpack 3? I have it working correctly in my application, using Webpack 3 and fast-sass-loader 1.2.5.

Would it be possible to add webpack: 3.x to the peerDependencies list?

Its crashing with the latest version of vue-loader: Cannot read property 'getTime' of undefined

Failed to compile.

Module build failed (from ../node_modules/fast-sass-loader/lib/index.js):
TypeError: Cannot read property 'getTime' of undefined
    at Cache.write (/Users/milewski/Code/frontend/node_modules/fast-sass-loader/lib/cache.js:109:48)
    at /Users/milewski/Code/frontend/node_modules/fast-sass-loader/lib/index.js:290:15
    at Generator.next (<anonymous>)
    at onFulfilled (/Users/milewski/Code/frontend/node_modules/co/index.js:65:19)
"webpack": "^4.17.1",
"vue-loader": "15.4.0",

Cannot read property 'config' of null

I get Module build failed: TypeError: Cannot read property 'config' of null with v1.2.1. Seems like it occurs when you don't pass any query at all. Fixed by replace this line with:

let query = loaderUtils.getOptions(loaderContext) || {}

Mixing .sass and .scss syntax

Today, I switched from sass-loader to fast-sass-loader, but noticed an issue related to mixing .sass and .scss files. For example, if I'm compiling src/app.scss, and that file has:

@import '_partial.sass';

If I run Webpack with your loader, it'll blow up.

[1]  .something
     ^
[2]      color: red
[3]
----------------------------------------
Error: Invalid CSS after ".": expected 1 selector or at-rule, was ".something"
    at options.error (/Users/jeffreyway/code/laracasts/node_modules/node-sass/lib/index.js:291:26)

Is there any way around this?

js file picked up instead of css

In the latest release the addition of this code into index.js

  // is module import
  if (original.startsWith('~') && (dirname === '.' || dirname.indexOf('/') < 0)) {
    return [original]
  }

has meant that the code is now including a javascript file instead of a css file, seemingly when an npm package doesnt fit into the right dir format.
The scss line is
@import "~spectrum-colorpicker/spectrum";

That npm package has two files in its route; spectrum.js and spectrum.css. You are now picking up spectrum.js and collating it into the main css file. Which obviously then breaks.

Apologies this isnt a proper test case, this is buried deep in some project code. I can probably knock one together but it'll take me a while.

Trying to get working with babel, raw, and postcss-loaders

Hi there!

I am very interested in using this in place of sass-loader, but unfortunately I'm not able to get it working! I am using this in the context of a next.js project

This is my current configuration:
screen shot 2017-11-04 at 11 51 25 am

and when I add in fast-sass-loader in place, I get this error:
screen shot 2017-11-04 at 11 53 15 am

I've tried to debug it, but I am not sure how to proceed!

Thanks so much!

Passing outputStyle to sass.render

We have successfully replaced sass-loader with fast-sass-loader, and are seeing very nice performance improvements. However, our output files are substantially larger. We have traced that to the fact that our rule for sass-loader sets use.options.outputStyle to "compressed"in our webpack configuration file, and we have many comments in our .scss files which outputStyle "compressed" eliminates.

Currently, I don't see a way to pass an outputStyle through fast-sass-loader to node-sass, so we experimented by hacking index.js to do that:

  try {
    let result = yield new Promise((resolve, reject) => {
      sass.render({
        indentedSyntax: entry.endsWith('.sass'),
        outputStyle: 'compressed',
        file: entry,
        data: merged
      }, (err, result) => {
        if (err) {
          reject(err)
        } else {
          resolve(result)
        }
      })
    })

and that worked for us. Can outputStyle be added to the fast-sass-loader options?
We can work up a PR if you would like.

Thanks,
Barry Bentley

resolve-url url() to absolute path

Problem

our file structure separates the assets and scss files (not in one directory)
fas-sass-loader always try to fill the assets location same as scss files where the assets are called.
is there a way to turn these off and point the url() to designated location??

Code Snippet

Error log

ERROR in ./app/stylesheets/packs/mobile/home.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleNotFoundError: Module not found: Error: Can't resolve '../../gulp/assets/stylesheets/mobile/icons/icn-upload.png' in '/vidio_vagrant/app/stylesheets/packs/mobile'

gulp/assets/stylesheets/mobile/upload.scss

background-image: image-url("icon/icn-upload.png")

gulp/assets/stylesheets/mixin/images.scss

you can see that i tried to input the url
@function image-url($url) { @return url("app/assets" + $url); }

app/assets/icon/icn-upload.png

assets are located in here!!

Please is there any kind of config?
so that i can change using my path

Thanks

@import sytax can not be correct resolved on Windows 10 System.

Description

When I use fast-sass-loader in react project. It was well on my Mac. But when I try run this project on Windows 10 device, it can not pass the compile.

The Webpack throw a error message about "Module build failed.... Error : Import file cannot be resolved : @import '~src/styles/vars.scss' "...

image

image

Code

webpack config:

...json
// webpack.config
"alias": {
    "src": "./src" // ignore the short path, it will be resolved correctly.
}
@import '~src/styles.vars.scss';

Environment

  • fast-sass-load: @1.5.0
  • webpack 4.x
  • windows 10

Dedupe not working

I exchanged sass-loader with fast-sass-loader because I need the deduplicating feature of fast-sass-loader.
My config looks like:

{
	test: /\.(scss)$/,
	loader: ExtractTextPlugin.extract(
		Object.assign(
			{
				fallback: require.resolve('style-loader'),
				use: [
					{
						loader: require.resolve('css-loader'),
						options: {
							importLoaders: 2,
							minimize: true,
							sourceMap: shouldUseSourceMap,
							modules: true,
							localIdentName: '[local]'
						},
					},
					{
						loader: require.resolve('postcss-loader'),
						options: {
							// Necessary for external CSS imports to work
							// https://github.com/facebookincubator/create-react-app/issues/2677
							ident: 'postcss',
							plugins: () => [
								require('postcss-flexbugs-fixes'),
								autoprefixer({
									browsers: [
										'>1%',
										'last 4 versions',
										'Firefox ESR',
										'not ie < 9', // React doesn't support IE8 anyway
									],
									flexbox: 'no-2009',
								}),
							],
							sourceMap: shouldUseSourceMap,
						},
					},
					{
						loader: require.resolve('fast-sass-loader'),
						options: {
							sourceMap: shouldUseSourceMap,
							precision: 10,
						},
					},
				],
			},
			extractTextPluginOptions
		)
	),
},

I then import a library from the javascript index.js like:
import 'infinity/scss/main.scss';
The main.scss itself imports fonts/all.scss which in turn imports icons.scss among others.

In two of my components I import two separate scss files which in turn do @import "~infinity/scss/fonts/icons";

First issue: the classes which are imported by infinity/scss/main.scss are also included in the scss of the components.
Second issue: the classes which are included by the first component are also included in the second component.

Webpack 4 error

I get this error using [email protected] with [email protected].

Module build failed: ModuleBuildError: Module build failed: TypeError: Cannot read property 'context' of undefined
      at getLoaderConfig (C:\path\to\node_modules\fast-sass-loader\lib\index.js:72:29)
      at Object.module.exports (C:\path\to\node_modules\fast-sass-loader\lib\index.js:224:17)
      at runLoaders (C:\path\to\node_modules\webpack\lib\NormalModule.js:236:20)
      at C:\path\to\node_modules\loader-runner\lib\LoaderRunner.js:364:11
      at C:\path\to\node_modules\loader-runner\lib\LoaderRunner.js:230:18
      at runSyncOrAsync (C:\path\to\node_modules\loader-runner\lib\LoaderRunner.js:143:3)
      at iterateNormalLoaders (C:\path\to\node_modules\loader-runner\lib\LoaderRunner.js:229:2)
      at iterateNormalLoaders (C:\path\to\node_modules\loader-runner\lib\LoaderRunner.js:218:10)
      at C:\path\to\node_modules\loader-runner\lib\LoaderRunner.js:233:3
      at runSyncOrAsync (C:\path\to\node_modules\loader-runner\lib\LoaderRunner.js:130:11)
      at iterateNormalLoaders (C:\path\to\node_modules\loader-runner\lib\LoaderRunner.js:229:2)
      at Array.<anonymous> (C:\path\to\node_modules\loader-runner\lib\LoaderRunner.js:202:4)

Does fast-sass-loader intend to sync options with sass-loader?

sass-loader has published version 8 and they have breaking changes to their options config. They now put the options under the sassOptions property. I'm just curious if it's the intention of this library to keep that option structure in sync. Regardless, I love using fast-sass-loader! Thank you folks for all your hard work!

Issue with relative imports and aliases

Hi there,

It seems upgrading from 1.4.6 to 1.4.7 has created an issue with a case of importing. Though I am not sure if this has to do with not ideal practices on my part or an oversight with 1.4.7

Currently throughout our project some imports in scss files are done such as:
@import '~scss/meta';

Though an alias exists for part of the path in the webpack.config.js, such as:
resolve: { alias: { scss: path.resolve(__dirname, PATH_TO_SHARE, "source/scss/") } }

So with 1.4.7 installed, I'm getting errors throughout our SCSS files:
Error: import file cannot be resolved: "@import '~scss/meta';"

Removing the ~ seems to get rid of the import errors associated, fwiw.

Any insight would be greatly appreciated!

vue 文件 多个style 模块 缓存问题

vue 文件 多个style 模块 缓存问题

let entry = this.resourcePath
let cache = new Cache(entry)

以文件路径作为缓存的标识符 无法满足 当vue 单文件中出现 多个<style lang=“scss”>...</style>模块后,vue-loader 会调用多次 fast-sass-loader 但是文件路径还是同一个 命中缓存后 会取第一个<style>代码块的代码

Problem in jest tests fast-sass-loader/lib/index.js is not a loader

i got this full error :

  console.error node_modules/jest-jasmine2/build/jasmine/Env.js:195
    Error: Module '/formats/node_modules/fast-sass-loader/lib/index.js' is not a loader (must have normal or pitch function)
        at loadLoader (/formats/node_modules/loader-runner/lib/loadLoader.js:35:10)
        at iteratePitchingLoaders (/formats/node_modules/loader-runner/lib/LoaderRunner.js:169:2)
        at iteratePitchingLoaders (/formats/node_modules/loader-runner/lib/LoaderRunner.js:165:10)
        at /formats/node_modules/loader-runner/lib/LoaderRunner.js:173:18
        at loadLoader (/formats/node_modules/loader-runner/lib/loadLoader.js:36:3)
        at iteratePitchingLoaders (/formats/node_modules/loader-runner/lib/LoaderRunner.js:169:2)
        at runLoaders (/formats/node_modules/loader-runner/lib/LoaderRunner.js:362:2)
        at NormalModule.doBuild (/formats/node_modules/webpack/lib/NormalModule.js:179:3)
        at NormalModule.build (/formats/node_modules/webpack/lib/NormalModule.js:268:15)
        at Compilation.buildModule (/formats/node_modules/webpack/lib/Compilation.js:146:10)
        at factoryCallback (/formats/node_modules/webpack/lib/Compilation.js:329:11)
        at factory (/formats/node_modules/webpack/lib/NormalModuleFactory.js:253:5)
        at applyPluginsAsyncWaterfall (/formats/node_modules/webpack/lib/NormalModuleFactory.js:99:14)
        at /formats/node_modules/webpack/node_modules/tapable/lib/Tapable.js:268:11
        at NormalModuleFactory.params.normalModuleFactory.plugin (/formats/node_modules/webpack/lib/CompatibilityPlugin.js:52:5)
        at NormalModuleFactory.applyPluginsAsyncWaterfall (/formats/node_modules/webpack/node_modules/tapable/lib/Tapable.js:272:13)
        at resolver (/formats/node_modules/webpack/lib/NormalModuleFactory.js:74:11)
        at process.nextTick (/formats/node_modules/webpack/lib/NormalModuleFactory.js:205:8)
        at _combinedTickCallback (internal/process/next_tick.js:131:7)
        at process._tickCallback (internal/process/next_tick.js:180:9)

Options: includePaths is not passed to node-sass

Hello there,

I'm porting from grunt to webpack and encountered a problem with the fast-sass-loader.

webpack.config.js

        {
          test: /\.(s?css|sass)$/,
          use: ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: [
              {
                loader: 'css-loader',
                options: { minimize: true }
              },
              {
                loader: 'fast-sass-loader',
                options: {
                  includePaths: ['client/styles']
                }
              }
            ]
          })
        }

The includePaths is not passed to the node-sass.
I can verify this by manually added console-loggings in node_modules/node-sass/lib/index.js.

However: If i am setting process.env.SASS_PATH = ['client/styles']; manually, it works fine.
I have not checked other options.

OS: Windows 7 x64 (6.1.7601)
node: v6.11.2
node-sass: 4.7.2
fast-sass-loader: 1.4.0

Regards and keep up your nice work!

Variables imported in the top file cannot get by files followed

Hi there,I have used fast-sass-loader in my webpack config file to improve sass compiling performance.
My directories structure like this:

/common
  index-common.scss
/page
   /sop
       /components
         CircleChart.scss
     index.scss

In the file /common/index-common.scss,I set a variable like this: $sop-color-3: #999999;.

/common/index-common.scss
$sop-color-3: #999999;

And then, imported the index-common.scss file in /page/sop/index.scss.

/page/sop/index.scss
@import '../../common/index-common.scss'

/page/sop/index.scss is the entry point of all files.CircleChart is component file imported by entry point.
When I used variable $sop-color-3,some errors occured like this.
image
Is there something wrong in my config.js file?Or I have missed something.

{
        test: /\.(sa|sc|c)ss$/u,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'fast-sass-loader'
        ],
      },

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.