Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: webpack-contrib/sass-loader
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 43d6d14a1b3d83d1e0e4af50b162874e1ffc123b
Choose a base ref
...
head repository: webpack-contrib/sass-loader
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 44fe61c8280bdf72ce7c8207be91bdf020dab93a
Choose a head ref

Commits on Jun 27, 2016

  1. Update CHANGELOG

    jhnns committed Jun 27, 2016
    Copy the full SHA
    e2a8491 View commit details
  2. 3.2.3

    jhnns committed Jun 27, 2016
    Copy the full SHA
    15a4b89 View commit details
  3. Merge branch 'release/v3.2.3'

    # Conflicts:
    #	CHANGELOG.md
    #	package.json
    jhnns committed Jun 27, 2016
    Copy the full SHA
    11aaf06 View commit details

Commits on Aug 10, 2016

  1. Use resoucePath for custom importers

    Fixes #234
    Chris Fitzgerald committed Aug 10, 2016
    Copy the full SHA
    fd6be1f View commit details

Commits on Sep 1, 2016

  1. Merge pull request #267 from chrisfitz/master

    Use resoucePath for custom importers
    jhnns authored Sep 1, 2016
    Copy the full SHA
    327de9c View commit details
  2. Update dependencies

    jhnns committed Sep 1, 2016
    Copy the full SHA
    5dc9c2a View commit details
  3. Copy the full SHA
    08090a8 View commit details
  4. Update CHANGELOG

    jhnns committed Sep 1, 2016
    Copy the full SHA
    2ee710a View commit details
  5. 4.0.1

    jhnns committed Sep 1, 2016
    Copy the full SHA
    c42086e View commit details
  6. Add travis yml

    Jorik Tangelder committed Sep 1, 2016

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d85919f View commit details
  7. Merge pull request #276 from jtangelder/travis

    Add travis yml
    jtangelder authored Sep 1, 2016
    Copy the full SHA
    9e87532 View commit details

Commits on Sep 7, 2016

  1. Fix wrong context in customImporters

    This is a regression that was introduced with fd6be1f
    
    #275 #277
    jhnns committed Sep 7, 2016
    Copy the full SHA
    d894345 View commit details
  2. Merge pull request #281 from jtangelder/fix/wrong-ctx-custom-importer

    Fix wrong context in customImporters
    jhnns authored Sep 7, 2016
    Copy the full SHA
    6be7eff View commit details
  3. Update CHANGELOG

    jhnns committed Sep 7, 2016
    Copy the full SHA
    af6d7e3 View commit details
  4. 4.0.2

    jhnns committed Sep 7, 2016
    Copy the full SHA
    6b555dd View commit details
  5. Merge pull request #282 from jtangelder/release/4.0.2

    Release/4.0.2
    jhnns authored Sep 7, 2016
    Copy the full SHA
    7802f1e View commit details

Commits on Nov 17, 2016

  1. Fix typos

    johnjacobkenny authored Nov 17, 2016
    Copy the full SHA
    e09e7ca View commit details

Commits on Nov 21, 2016

  1. Merge pull request #304 from kennyjacob/patch-1

    Fix typos in README.md
    jhnns authored Nov 21, 2016
    Copy the full SHA
    beec1fe View commit details

Commits on Nov 24, 2016

  1. Copy the full SHA
    4863e04 View commit details
  2. Merge pull request #310 from clintonb/readme-fix

    Corrected invocations of raw-loader, style-loader and css-loader
    jhnns authored Nov 24, 2016
    Copy the full SHA
    a0d12a6 View commit details

Commits on Dec 4, 2016

  1. Export instance of node-sass compiler

    Closes #311.
    niksy committed Dec 4, 2016
    Copy the full SHA
    8076b80 View commit details

Commits on Dec 11, 2016

  1. Copy the full SHA
    b42a7fd View commit details

Commits on Dec 14, 2016

  1. Merge pull request #319 from mattlewis92/patch-1

    Update node-sass to 4.0.0
    jhnns authored Dec 14, 2016
    Copy the full SHA
    c654aa6 View commit details
  2. Update .travis.yml

    - Remove node 5 (since it's not LTS)
    - Add node 4 (since it's LTS)
    - Add node 7
    jhnns committed Dec 14, 2016
    Copy the full SHA
    d383feb View commit details
  3. Update CHANGELOG

    jhnns committed Dec 14, 2016
    Copy the full SHA
    1e68c79 View commit details
  4. 4.1.0

    jhnns committed Dec 14, 2016
    Copy the full SHA
    51d7544 View commit details
  5. Merge pull request #322 from jtangelder/release/4.1.0

    Release/4.1.0
    jhnns authored Dec 14, 2016
    Copy the full SHA
    e5f2196 View commit details
  6. Merge pull request #317 from niksy/issue-311

    Export instance of node-sass compiler
    jhnns authored Dec 14, 2016
    Copy the full SHA
    f3b58f5 View commit details
  7. Copy the full SHA
    8fc199a View commit details

Commits on Dec 16, 2016

  1. Merge pull request #324 from jtangelder/revert-317-issue-311

    Revert "Export instance of node-sass compiler"
    jhnns authored Dec 16, 2016
    Copy the full SHA
    73cdc38 View commit details

Commits on Dec 21, 2016

  1. Copy the full SHA
    402b5d3 View commit details
  2. Merge pull request #330 from jtangelder/webpack-w

    update webpack peerDependency
    jtangelder authored Dec 21, 2016
    Copy the full SHA
    44dc274 View commit details
  3. Update CHANGELOG.md

    jtangelder authored Dec 21, 2016
    Copy the full SHA
    f94db6e View commit details
  4. Merge pull request #331 from jtangelder/update-changelog

    Update CHANGELOG.md
    jtangelder authored Dec 21, 2016
    Copy the full SHA
    f5a0e77 View commit details

Commits on Dec 26, 2016

  1. Remove synchronous compilation support

    See #333
    jhnns committed Dec 26, 2016
    Copy the full SHA
    a9c9007 View commit details
  2. Merge pull request #334 from jtangelder/remove/sync-compilation

    Remove synchronous compilation support
    jhnns authored Dec 26, 2016
    Copy the full SHA
    b68db45 View commit details
  3. Remove node 0.12 support and replace jshint with eslint using eslint-…

    …config-peerigon
    
    This has been done in one step since eslint can automatically fix a lot issues for us. We're using eslint-config-peerigon as new baseline.
    jhnns committed Dec 26, 2016
    Copy the full SHA
    29b3075 View commit details
  4. Merge pull request #335 from jtangelder/remove/node-0.12-support

    Remove node 0.12 support and replace jshint with eslint using eslint-…
    jhnns authored Dec 26, 2016
    Copy the full SHA
    96e21d0 View commit details
  5. Refactor code

    - Remove unused stuff
    - Update code for ES6 features
    jhnns committed Dec 26, 2016
    Copy the full SHA
    003ecf4 View commit details
  6. Merge pull request #336 from jtangelder/refactor/code

    Refactor code
    jhnns authored Dec 26, 2016
    Copy the full SHA
    9a40c7b View commit details
  7. Move loader into lib folder

    jhnns committed Dec 26, 2016
    Copy the full SHA
    83a59b3 View commit details
  8. Copy the full SHA
    227a1d3 View commit details
  9. Move importsToResolve to dedicated module

    And refactor imperative code in favor of a functional approach
    jhnns committed Dec 26, 2016
    Copy the full SHA
    a796ace View commit details
  10. Copy the full SHA
    f8ea88a View commit details
  11. Copy the full SHA
    7dc9731 View commit details

Commits on Dec 27, 2016

  1. Refactor webpackImporter

    jhnns committed Dec 27, 2016
    Copy the full SHA
    43cec39 View commit details
  2. Refactor and simplify index.test.js

    The new test setup makes it easier to use it.only() and it.skip()
    jhnns committed Dec 27, 2016
    Copy the full SHA
    09589c3 View commit details
  3. Simplify formatSassError

    jhnns committed Dec 27, 2016
    Copy the full SHA
    d8e1fa9 View commit details
  4. Copy the full SHA
    bd0e549 View commit details
  5. Merge pull request #337 from jtangelder/refactor/code

    Refactor/code
    jhnns authored Dec 27, 2016
    Copy the full SHA
    58789df View commit details
Showing with 1,562 additions and 1,049 deletions.
  1. +5 −0 .eslintignore
  2. +9 −0 .eslintrc.json
  3. +2 −0 .gitignore
  4. +0 −20 .jshintignore
  5. +0 −49 .jshintrc
  6. +0 −19 .npmignore
  7. +14 −0 .nycrc
  8. +49 −0 .travis.yml
  9. +267 −48 CHANGELOG.md
  10. +1 −1 LICENSE
  11. +184 −108 README.md
  12. +29 −0 appveyor.yml
  13. +0 −393 index.js
  14. +73 −0 lib/formatSassError.js
  15. +58 −0 lib/importsToResolve.js
  16. +83 −0 lib/loader.js
  17. +78 −0 lib/normalizeOptions.js
  18. +29 −0 lib/proxyCustomImporters.js
  19. +73 −0 lib/webpackImporter.js
  20. +52 −36 package.json
  21. +5 −0 test/.eslintrc.json
  22. +27 −18 test/bootstrapSass/webpack.config.js
  23. +34 −0 test/extractText/webpack.config.js
  24. +6 −5 test/hmr/entry.js
  25. +7 −0 test/hmr/simple.scss
  26. +17 −24 test/hmr/webpack.config.js
  27. +237 −213 test/index.test.js
  28. +3 −0 test/node_modules/@org/bar/_foo.scss
  29. +3 −0 test/node_modules/@org/pkg/index.scss
  30. +4 −0 test/node_modules/@org/pkg/package.json
  31. +1 −2 test/{hmr/simple.css → node_modules/animate.css/animate.css}
  32. +0 −1 test/output/.gitignore
  33. +1 −0 test/sass/another/variables.sass
  34. 0 test/sass/empty.sass
  35. +7 −0 test/sass/import-from-npm-org-pkg.sass
  36. +1 −0 test/sass/import-include-paths.sass
  37. +8 −4 test/sass/imports.sass
  38. 0 test/sass/{from-include-path → includePath}/_underscore-include-path-module.sass
  39. +3 −0 test/sass/includePath/animate.css/animate.css
  40. 0 test/sass/{from-include-path → includePath}/include-path-module.sass
  41. +11 −0 test/sass/language.sass
  42. +1 −0 test/scss/another/_variables.scss
  43. 0 test/scss/empty.scss
  44. +3 −1 test/scss/error.scss
  45. +8 −0 test/scss/import-from-npm-org-pkg.scss
  46. +1 −0 test/scss/import-include-paths.scss
  47. +11 −3 test/scss/imports.scss
  48. 0 test/scss/{from-include-path → includePath}/_underscore-include-path-module.scss
  49. +3 −0 test/scss/includePath/animate.css/animate.css
  50. 0 test/scss/{from-include-path → includePath}/include-path-module.scss
  51. +15 −0 test/scss/language.scss
  52. +1 −0 test/scss/multipleCompilations/a.scss
  53. +1 −0 test/scss/multipleCompilations/b.scss
  54. +1 −0 test/scss/multipleCompilations/c.scss
  55. +1 −0 test/scss/multipleCompilations/d.scss
  56. +1 −0 test/scss/multipleCompilations/e.scss
  57. +1 −0 test/scss/multipleCompilations/f.scss
  58. +1 −0 test/scss/multipleCompilations/g.scss
  59. +1 −0 test/scss/multipleCompilations/h.scss
  60. +0 −3 test/sourceMap/entry.js
  61. +2 −2 test/sourceMap/index.html
  62. +20 −14 test/sourceMap/webpack.config.js
  63. +22 −25 test/spec.test.js
  64. +28 −28 test/tools/createSpec.js
  65. +8 −8 test/tools/customFunctions.js
  66. +10 −5 test/tools/customImporter.js
  67. +3 −3 test/tools/runCreateSpec.js
  68. +14 −0 test/tools/testLoader.js
  69. +2 −2 test/watch/entry.js
  70. +22 −14 test/watch/webpack.config.js
5 changes: 5 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Compiled by webpack
test/output

# Fake node_modules folder for tests
test/node_modules
9 changes: 9 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": [
"peerigon/base"
],
"env": {
"node": true
},
"root": true
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -15,3 +15,5 @@ npm-debug.log
/node_modules
coverage
.idea
.nyc_output
test/output
20 changes: 0 additions & 20 deletions .jshintignore

This file was deleted.

49 changes: 0 additions & 49 deletions .jshintrc

This file was deleted.

19 changes: 0 additions & 19 deletions .npmignore

This file was deleted.

14 changes: 14 additions & 0 deletions .nycrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"reporter": [
"lcov",
"text"
],
"include": [
"lib/**/*.js"
],
"lines": 97,
"statements": 91,
"functions": 100,
"branches": 89,
"check-coverage": true
}
49 changes: 49 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
sudo: false
dist: trusty
language: node_js
branches:
only:
- master
- feature/webpack3
jobs:
fast_finish: true
allow_failures:
- env: WEBPACK_VERSION=canary
include:
- &test-latest
stage: Webpack latest
nodejs: 6
env: WEBPACK_VERSION=latest JOB_PART=test
script: npm run travis:$JOB_PART
- <<: *test-latest
nodejs: 4.8
env: WEBPACK_VERSION=latest JOB_PART=test
script: npm run travis:$JOB_PART
- <<: *test-latest
node_js: 8
env: WEBPACK_VERSION=latest JOB_PART=lint
script: npm run travis:$JOB_PART
- <<: *test-latest
node_js: 8
env: WEBPACK_VERSION=latest JOB_PART=coverage
script: npm run travis:$JOB_PART
after_success: 'bash <(curl -s https://codecov.io/bash)'
- stage: Webpack canary
before_script: npm i --no-save git://github.com/webpack/webpack.git#master
script: npm run travis:$JOB_PART
node_js: 8
env: WEBPACK_VERSION=canary JOB_PART=test
before_install:
- 'if [[ `npm -v` != 5* ]]; then npm i -g npm@^5.0.0; fi'
- nvm --version
- node --version
- npm --version
before_script:
- |-
if [ "$WEBPACK_VERSION" ]; then
npm i --no-save webpack@$WEBPACK_VERSION
fi
script:
- 'npm run travis:$JOB_PART'
after_success:
- 'bash <(curl -s https://codecov.io/bash)'
315 changes: 267 additions & 48 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,78 +1,297 @@
Changelog
---------
# Change Log

### 4.0.0
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

- **Breaking**: Release new major version because the previous release was a breaking change in certain scenarios [#250](https://github.com/jtangelder/sass-loader/pull/250)
<a name="6.0.7"></a>
## [6.0.7](https://github.com/webpack-contrib/sass-loader/compare/v6.0.6...v6.0.7) (2018-03-03)

### 3.2.2

- Fix incorrect source map paths [#250](https://github.com/jtangelder/sass-loader/pull/250)
### Bug Fixes

### 3.2.1
* **package:** add `webpack >= v4.0.0` (`peerDependencies`) ([#541](https://github.com/webpack-contrib/sass-loader/issues/541)) ([620bdd4](https://github.com/webpack-contrib/sass-loader/commit/620bdd4))

- Add `webpack@^2.1.0-beta` as peer dependency [#233](https://github.com/jtangelder/sass-loader/pull/233)

### 3.2.0
### Performance Improvements

- Append file content instead of overwriting when `data`-option is already present [#216](https://github.com/jtangelder/sass-loader/pull/216)
- Make `indentedSyntax` option a bit smarter [#196](https://github.com/jtangelder/sass-loader/pull/196)
* use `neo-async` instead `async` ([#538](https://github.com/webpack-contrib/sass-loader/issues/538)) ([fab89dc](https://github.com/webpack-contrib/sass-loader/commit/fab89dc))

### 3.1.2

- Fix loader query not overriding webpack config [#189](https://github.com/jtangelder/sass-loader/pull/189)
- Update peer-dependencies [#182](https://github.com/jtangelder/sass-loader/pull/182)
- `node-sass@^3.4.2`
- `webpack@^1.12.6`

### 3.1.1
<a name="6.0.6"></a>
## [6.0.6](https://github.com/webpack-contrib/sass-loader/compare/v6.0.5...v6.0.6) (2017-06-14)

- Fix missing module `object-assign` [#178](https://github.com/jtangelder/sass-loader/issues/178)
### Chore

### 3.1.0
* Adds Webpack 3.x version range to peerDependencies

- Add possibility to also define all options in your `webpack.config.js` [#152](https://github.com/jtangelder/sass-loader/pull/152) [#170](https://github.com/jtangelder/sass-loader/pull/170)
- Fix a problem where modules with a `.` in their names were not resolved [#167](https://github.com/jtangelder/sass-loader/issues/167)

### 3.0.0
<a name="6.0.5"></a>
# [6.0.5](https://github.com/webpack-contrib/sass-loader/compare/v6.0.5...v6.0.4) (2017-05-10)

- **Breaking:** Add `node-sass@^3.3.3` and `webpack@^1.12.2` as peer-dependency [#165](https://github.com/jtangelder/sass-loader/pull/165) [#166](https://github.com/jtangelder/sass-loader/pull/166) [#169](https://github.com/jtangelder/sass-loader/pull/169)
- Fix crash when Sass reported an error without `file` [#158](https://github.com/jtangelder/sass-loader/pull/158)
### Bug Fixes

### 2.0.1
* importing file directly from scoped npm package [#450](https://github.com/webpack-contrib/sass-loader/pull/450) ([5d06e9d](https://github.com/webpack-contrib/sass-loader/commit/5d06e9d))

- Add missing path normalization [#141](https://github.com/jtangelder/sass-loader/pull/141)

### 2.0.0
<a name="6.0.4"></a>
# [6.0.4](https://github.com/webpack-contrib/sass-loader/compare/v6.0.4...v6.0.3) (2017-05-09)

- **Breaking:** Refactor [import resolving algorithm](https://github.com/jtangelder/sass-loader/blob/089c52dc9bd02ec67fb5c65c2c226f43710f231c/index.js#L293-L348). The new algorithm is aligned to libsass' way of resolving files. This yields to different results if two files with the same path and filename but with different extensions are present. Though this change should be no problem for most users, we must flag it as breaking change. [#135](https://github.com/jtangelder/sass-loader/issues/135) [#138](https://github.com/jtangelder/sass-loader/issues/138)
- Add temporary fix for stuck processes (see [sass/node-sass#857](https://github.com/sass/node-sass/issues/857)) [#100](https://github.com/jtangelder/sass-loader/issues/100) [#119](https://github.com/jtangelder/sass-loader/issues/119) [#132](https://github.com/jtangelder/sass-loader/pull/132)
- Fix path resolving on Windows [#108](https://github.com/jtangelder/sass-loader/issues/108)
- Fix file watchers on Windows [#102](https://github.com/jtangelder/sass-loader/issues/102)
- Fix file watchers for files with errors [#134](https://github.com/jtangelder/sass-loader/pull/134)
### Bug Fixes

### 1.0.4
* fix: Resolving of scoped npm packages [#447](https://github.com/webpack-contrib/sass-loader/pull/447)

- Fix wrong source-map urls [#123](https://github.com/jtangelder/sass-loader/pull/123)
- Include source-map contents by default [#104](https://github.com/jtangelder/sass-loader/pull/104)

### 1.0.3
<a name="6.0.3"></a>
# [6.0.3](https://github.com/webpack-contrib/sass-loader/compare/v6.0.3...v6.0.2) (2017-03-07)

- Fix importing css files from scss/sass [#101](https://github.com/jtangelder/sass-loader/issues/101)
- Fix importing Sass partials from includePath [#98](https://github.com/jtangelder/sass-loader/issues/98) [#110](https://github.com/jtangelder/sass-loader/issues/110)
### Bug Fixes

### 1.0.2
* Fix regression with empty files [#398](https://github.com/webpack-contrib/sass-loader/pull/398)

- Fix a bug where files could not be imported across language styles [#73](https://github.com/jtangelder/sass-loader/issues/73)
- Update peer-dependency `node-sass` to `3.1.0`

### 1.0.1
### Chore

- Fix Sass partials not being resolved anymore [#68](https://github.com/jtangelder/sass-loader/issues/68)
- Update peer-dependency `node-sass` to `3.0.0-beta.4`
* Reduce npm package size by using the [files](https://docs.npmjs.com/files/package.json#files) property in the `package.json`

### 1.0.0

- Moved `node-sass^3.0.0-alpha.0` to `peerDependencies` [#28](https://github.com/jtangelder/sass-loader/issues/28)
- Using webpack's module resolver as custom importer [#39](https://github.com/jtangelder/sass-loader/issues/31)
- Add synchronous compilation support for usage with [enhanced-require](https://github.com/webpack/enhanced-require) [#39](https://github.com/jtangelder/sass-loader/pull/39)
<a name="6.0.2"></a>
# [6.0.2](https://github.com/webpack-contrib/sass-loader/compare/v6.0.2...v6.0.1) (2017-02-21)

### Chore

* Update dependencies [#383](https://github.com/webpack-contrib/sass-loader/pull/383)


<a name="6.0.1"></a>
# [6.0.1](https://github.com/webpack-contrib/sass-loader/compare/v6.0.1...v6.0.0) (2017-02-17)

### Bug Fixes

* Fix source maps in certain CWDs. [#377](https://github.com/webpack-contrib/sass-loader/pull/377)


<a name="6.0.0"></a>
# [6.0.0](https://github.com/webpack-contrib/sass-loader/compare/v6.0.0...v5.0.1) (2017-02-13)

### Bug Fixes

* Improve source map support. [#374](https://github.com/webpack-contrib/sass-loader/issues/374)


### BREAKING CHANGES

* This is breaking for the resolve-url-loader


<a name="5.0.1"></a>
# [5.0.1](https://github.com/webpack-contrib/sass-loader/compare/v5.0.1...v5.0.0) (2017-02-13)

### Bug Fixes

* Fix bug where multiple compilations interfered with each other. [#369](https://github.com/webpack-contrib/sass-loader/pull/369)


<a name="5.0.0"></a>
# [5.0.0](https://github.com/webpack-contrib/sass-loader/compare/v5.0.0...v4.1.1) (2017-02-13)

### Code Refactoring

* Remove synchronous compilation support [#334](https://github.com/webpack-contrib/sass-loader/pull/334)


### BREAKING CHANGES

* Remove node 0.12 support. [29b30755021a834e622bf4b5bb9db4d6e5913905](https://github.com/webpack-contrib/sass-loader/commit/29b30755021a834e622bf4b5bb9db4d6e5913905)
* Remove official node-sass@3 and webpack@1 support. [5a6bcb96d8bd7a7a11c33252ba739ffe09ca38c5](https://github.com/webpack-contrib/sass-loader/commit/5a6bcb96d8bd7a7a11c33252ba739ffe09ca38c5)
* Remove synchronous compilation support. [#334](https://github.com/webpack-contrib/sass-loader/pull/334)


<a name="4.1.1"></a>
# [4.1.1](https://github.com/webpack-contrib/sass-loader/compare/v4.1.1...v4.1.0) (2016-12-21)

### Chore

* Update webpack peer dependency to support 2.2.0rc. [#330](https://github.com/webpack-contrib/sass-loader/pull/330)


<a name="4.1.0"></a>
# [4.1.0](https://github.com/webpack-contrib/sass-loader/compare/v4.1.0...v4.0.2) (2016-12-14)

### Features

* Update `node-sass@4.0.0` [#319](https://github.com/webpack-contrib/sass-loader/pull/319)


<a name="4.0.2"></a>
# [4.0.2](https://github.com/webpack-contrib/sass-loader/compare/v4.0.2...v4.0.1) (2016-07-07)

### Bug Fixes

* Fix wrong context in customImporters [#281](https://github.com/webpack-contrib/sass-loader/pull/281)


<a name="4.0.1"></a>
# [4.0.1](https://github.com/webpack-contrib/sass-loader/compare/v4.0.1...v4.0.0) (2016-07-01)

### Bug Fixes

* Fix custom importers receiving `'stdin'` as second argument instead of the actual `resourcePath` [#267](https://github.com/webpack-contrib/sass-loader/pull/267)


<a name="4.0.0"></a>
# [4.0.0](https://github.com/webpack-contrib/sass-loader/compare/v4.0.0...v3.2.2) (2016-06-27)

### Bug Fixes

* Fix incorrect source map paths [#250](https://github.com/webpack-contrib/sass-loader/pull/250)


### BREAKING CHANGES

* Release new major version because the previous release was a breaking change in certain scenarios
See: https://github.com/webpack-contrib/sass-loader/pull/250#issuecomment-228663059


<a name="3.2.2"></a>
# [3.2.2](https://github.com/webpack-contrib/sass-loader/compare/v3.2.2...v3.2.1) (2016-06-26)

### Bug Fixes

* Fix incorrect source map paths [#250](https://github.com/webpack-contrib/sass-loader/pull/250)


<a name="3.2.1"></a>
# [3.2.1](https://github.com/webpack-contrib/sass-loader/compare/v3.2.1...v3.2.0) (2016-06-19)

### Bug Fixes

* Add `webpack@^2.1.0-beta` as peer dependency [#233](https://github.com/webpack-contrib/sass-loader/pull/233)


<a name="3.2.0"></a>
# [3.2.0](https://github.com/webpack-contrib/sass-loader/compare/v3.2.0...v3.1.2) (2016-03-12)

### Features

* Append file content instead of overwriting when `data`-option is already present [#216](https://github.com/webpack-contrib/sass-loader/pull/216)
* Make `indentedSyntax` option a bit smarter [#196](https://github.com/webpack-contrib/sass-loader/pull/196)


<a name="3.1.2"></a>
# [3.1.2](https://github.com/webpack-contrib/sass-loader/compare/v3.1.2...v3.1.1) (2015-11-22)

### Bug Fixes

* Fix loader query not overriding webpack config [#189](https://github.com/webpack-contrib/sass-loader/pull/189)
* Update peer-dependencies [#182](https://github.com/webpack-contrib/sass-loader/pull/182)
- `node-sass^3.4.2`
- `webpack^1.12.6`


<a name="3.1.1"></a>
# [3.1.1](https://github.com/webpack-contrib/sass-loader/compare/v3.1.1...v3.1.0) (2015-10-26)

### Bug Fixes

* Fix missing module `object-assign` [#178](https://github.com/webpack-contrib/sass-loader/issues/178)


<a name="3.1.0"></a>
# [3.1.0](https://github.com/webpack-contrib/sass-loader/compare/v3.1.0...v3.0.0) (2015-10-25)

### Bug Fixes

* Fix a problem where modules with a `.` in their names were not resolved [#167](https://github.com/webpack-contrib/sass-loader/issues/167)


### Features

* Add possibility to also define all options in your `webpack.config.js` [#152](https://github.com/webpack-contrib/sass-loader/pull/152) [#170](https://github.com/webpack-contrib/sass-loader/pull/170)


<a name="3.0.0"></a>
# [3.0.0](https://github.com/webpack-contrib/sass-loader/compare/v3.0.0...v2.0.1) (2015-09-29)

### Bug Fixes

* Fix crash when Sass reported an error without `file` [#158](https://github.com/webpack-contrib/sass-loader/pull/158)


### BREAKING CHANGES

* Add `node-sass@^3.3.3` and `webpack@^1.12.2` as peer-dependency [#165](https://github.com/webpack-contrib/sass-loader/pull/165) [#166](https://github.com/webpack-contrib/sass-loader/pull/166) [#169](https://github.com/webpack-contrib/sass-loader/pull/169)


<a name="2.0.1"></a>
# [2.0.1](https://github.com/webpack-contrib/sass-loader/compare/v2.0.1...v2.0.0) (2015-08-14)

### Bug Fixes

* Add missing path normalization (fixes [#141](https://github.com/webpack-contrib/sass-loader/pull/141))


<a name="2.0.0"></a>
# [2.0.0](https://github.com/webpack-contrib/sass-loader/compare/v2.0.0...v1.0.4) (2015-08-06)

### Bug Fixes

* Add temporary fix for stuck processes (see [sass/node-sass#857](https://github.com/sass/node-sass/issues/857)) [#100](https://github.com/webpack-contrib/sass-loader/issues/100) [#119](https://github.com/webpack-contrib/sass-loader/issues/119) [#132](https://github.com/webpack-contrib/sass-loader/pull/132)
* Fix path resolving on Windows [#108](https://github.com/webpack-contrib/sass-loader/issues/108)
* Fix file watchers on Windows [#102](https://github.com/webpack-contrib/sass-loader/issues/102)
* Fix file watchers for files with errors [#134](https://github.com/webpack-contrib/sass-loader/pull/134)


### Code Refactoring

* Refactor [import resolving algorithm](https://github.com/webpack-contrib/sass-loader/blob/089c52dc9bd02ec67fb5c65c2c226f43710f231c/index.js#L293-L348). ([#138](https://github.com/webpack-contrib/sass-loader/issues/138)) ([c8621a1](https://github.com/webpack-contrib/sass-loader/commit/80944ccf09cd9716a100160c068d255c5d742338))


### BREAKING CHANGES

* The new algorithm is aligned to libsass' way of resolving files. This yields to different results if two files with the same path and filename but with different extensions are present. Though this change should be no problem for most users, we must flag it as breaking change. [#135](https://github.com/webpack-contrib/sass-loader/issues/135) [#138](https://github.com/webpack-contrib/sass-loader/issues/138)


<a name="1.0.4"></a>
# [1.0.4](https://github.com/webpack-contrib/sass-loader/compare/v1.0.4...v1.0.3) (2015-08-03)

### Bug Fixes

* Fix wrong source-map urls [#123](https://github.com/webpack-contrib/sass-loader/pull/123)
* Include source-map contents by default [#104](https://github.com/webpack-contrib/sass-loader/pull/104)


<a name="1.0.3"></a>
# [1.0.3](https://github.com/webpack-contrib/sass-loader/compare/v1.0.3...v1.0.2) (2015-07-22)

### Bug Fixes

* Fix importing css files from scss/sass [#101](https://github.com/webpack-contrib/sass-loader/issues/101)
* Fix importing Sass partials from includePath [#98](https://github.com/webpack-contrib/sass-loader/issues/98) [#110](https://github.com/webpack-contrib/sass-loader/issues/110)


<a name="1.0.2"></a>
# [1.0.2](https://github.com/webpack-contrib/sass-loader/compare/v1.0.2...v1.0.1) (2015-04-15)

### Bug Fixes

* Fix a bug where files could not be imported across language styles [#73](https://github.com/webpack-contrib/sass-loader/issues/73)
* Update peer-dependency `node-sass` to `3.1.0`


<a name="1.0.1"></a>
# [1.0.1](https://github.com/webpack-contrib/sass-loader/compare/v1.0.1...v1.0.0) (2015-03-31)

### Bug Fixes

* Fix Sass partials not being resolved anymore [#68](https://github.com/webpack-contrib/sass-loader/issues/68)
* Update peer-dependency `node-sass` to `3.0.0-beta.4`


<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/sass-loader/compare/v1.0.0...v0.3.1) (2015-03-22)

### Bug Fixes

* Moved `node-sass^3.0.0-alpha.0` to `peerDependencies` [#28](https://github.com/webpack-contrib/sass-loader/issues/28)
* Using webpack's module resolver as custom importer [#39](https://github.com/webpack-contrib/sass-loader/issues/31)
* Add synchronous compilation support for usage with [enhanced-require](https://github.com/webpack/enhanced-require) [#39](https://github.com/webpack-contrib/sass-loader/pull/39)
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2015 J. Tangelder
Copyright JS Foundation and other contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
292 changes: 184 additions & 108 deletions README.md

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
branches:
only:
- master
init:
- git config --global core.autocrlf input
environment:
matrix:
- nodejs_version: '8'
webpack_version: latest
job_part: test
- nodejs_version: '6'
webpack_version: latest
job_part: test
- nodejs_version: '4'
webpack_version: latest
job_part: test
build: 'off'
matrix:
fast_finish: true
install:
- ps: Install-Product node $env:nodejs_version x64
- npm i -g npm@^5.0.0
- npm install
before_test:
- cmd: npm i --no-save webpack@%webpack_version%
test_script:
- node --version
- npm --version
- cmd: npm run appveyor:%job_part%
393 changes: 0 additions & 393 deletions index.js

This file was deleted.

73 changes: 73 additions & 0 deletions lib/formatSassError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"use strict";

const path = require("path");
const os = require("os");
const fs = require("fs");

// A typical sass error looks like this
const SassError = { // eslint-disable-line no-unused-vars
message: "invalid property name",
column: 14,
line: 1,
file: "stdin",
status: 1
};

/**
* Enhances the sass error with additional information about what actually went wrong.
*
* @param {SassError} err
* @param {string} resourcePath
*/
function formatSassError(err, resourcePath) {
// Instruct webpack to hide the JS stack from the console
// Usually you're only interested in the SASS stack in this case.
err.hideStack = true;

// The file property is missing in rare cases.
// No improvement in the error is possible.
if (!err.file) {
return;
}

let msg = err.message;

if (err.file === "stdin") {
err.file = resourcePath;
}
// node-sass returns UNIX-style paths
err.file = path.normalize(err.file);

// The 'Current dir' hint of node-sass does not help us, we're providing
// additional information by reading the err.file property
msg = msg.replace(/\s*Current dir:\s*/, "");

err.message = getFileExcerptIfPossible(err) +
msg.charAt(0).toUpperCase() + msg.slice(1) + os.EOL +
" in " + err.file + " (line " + err.line + ", column " + err.column + ")";
}

/**
* Tries to get an excerpt of the file where the error happened.
* Uses err.line and err.column.
*
* Returns an empty string if the excerpt could not be retrieved.
*
* @param {SassError} err
* @returns {string}
*/
function getFileExcerptIfPossible(err) {
try {
const content = fs.readFileSync(err.file, "utf8");

return os.EOL +
content.split(os.EOL)[err.line - 1] + os.EOL +
new Array(err.column - 1).join(" ") + "^" + os.EOL +
" ";
} catch (err) {
// If anything goes wrong here, we don't want any errors to be reported to the user
return "";
}
}

module.exports = formatSassError;
58 changes: 58 additions & 0 deletions lib/importsToResolve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"use strict";

const path = require("path");

// libsass uses this precedence when importing files without extension
const extPrecedence = [".scss", ".sass", ".css"];

/**
* When libsass tries to resolve an import, it uses a special algorithm.
* Since the sass-loader uses webpack to resolve the modules, we need to simulate that algorithm. This function
* returns an array of import paths to try.
*
* @param {string} request
* @returns {Array<string>}
*/
function importsToResolve(request) {
// libsass' import algorithm works like this:
// In case there is no file extension...
// - Prefer modules starting with '_'.
// - File extension precedence: .scss, .sass, .css.
// In case there is a file extension...
// - If the file is a CSS-file, do not include it all, but just link it via @import url().
// - The exact file name must match (no auto-resolving of '_'-modules).

// Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.
// @see https://github.com/webpack-contrib/sass-loader/issues/167
const ext = path.extname(request);
const basename = path.basename(request);
const dirname = path.dirname(request);
const startsWithUnderscore = basename.charAt(0) === "_";
const hasCssExt = ext === ".css";
const hasSassExt = ext === ".scss" || ext === ".sass";

// a module import is an identifier like 'bootstrap-sass'
// We also need to check for dirname since it might also be a deep import like 'bootstrap-sass/something'
let isModuleImport = request.charAt(0) !== "." && dirname === ".";

if (dirname.charAt(0) === "@") {
// Check whether it is a deep import from scoped npm package
// (i.e. @pkg/foo/file), if so, process import as file import;
// otherwise, if we import from root npm scoped package (i.e. @pkg/foo)
// process import as a module import.
isModuleImport = !(dirname.indexOf("/") > -1);
}

return (isModuleImport && [request]) || // Do not modify module imports
(hasCssExt && []) || // Do not import css files
(hasSassExt && [request]) || // Do not modify imports with explicit extensions
(startsWithUnderscore ? [] : extPrecedence) // Do not add underscore imports if there is already an underscore
.map(ext => "_" + basename + ext)
.concat(
extPrecedence.map(ext => basename + ext)
).map(
file => dirname + "/" + file // No path.sep required here, because imports inside SASS are usually with /
);
}

module.exports = importsToResolve;
83 changes: 83 additions & 0 deletions lib/loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"use strict";

const sass = require("node-sass");
const path = require("path");
const async = require("neo-async");
const formatSassError = require("./formatSassError");
const webpackImporter = require("./webpackImporter");
const normalizeOptions = require("./normalizeOptions");
const pify = require("pify");

// This queue makes sure node-sass leaves one thread available for executing
// fs tasks when running the custom importer code.
// This can be removed as soon as node-sass implements a fix for this.
const threadPoolSize = process.env.UV_THREADPOOL_SIZE || 4;
const asyncSassJobQueue = async.queue(sass.render, threadPoolSize - 1);

/**
* The sass-loader makes node-sass available to webpack modules.
*
* @this {LoaderContext}
* @param {string} content
*/
function sassLoader(content) {
const callback = this.async();
const isSync = typeof callback !== "function";
const self = this;
const resourcePath = this.resourcePath;

function addNormalizedDependency(file) {
// node-sass returns POSIX paths
self.dependency(path.normalize(file));
}

if (isSync) {
throw new Error("Synchronous compilation is not supported anymore. See https://github.com/webpack-contrib/sass-loader/issues/333");
}

const options = normalizeOptions(this, content, webpackImporter(
resourcePath,
pify(this.resolve.bind(this)),
addNormalizedDependency
));

// Skip empty files, otherwise it will stop webpack, see issue #21
if (options.data.trim() === "") {
callback(null, "");
return;
}

// start the actual rendering
asyncSassJobQueue.push(options, (err, result) => {
if (err) {
formatSassError(err, this.resourcePath);
err.file && this.dependency(err.file);
callback(err);
return;
}

if (result.map && result.map !== "{}") {
result.map = JSON.parse(result.map);
// result.map.file is an optional property that provides the output filename.
// Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
delete result.map.file;
// The first source is 'stdin' according to node-sass because we've used the data input.
// Now let's override that value with the correct relative path.
// Since we specified options.sourceMap = path.join(process.cwd(), "/sass.map"); in normalizeOptions,
// we know that this path is relative to process.cwd(). This is how node-sass works.
result.map.sources[0] = path.relative(process.cwd(), resourcePath);
// node-sass returns POSIX paths, that's why we need to transform them back to native paths.
// This fixes an error on windows where the source-map module cannot resolve the source maps.
// @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
result.map.sourceRoot = path.normalize(result.map.sourceRoot);
result.map.sources = result.map.sources.map(path.normalize);
} else {
result.map = null;
}

result.stats.includedFiles.forEach(addNormalizedDependency);
callback(null, result.css.toString(), result.map);
});
}

module.exports = sassLoader;
78 changes: 78 additions & 0 deletions lib/normalizeOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"use strict";

const os = require("os");
const utils = require("loader-utils");
const cloneDeep = require("clone-deep");
const path = require("path");
const proxyCustomImporters = require("./proxyCustomImporters");

/**
* Derives the sass options from the loader context and normalizes its values with sane defaults.
*
* Please note: If loaderContext.query is an options object, it will be re-used across multiple invocations.
* That's why we must not modify the object directly.
*
* @param {LoaderContext} loaderContext
* @param {string} content
* @param {Function} webpackImporter
* @returns {Object}
*/
function normalizeOptions(loaderContext, content, webpackImporter) {
const options = cloneDeep(utils.getOptions(loaderContext)) || {};
const resourcePath = loaderContext.resourcePath;

options.data = options.data ? (options.data + os.EOL + content) : content;

// opt.outputStyle
if (!options.outputStyle && loaderContext.minimize) {
options.outputStyle = "compressed";
}

// opt.sourceMap
// Not using the `this.sourceMap` flag because css source maps are different
// @see https://github.com/webpack/css-loader/pull/40
if (options.sourceMap) {
// Deliberately overriding the sourceMap option here.
// node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
// In case it is a string, options.sourceMap should be a path where the source map is written.
// But since we're using the data option, the source map will not actually be written, but
// all paths in sourceMap.sources will be relative to that path.
// Pretty complicated... :(
options.sourceMap = path.join(process.cwd(), "/sass.map");
if ("sourceMapRoot" in options === false) {
options.sourceMapRoot = process.cwd();
}
if ("omitSourceMapUrl" in options === false) {
// The source map url doesn't make sense because we don't know the output path
// The css-loader will handle that for us
options.omitSourceMapUrl = true;
}
if ("sourceMapContents" in options === false) {
// If sourceMapContents option is not set, set it to true otherwise maps will be empty/null
// when exported by webpack-extract-text-plugin.
options.sourceMapContents = true;
}
}

// indentedSyntax is a boolean flag.
const ext = path.extname(resourcePath);

// If we are compiling sass and indentedSyntax isn't set, automatically set it.
if (ext && ext.toLowerCase() === ".sass" && "indentedSyntax" in options === false) {
options.indentedSyntax = true;
} else {
options.indentedSyntax = Boolean(options.indentedSyntax);
}

// Allow passing custom importers to `node-sass`. Accepts `Function` or an array of `Function`s.
options.importer = options.importer ? proxyCustomImporters(options.importer, resourcePath) : [];
options.importer.push(webpackImporter);

// `node-sass` uses `includePaths` to resolve `@import` paths. Append the currently processed file.
options.includePaths = options.includePaths || [];
options.includePaths.push(path.dirname(resourcePath));

return options;
}

module.exports = normalizeOptions;
29 changes: 29 additions & 0 deletions lib/proxyCustomImporters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use strict";

/**
* Creates new custom importers that use the given `resourcePath` if libsass calls the custom importer with `prev`
* being 'stdin'.
*
* Why do we need this? We have to use the `data` option of node-sass in order to compile our sass because
* the `resourcePath` might not be an actual file on disk. When using the `data` option, libsass uses the string
* 'stdin' instead of a filename.
*
* We have to fix this behavior in order to provide a consistent experience to the webpack user.
*
* @param {function|Array<function>} importer
* @param {string} resourcePath
* @returns {Array<function>}
*/
function proxyCustomImporters(importer, resourcePath) {
return [].concat(importer).map((importer) => {
return function (url, prev, done) {
return importer.apply(
this, // eslint-disable-line no-invalid-this
Array.from(arguments)
.map((arg, i) => i === 1 && arg === "stdin" ? resourcePath : arg)
);
};
});
}

module.exports = proxyCustomImporters;
73 changes: 73 additions & 0 deletions lib/webpackImporter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"use strict";

/**
* @name PromisedResolve
* @type {Function}
* @param {string} dir
* @param {string} request
* @returns Promise
*/

/**
* @name Importer
* @type {Function}
* @param {string} url
* @param {string} prev
* @param {Function<Error, string>} done
*/

const path = require("path");
const utils = require("loader-utils");
const tail = require("lodash.tail");
const importsToResolve = require("./importsToResolve");

const matchCss = /\.css$/;

/**
* Returns an importer that uses webpack's resolving algorithm.
*
* It's important that the returned function has the correct number of arguments
* (based on whether the call is sync or async) because otherwise node-sass doesn't exit.
*
* @param {string} resourcePath
* @param {PromisedResolve} resolve
* @param {Function<string>} addNormalizedDependency
* @returns {Importer}
*/
function webpackImporter(resourcePath, resolve, addNormalizedDependency) {
function dirContextFrom(fileContext) {
return path.dirname(
// The first file is 'stdin' when we're using the data option
fileContext === "stdin" ? resourcePath : fileContext
);
}

function startResolving(dir, importsToResolve) {
return importsToResolve.length === 0 ?
Promise.reject() :
resolve(dir, importsToResolve[0])
.then(resolvedFile => {
// Add the resolvedFilename as dependency. Although we're also using stats.includedFiles, this might come
// in handy when an error occurs. In this case, we don't get stats.includedFiles from node-sass.
addNormalizedDependency(resolvedFile);
return {
// By removing the CSS file extension, we trigger node-sass to include the CSS file instead of just linking it.
file: resolvedFile.replace(matchCss, "")
};
}, () => startResolving(
dir,
tail(importsToResolve)
));
}

return (url, prev, done) => {
startResolving(
dirContextFrom(prev),
importsToResolve(utils.urlToRequest(url))
) // Catch all resolving errors, return the original file and pass responsibility back to other custom importers
.catch(() => ({ file: url }))
.then(done);
};
}

module.exports = webpackImporter;
88 changes: 52 additions & 36 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,52 +1,68 @@
{
"name": "sass-loader",
"version": "4.0.0",
"version": "6.0.7",
"description": "Sass loader for webpack",
"main": "index.js",
"author": "J. Tangelder",
"license": "MIT",
"main": "lib/loader.js",
"files": [
"lib"
],
"scripts": {
"appveyor:test": "npm test",
"create-spec": "node test/tools/runCreateSpec.js",
"pretest": "node test/tools/runCreateSpec.js",
"test": "mocha -R spec",
"posttest": "jshint index.js test",
"lint": "eslint lib test",
"test": "nyc --all mocha -R spec -t 10000",
"test-bootstrap-sass": "webpack-dev-server --config test/bootstrapSass/webpack.config.js --content-base ./test/bootstrapSass",
"test-source-map": "webpack-dev-server --config test/sourceMap/webpack.config.js --content-base ./test/sourceMap",
"test-source-map": "webpack-dev-server --config test/sourceMap/webpack.config.js --content-base ./test/sourceMap --inline",
"test-watch": "webpack --config test/watch/webpack.config.js",
"test-extract-text": "webpack --config test/extractText/webpack.config.js",
"test-hmr": "webpack-dev-server --config test/hmr/webpack.config.js --content-base ./test/hmr --hot --inline",
"test-spec": "mocha -R spec test/spec.test.js"
"travis:lint": "npm run lint",
"travis:test": "npm run test",
"travis:coverage": "npm run test",
"pretest": "npm run create-spec",
"posttest": "npm run lint",
"release": "standard-version"
},
"dependencies": {
"clone-deep": "^2.0.1",
"loader-utils": "^1.0.1",
"lodash.tail": "^4.1.1",
"neo-async": "^2.5.0",
"pify": "^3.0.0"
},
"devDependencies": {
"bootstrap-sass": "^3.3.5",
"css-loader": "^0.28.4",
"eslint": "^3.16.0",
"eslint-config-peerigon": "^9.0.0",
"eslint-plugin-jsdoc": "^2.4.0",
"file-loader": "^0.11.2",
"mocha": "^3.0.2",
"node-sass": "^4.5.0",
"nyc": "^11.0.2",
"raw-loader": "^0.5.1",
"should": "^11.2.0",
"standard-version": "^4.2.0",
"style-loader": "^0.18.2",
"webpack-dev-server": "^2.4.1",
"webpack-merge": "^4.0.0"
},
"engines": {
"node": ">= 4.3 < 5.0.0 || >= 5.10"
},
"peerDependencies": {
"node-sass": "^4.0.0",
"webpack": "^2.0.0 || ^3.0.0 || ^4.0.0"
},
"keywords": [
"sass",
"libsass",
"webpack",
"loader"
],
"repository": {
"type": "git",
"url": "git://github.com/jtangelder/sass-loader.git"
},
"author": "J. Tangelder",
"license": "MIT",
"peerDependencies": {
"node-sass": "^3.4.2",
"webpack": "^1.12.6 || ^2.1.0-beta"
},
"dependencies": {
"async": "^1.4.0",
"loader-utils": "^0.2.15",
"object-assign": "^4.1.0"
},
"devDependencies": {
"bootstrap-sass": "^3.3.5",
"css-loader": "^0.23.0",
"enhanced-require": "^0.5.0-beta6",
"file-loader": "^0.8.4",
"jshint": "^2.9.2",
"mocha": "^2.5.3",
"node-sass": "^3.8.0",
"raw-loader": "^0.5.1",
"should": "^9.0.2",
"style-loader": "^0.13.1",
"webpack": "^1.13.1",
"webpack-dev-server": "^1.7.0"
}
"repository": "https://github.com/webpack-contrib/sass-loader.git",
"bugs": "https://github.com/webpack-contrib/sass-loader/issues",
"homepage": "https://github.com/webpack-contrib/sass-loader"
}
5 changes: 5 additions & 0 deletions test/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": [
"peerigon/tests"
]
}
45 changes: 27 additions & 18 deletions test/bootstrapSass/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
'use strict';
"use strict";

var path = require('path');

var pathToSassLoader = path.resolve(__dirname, '../../index.js');
const path = require("path");
const sassLoader = require.resolve("../../lib/loader");

module.exports = {
entry: path.resolve(__dirname, '../scss/bootstrap-sass.scss'),
entry: path.resolve(__dirname, "../scss/bootstrap-sass.scss"),
output: {
path: path.resolve(__dirname, '../output'),
filename: 'bundle.bootstrap-sass.js'
path: path.resolve(__dirname, "../output"),
filename: "bundle.bootstrap-sass.js"
},
devtool: 'inline-source-map',
devtool: "source-map",
module: {
loaders: [
{
test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
loader: 'file'
},
{
test: /\.scss$/,
loader: 'style-loader!css-loader!' + pathToSassLoader
}
]
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: sassLoader,
options: {
includePaths: [
path.resolve(__dirname, "../scss/includePath")
]
}
}]
}, {
test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
use: [{
loader: "file-loader"
}]
}]
}
};
34 changes: 34 additions & 0 deletions test/extractText/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use strict";

const path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const sassLoader = require.resolve("../../lib/loader");

const extractSass = new ExtractTextPlugin({
filename: "[name].[contenthash].css",
disable: process.env.NODE_ENV === "development"
});

module.exports = {
entry: require.resolve("../scss/language.scss"),
output: {
path: path.resolve(__dirname, "../output"),
filename: "bundle.extractText.js"
},
module: {
rules: [{
test: /\.scss$/,
loader: extractSass.extract({
loader: [{
loader: "css-loader"
}, {
loader: sassLoader
}],
fallbackLoader: "style-loader"
})
}]
},
plugins: [
extractSass
]
};
11 changes: 6 additions & 5 deletions test/hmr/entry.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict';
"use strict";

require('../scss/language.scss');
require('./simple.css');
/* global document */

setInterval(function () {
document.body.innerHTML += '<br>Now we just change the DOM, so that we can ensure that webpack is not just reloading the page';
require("./simple.scss");

setInterval(() => {
document.body.innerHTML += "<br>Now we just change the DOM, so that we can ensure that webpack is not just reloading the page";
}, 2000);
7 changes: 7 additions & 0 deletions test/hmr/simple.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
$color: black;
$background: hotpink;

body {
color: $color;
background: $background;
}
41 changes: 17 additions & 24 deletions test/hmr/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
'use strict';
"use strict";

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

var pathToSassLoader = path.resolve(__dirname, '../../index.js');
const path = require("path");
const sassLoader = require.resolve("../../lib/loader");

module.exports = {
entry: path.resolve(__dirname, './entry.js'),
entry: path.resolve(__dirname, "./entry.js"),
output: {
path: path.resolve(__dirname, '../output'),
filename: 'bundle.hmr.js'
path: path.resolve(__dirname, "../output"),
filename: "bundle.hmr.js"
},
module: {
loaders: [
{
test: /\.scss$/,
loader: 'style!css!' + pathToSassLoader
},
{
test: /\.css$/,
loader: 'style!css'
}
]
},
debug: true,
watch: true,
plugins: [
new webpack.HotModuleReplacementPlugin()
]
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: sassLoader
}]
}]
}
};
450 changes: 237 additions & 213 deletions test/index.test.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions test/node_modules/@org/bar/_foo.scss
3 changes: 3 additions & 0 deletions test/node_modules/@org/pkg/index.scss
4 changes: 4 additions & 0 deletions test/node_modules/@org/pkg/package.json
1 change: 0 additions & 1 deletion test/output/.gitignore

This file was deleted.

1 change: 1 addition & 0 deletions test/sass/another/variables.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$n-ary-summation: '\2211'
Empty file added test/sass/empty.sass
Empty file.
7 changes: 7 additions & 0 deletions test/sass/import-from-npm-org-pkg.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* @import ~@org/pkg */
@import ~@org/pkg
/* @import ~@org/bar/foo */
@import ~@org/bar/foo

.foo
background: #000;
1 change: 1 addition & 0 deletions test/sass/import-include-paths.sass
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
@import include-path-module
@import underscore-include-path-module
@import animate.css/animate
12 changes: 8 additions & 4 deletions test/sass/imports.sass
Original file line number Diff line number Diff line change
@@ -2,10 +2,14 @@
@import another/module
/* @import another/underscore */
@import another/underscore
/* @import ~sass/underscore */
@import ~sass/underscore
// Import a module with a dot in its name
// @see https://github.com/jtangelder/sass-loader/issues/167
// @see https://github.com/webpack-contrib/sass-loader/issues/167
/* @import ~sass/some.module */
@import ~sass/some.module
/* @import ~sass/underscore */
@import ~sass/underscore
@import url(http://example.com/something/from/the/interwebs)
// @see https://github.com/webpack-contrib/sass-loader/issues/360
/* @import ~animate.css/animate */
@import ~animate.css/animate
/* @import url(http://example.com/something/from/the/interwebs); */
@import url(http://example.com/something/from/the/interwebs);
3 changes: 3 additions & 0 deletions test/sass/includePath/animate.css/animate.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.animate-css {
background: hotpink;
}
11 changes: 11 additions & 0 deletions test/sass/language.sass
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
@import "another/variables"

$font-stack: Helvetica, sans-serif
$primary-color: #333
$pi: '\e0C6'

body
font: 100% $font-stack
@@ -45,3 +48,11 @@ nav
@extend .message
border-color: yellow

.foo
&:before
content: $pi

.bar
&:before
content: $n-ary-summation

1 change: 1 addition & 0 deletions test/scss/another/_variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$n-ary-summation: '\2211'
Empty file added test/scss/empty.scss
Empty file.
4 changes: 3 additions & 1 deletion test/scss/error.scss
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.syntax-error''
.syntax-error {
some-value
}
8 changes: 8 additions & 0 deletions test/scss/import-from-npm-org-pkg.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* @import "~@org/pkg"; */
@import "~@org/pkg";
/* @import "~@org/bar/foo"; */
@import "~@org/bar/foo";

.foo {
background: #000;
}
1 change: 1 addition & 0 deletions test/scss/import-include-paths.scss
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
@import "include-path-module";
@import "underscore-include-path-module";
@import "animate.css/animate";
14 changes: 11 additions & 3 deletions test/scss/imports.scss
Original file line number Diff line number Diff line change
@@ -2,10 +2,18 @@
@import "another/module";
/* @import "another/underscore"; */
@import "another/underscore";
/* @import "~scss/underscore"; */
@import "~scss/underscore";
// Import a module with a dot in its name
// @see https://github.com/jtangelder/sass-loader/issues/167
// @see https://github.com/webpack-contrib/sass-loader/issues/167
/* @import "~scss/some.module"; */
@import "~scss/some.module";
/* @import "~t~scss/underscore"; */
@import "~scss/underscore";
// @see https://github.com/webpack-contrib/sass-loader/issues/360
/* @import "~animate.css/animate"; */
@import "~animate.css/animate";
/* @import url(http://example.com/something/from/the/interwebs); */
@import url(http://example.com/something/from/the/interwebs);
/* scoped import @import "language"; */
.scoped-import {
@import "language";
}
3 changes: 3 additions & 0 deletions test/scss/includePath/animate.css/animate.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.animate-css {
background: hotpink;
}
15 changes: 15 additions & 0 deletions test/scss/language.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
@import "another/variables";

$font-stack: Helvetica, sans-serif;
$primary-color: #333;
$pi: '\e0C6';

body {
font: 100% $font-stack;
@@ -30,3 +33,15 @@ nav {
}

.box { @include border-radius(10px); }

.foo {
&:before {
content: $pi;
}
}

.bar {
&:before {
content: $n-ary-summation;
}
}
1 change: 1 addition & 0 deletions test/scss/multipleCompilations/a.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "../imports";
1 change: 1 addition & 0 deletions test/scss/multipleCompilations/b.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "../imports";
1 change: 1 addition & 0 deletions test/scss/multipleCompilations/c.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "../imports";
1 change: 1 addition & 0 deletions test/scss/multipleCompilations/d.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "../imports";
1 change: 1 addition & 0 deletions test/scss/multipleCompilations/e.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "../imports";
1 change: 1 addition & 0 deletions test/scss/multipleCompilations/f.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "../imports";
1 change: 1 addition & 0 deletions test/scss/multipleCompilations/g.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "../imports";
1 change: 1 addition & 0 deletions test/scss/multipleCompilations/h.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "../imports";
3 changes: 0 additions & 3 deletions test/sourceMap/entry.js

This file was deleted.

4 changes: 2 additions & 2 deletions test/sourceMap/index.html
Original file line number Diff line number Diff line change
@@ -3,9 +3,9 @@
<head>
<title></title>
<meta charset="utf-8"/>
<script async src="/bundle.sourcemap.js"></script>
<script async src="/bundle.js"></script>
</head>
<body>
<body class="scoped-import">
<h1 class="another-scss-module box">Open the developer tools, dude!</h1>
</body>
</html>
34 changes: 20 additions & 14 deletions test/sourceMap/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
'use strict';
"use strict";

var path = require('path');

var pathToSassLoader = path.resolve(__dirname, '../../index.js');
const path = require("path");
const sassLoader = require.resolve("../../lib/loader");

module.exports = {
entry: path.resolve(__dirname, './entry.js'),
entry: path.resolve(__dirname, "..", "scss", "imports.scss"),
output: {
path: path.resolve(__dirname, '../output'),
filename: 'bundle.sourcemap.js'
filename: "bundle.js"
},
devtool: 'inline-source-map',
devtool: "source-map",
module: {
loaders: [
{
test: /\.scss$/,
loaders: ['style', 'css-loader?sourceMap', pathToSassLoader + '?sourceMap']
}
]
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader", options: {
sourceMap: true
}
}, {
loader: sassLoader, options: {
sourceMap: true
}
}]
}]
}
};
47 changes: 22 additions & 25 deletions test/spec.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'use strict';
"use strict";

/**
* This file can be used to track changes in the spec introduced by newer node-sass versions.
@@ -10,24 +10,24 @@
* 2. Run `npm run create-spec`
* 3. Now install the new version of node-sass
* 4. Remove .skip( from describe-block in this file to activate the test
* 5. Run `npm run test-spec`
* 5. Run `npm run test`
*/

var should = require('should');
var fs = require('fs');
var path = require('path');
var createSpec = require('./tools/createSpec.js');
require("should");
const fs = require("fs");
const path = require("path");
const createSpec = require("./tools/createSpec.js");

var testFolder = __dirname;
var matchCss = /\.css$/;
const testFolder = __dirname;
const matchCss = /\.css$/;

function readSpec(folder) {
var result = {};
const result = {};

fs.readdirSync(folder)
.forEach(function (file) {
.forEach((file) => {
if (matchCss.test(file)) {
result[file] = fs.readFileSync(path.join(folder, file), 'utf8');
result[file] = fs.readFileSync(path.join(folder, file), "utf8");
}
});

@@ -36,33 +36,30 @@ function readSpec(folder) {

function writeSpec(folder, spec) {
Object.keys(spec)
.forEach(function (specName) {
fs.writeFileSync(path.resolve(folder, specName), spec[specName], 'utf8');
.forEach((specName) => {
fs.writeFileSync(path.resolve(folder, specName), spec[specName], "utf8");
});
}

['scss', 'sass'].forEach(function (ext) {
["scss", "sass"].forEach((ext) => {
describe(ext + " spec", () => {
const specFolder = path.resolve(testFolder, ext, "spec");
const oldSpec = readSpec(specFolder);

describe.skip(ext + ' spec', function () {
var specFolder = path.resolve(testFolder, ext, 'spec');
var oldSpec;
var newSpec;

oldSpec = readSpec(specFolder);
createSpec(ext);
newSpec = readSpec(specFolder);

const newSpec = readSpec(specFolder);

Object.keys(oldSpec)
.forEach(function (specName) {
it(specName + ' should not have been changed', function () {
.forEach((specName) => {
it(specName + " should not have been changed", () => {
oldSpec[specName].should.eql(newSpec[specName]);
});
});

after(function () {
after(() => {
// Write old spec back to the folder so that future tests will also fail
writeSpec(specFolder, oldSpec);
});
});

});
56 changes: 28 additions & 28 deletions test/tools/createSpec.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,37 @@
'use strict';
"use strict";

var sass = require('node-sass');
var os = require('os');
var fs = require('fs');
var path = require('path');
var customImporter = require('./customImporter.js');
var customFunctions = require('./customFunctions.js');
const sass = require("node-sass");
const os = require("os");
const fs = require("fs");
const path = require("path");
const customImporter = require("./customImporter.js");
const customFunctions = require("./customFunctions.js");

var testFolder = path.resolve(__dirname, '../');
var error = 'error';
const testFolder = path.resolve(__dirname, "../");
const error = "error";

function createSpec(ext) {
var basePath = path.join(testFolder, ext);
var testNodeModules = path.relative(basePath, path.join(testFolder, 'node_modules')) + path.sep;
var pathToBootstrap = path.relative(basePath, path.resolve(testFolder, '..', 'node_modules', 'bootstrap-sass'));
const basePath = path.join(testFolder, ext);
const testNodeModules = path.relative(basePath, path.join(testFolder, "node_modules")) + path.sep;
const pathToBootstrap = path.relative(basePath, path.resolve(testFolder, "..", "node_modules", "bootstrap-sass"));
const pathToScopedNpmPkg = path.relative(basePath, path.resolve(testFolder, "node_modules", "@org", "pkg", "./index.scss"));

fs.readdirSync(path.join(testFolder, ext))
.filter(function (file) {
return path.extname(file) === '.' + ext && file.slice(0, error.length) !== error;
.filter((file) => {
return path.extname(file) === "." + ext && file.slice(0, error.length) !== error;
})
.map(function (file) {
var fileName = path.join(basePath, file);
var fileWithoutExt = file.slice(0, -ext.length - 1);
var sassOptions;
var css;

sassOptions = {
importer: function (url) {
if (url === 'import-with-custom-logic') {
.map((file) => {
const fileName = path.join(basePath, file);
const fileWithoutExt = file.slice(0, -ext.length - 1);
const sassOptions = {
importer(url) {
if (url === "import-with-custom-logic") {
return customImporter.returnValue;
}
if (/\.css$/.test(url) === false) { // Do not transform css imports
url = url
.replace(/^~bootstrap-sass/, pathToBootstrap)
.replace(/^~@org\/pkg/, pathToScopedNpmPkg)
.replace(/^~/, testNodeModules);
}
return {
@@ -41,20 +40,21 @@ function createSpec(ext) {
},
functions: customFunctions,
includePaths: [
path.join(testFolder, ext, 'another'),
path.join(testFolder, ext, 'from-include-path')
path.join(testFolder, ext, "another"),
path.join(testFolder, ext, "includePath")
]
};

if (/prepending-data/.test(fileName)) {
sassOptions.data = '$prepended-data: hotpink;' + os.EOL + fs.readFileSync(fileName, 'utf8');
sassOptions.data = "$prepended-data: hotpink;" + os.EOL + fs.readFileSync(fileName, "utf8");
sassOptions.indentedSyntax = /\.sass$/.test(fileName);
} else {
sassOptions.file = fileName;
}

css = sass.renderSync(sassOptions).css;
fs.writeFileSync(path.join(basePath, 'spec', fileWithoutExt + '.css'), css, 'utf8');
const css = sass.renderSync(sassOptions).css;

fs.writeFileSync(path.join(basePath, "spec", fileWithoutExt + ".css"), css, "utf8");
});
}

16 changes: 8 additions & 8 deletions test/tools/customFunctions.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
'use strict';
"use strict";

var sass = require('node-sass');
const sass = require("node-sass");

module.exports = {
'headings($from: 0, $to: 6)': function (from, to) {
var f = from.getValue();
var t = to.getValue();
var list = new sass.types.List(t - f + 1);
var i;
"headings($from: 0, $to: 6)"(from, to) {
const f = from.getValue();
const t = to.getValue();
const list = new sass.types.List(t - f + 1);
let i;

for (i = f; i <= t; i++) {
list.setValue(i - f, new sass.types.String('h' + i));
list.setValue(i - f, new sass.types.String("h" + i));
}

return list;
15 changes: 10 additions & 5 deletions test/tools/customImporter.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
'use strict';
"use strict";

var should = require('should');
require("should");

function customImporter(path, prev) {
path.should.equal("import-with-custom-logic");
prev.should.match(/(sass|scss)[/\\]custom-importer\.(scss|sass)/);

this.should.have.property("options"); // eslint-disable-line no-invalid-this

function customImporter(path) {
path.should.equal('import-with-custom-logic');
return customImporter.returnValue;
}

customImporter.returnValue = {
contents: '.custom-imported {}'
contents: ".custom-imported {}"
};

module.exports = customImporter;
6 changes: 3 additions & 3 deletions test/tools/runCreateSpec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
"use strict";

var createSpec = require('./createSpec.js');
const createSpec = require("./createSpec.js");

['scss', 'sass'].forEach(function (ext) {
["scss", "sass"].forEach((ext) => {
createSpec(ext);
});
14 changes: 14 additions & 0 deletions test/tools/testLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"use strict";

function testLoader(content, sourceMap) {
testLoader.content = content;
testLoader.sourceMap = sourceMap;

return "";
}

testLoader.content = "";
testLoader.sourceMap = null;
testLoader.filename = __filename;

module.exports = testLoader;
4 changes: 2 additions & 2 deletions test/watch/entry.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
'use strict';
"use strict";

require('../scss/imports.scss');
require("../scss/imports.scss");
36 changes: 22 additions & 14 deletions test/watch/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
'use strict';
"use strict";

var path = require('path');

var pathToSassLoader = path.resolve(__dirname, '../../index.js');
const path = require("path");
const sassLoader = require.resolve("../../lib/loader");

module.exports = {
entry: [
path.resolve(__dirname, '../scss/imports.scss'),
path.resolve(__dirname, '../scss/import-include-paths.scss')
path.resolve(__dirname, "../scss/imports.scss"),
path.resolve(__dirname, "../scss/import-include-paths.scss")
],
output: {
path: path.resolve(__dirname, '../output'),
filename: 'bundle.watch.js'
path: path.resolve(__dirname, "../output"),
filename: "bundle.watch.js"
},
watch: true,
module: {
loaders: [
{
test: /\.scss$/,
loader: 'css-loader!' + pathToSassLoader + '?includePaths[]=' + encodeURIComponent(path.resolve(__dirname, '../scss/from-include-path'))
}
]
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: sassLoader,
options: {
includePaths: [
path.resolve(__dirname, "../scss/includePath")
]
}
}]
}]
}
};