├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── lib └── index.js ├── package-lock.json ├── package.json └── test ├── fixtures ├── basic │ ├── expected │ │ ├── main.css │ │ └── oldfile.css │ └── src │ │ ├── main.scss │ │ └── oldfile.css ├── dotfiles │ ├── expected │ │ └── goodfile.css │ └── src │ │ ├── .badfile.scss │ │ └── goodfile.scss ├── front-matter │ ├── expected │ │ └── front-matter.css │ └── src │ │ └── front-matter.scss ├── functions │ ├── expected │ │ └── functions.css │ └── src │ │ └── functions.scss ├── imports │ ├── expected │ │ └── css │ │ │ └── main.css │ └── src │ │ └── css │ │ ├── main.scss │ │ └── vendor │ │ └── _part.scss ├── invalid │ └── src │ │ └── invalid.scss ├── maps │ ├── expected │ │ └── css │ │ │ ├── main.css │ │ │ └── main.css.map │ └── src │ │ └── css │ │ ├── main.scss │ │ └── vendor │ │ └── _part.scss ├── outputDir │ ├── expected │ │ └── nested │ │ │ ├── main.css │ │ │ └── sub │ │ │ └── subpage.css │ └── src │ │ └── scss │ │ ├── main.scss │ │ └── sub │ │ └── subpage.scss ├── partials │ ├── expected │ │ ├── main.css │ │ └── not_partial.css │ └── src │ │ ├── _partial.scss │ │ ├── _partial_with_underscore.scss │ │ ├── main.scss │ │ └── not_partial.scss └── sass-type │ ├── expected │ └── main.css │ └── src │ └── main.sass └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | npm-debug.log 15 | node_modules 16 | 17 | build/ 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | compiler: 3 | - gcc 4 | node_js: 5 | - "node" 6 | - "lts/*" 7 | before_install: 8 | - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; 9 | - sudo apt-get update; 10 | - sudo apt-get install gcc-4.8 g++-4.8; 11 | - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 20; 12 | - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 20; 13 | - sudo g++ --version; 14 | - sudo apt-get update -qq; 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [v2.0.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v2.0.0) 4 | 5 | _01/06/2022_ 6 | 7 | **BREAKING CHANGE:** `node-sass` has been changed from a direct dependency to a [peer dependency](https://nodejs.org/es/blog/npm/peer-dependencies/). If you are upgrading from v1.x.x, you may need to install it directly in your project using `npm install --save node-sass`. 8 | 9 | * Changed `node-sass` to a peer dependency. This gives you direct control over which version of `node-sass` you want to use in your project going forward. No more waiting for metalsmith-sass releases! 10 | * Upgraded dependencies and resolved vulnerabilities. 11 | * Remove test files from npm distribution. 12 | * Enable support for all versions of Node.js supported by node-sass. Going forward, whichever version of node-sass you install will determine your Node.js support. See [node-sass' version support policy](https://github.com/sass/node-sass#node-version-support-policy) for details. 13 | 14 | ## [v1.7.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v1.7.0) 15 | 16 | _11/21/2019_ 17 | 18 | - Enable support for Node.js version 12/13 by upgrading to [node-sass v4.13.0](https://github.com/sass/node-sass/releases/tag/v4.13.0) - thanks [@nickcolley](https://github.com/nickcolley). 19 | 20 | ## [v1.6.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v1.6.0) 21 | 22 | _01/20/2018_ 23 | 24 | - Updated to [node-sass v4.11](https://github.com/sass/node-sass/releases/tag/v4.11.0). 25 | - Fixed performance issue with calling `toString()` on non-sass files. Thanks @crazy2be! #47 :tada: 26 | 27 | ## [v1.4.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v1.4.0) 28 | 29 | _01/09/2017_ 30 | 31 | - Updated to [node-sass v4.2](https://github.com/sass/node-sass/releases/tag/v4.2.0). Thanks @shouze! #40 :tada: 32 | 33 | ## [v1.3.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v1.3.0) 34 | 35 | _07/20/2015_ 36 | 37 | - Support for Metalsmith v2 38 | - Nicer error messaging, thanks @callym! #26 39 | 40 | ## [v1.2.1](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v1.2.1) 41 | 42 | _06/10/2015_ 43 | 44 | - README updates 45 | 46 | ## [v1.2.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v1.2.0) 47 | 48 | _06/10/2015_ 49 | 50 | - Added support for `.sass` files! :tada: 51 | 52 | ## [v1.1.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v1.1.0) 53 | 54 | _06/08/2015_ 55 | 56 | - Added support for using a function in the `outputDir` option. Useful for preserving folder structure instead of just aggregating everything into a single folder. 57 | 58 | ## [v1.0.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v1.0.0) 59 | 60 | _05/25/2015_ 61 | 62 | - Updated to [node-sass v3.0](https://github.com/sass/node-sass/releases/tag/v3.0.0) :tada: 63 | - Added support for [source maps](https://github.com/stevenschobert/metalsmith-sass/blob/b162dd7c6ae6e5c6ee858e4db7bfc2a5c6393a85/README.md#source-maps). 64 | - All options now get passed through to node-sass (no more manual updates for new options!) 65 | 66 | ## [v0.7.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v0.7.0) 67 | 68 | _02/21/2015_ 69 | 70 | - Upgrades to [node-sass v2.0.1](https://github.com/sass/node-sass/releases/tag/v2.0.1) 71 | - Adds support for node v0.12 72 | 73 | ## [v0.6.1](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v0.6.1) 74 | 75 | _01/30/2015_ 76 | 77 | - Compilation errors are now reported correctly through Metalsmith CLI. 78 | 79 | ## [v0.6.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v0.6.0) 80 | 81 | _01/29/2015_ 82 | 83 | - Switched node-sass compilation to use buffers instead of file paths. This enables other plugins (like yaml front-matter) to work properly. See #14. 84 | - Upgrade node-sass to v1.2 85 | 86 | ## [v0.5.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v0.5.0) 87 | 88 | _11/05/2014_ 89 | 90 | - Any errors encountered when compiling sass files are now capture-able through Metalsmith's `.build(function(err, files) {})` method. Thank you @ubenzer for the contribution ([#12](https://github.com/stevenschobert/metalsmith-sass/pull/12))! 91 | 92 | ## [v0.4.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v0.4.0) 93 | 94 | _10/17/2014_ 95 | 96 | This release updates [libsass](https://github.com/sass/libsass/) (the underlying sass library) to [v3.0](https://github.com/sass/libsass/releases/tag/3.0), which includes **tons** of major fixes and improvements. 97 | 98 | ##### Check out the [Libsass v3.0 release notes](https://github.com/sass/libsass/releases/tag/3.0) for a detailed list of updates. 99 | 100 | --- 101 | 102 | - Update to [node-sass v1.0](https://github.com/sass/node-sass/releases/tag/v1.0.0). 103 | 104 | ## [v0.3.1](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v0.3.1) 105 | 106 | _10/07/2014_ 107 | 108 | - Support for **Metalsmith v1.0**. 109 | 110 | ## [v0.3.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v0.3.0) 111 | 112 | _07/05/2014_ 113 | 114 | - Now uses libsass 2.0. See the [node-sass changelog](https://github.com/sass/node-sass/releases/tag/v0.9.0). 115 | - Dotfiles are now ignored in builds. 116 | 117 | ## [v0.2.1](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v0.2.1) 118 | 119 | _06/23/2014_ 120 | 121 | - Fixed an issue that was causing filenames with underscores (e.g. `my_file.scss`) to incorrectly be treated as partials. 122 | 123 | ## [v0.2.0](https://github.com/stevenschobert/metalsmith-sass/releases/tag/v0.2.0) 124 | 125 | _06/09/2014_ 126 | 127 | - Partials are now properly ignored (thanks [@dpisklov](https://github.com/dpisklov)!). Addresses #1 and #2. 128 | - Added an `outputDir` option. Can be used in combination with `Metalsmith.destination()` to control output paths for stylesheets. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Steven Schobert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | metalsmith-sass 2 | =============== 3 | 4 | [![Build Status](https://app.travis-ci.com/stevenschobert/metalsmith-sass.svg?branch=master)](https://app.travis-ci.com/stevenschobert/metalsmith-sass) 5 | 6 | A Sass plugin for Metalsmith. 7 | 8 | ## Installation 9 | 10 | ```sh 11 | npm install --save metalsmith-sass node-sass 12 | ``` 13 | 14 | > Note: As of [v2.0](https://github.com/stevenschobert/metalsmith-sass/releases/v2.0.0), `node-sass` is listed as a peer dependency, and will need to be installed alongside metalsmith-sass as shown above. 15 | 16 | ## Getting Started 17 | 18 | If you haven't checked out [Metalsmith](http://metalsmith.io/) before, head over to their website and check out the 19 | documentation. 20 | 21 | ## CLI Usage 22 | 23 | If you are using the command-line version of Metalsmith, you can install via npm, and then add the 24 | `metalsmith-sass` key to your `metalsmith.json` file: 25 | 26 | ```json 27 | { 28 | "plugins": { 29 | "metalsmith-sass": { 30 | "outputStyle": "expanded" 31 | } 32 | } 33 | } 34 | ``` 35 | 36 | ## JavaScript API 37 | 38 | If you are using the JS Api for Metalsmith, then you can require the module and add it to your 39 | `.use()` directives: 40 | 41 | ```js 42 | var sass = require("metalsmith-sass"); 43 | 44 | metalsmith.use(sass({ 45 | outputStyle: "expanded" 46 | })); 47 | ``` 48 | 49 | ## Options 50 | 51 | See [node-sass](https://github.com/andrew/node-sass) for a complete list of supported options. 52 | 53 | In addition to the options that node-sass provides, metalsmith-sass provides the following options: 54 | 55 | ### outputDir 56 | 57 | Change the base folder path styles are output to. You can use this in combination with 58 | Metalsmith's `destination` option to control where styles end up after the build. 59 | 60 | The final output directory is equal to `Metalsmith.destination() + outputDirOption`. For example, 61 | the following setup output styles to `build/css/` even though the source files are in `src/scss/`: 62 | 63 | ```js 64 | Metalsmith() 65 | .source("src/") 66 | .destination("build/") 67 | .use(sass({ 68 | outputDir: "css/" // This changes the output dir to "build/css/" instead of "build/scss/" 69 | })) 70 | .build(function () { 71 | done(); 72 | }); 73 | ``` 74 | 75 | As of version [v1.1](https://github.com/stevenschobert/metalsmith-sass/releases/v1.1.0), you can also use a function to dynamically manipulate the output dir. 76 | 77 | This is useful if you want to preserve your folder structure, but change just one folder name. 78 | 79 | ```js 80 | Metalsmith(__dirname) 81 | .source("src/") 82 | .destination("build/") 83 | .use(sass({ 84 | outputDir: function(originalPath) { 85 | // this will change scss/some/path to css/some/path 86 | return originalPath.replace("scss", "css"); 87 | } 88 | })) 89 | .build(function () { 90 | done(); 91 | }); 92 | ``` 93 | 94 | ## Source Maps 95 | 96 | The easiest way to enable source maps in your metalsmith project is to add the following options: 97 | 98 | ```js 99 | Metalsmith(__dirname) 100 | .source("src/") 101 | .destination("build/") 102 | .use(sass({ 103 | sourceMap: true, 104 | sourceMapContents: true // This will embed all the Sass contents in your source maps. 105 | })) 106 | .build(function () { 107 | done(); 108 | }); 109 | ``` 110 | 111 | Though the `sourceMapContents` is not required, I recommend adding it, otherwise you'll need to 112 | manually serve up your `.scss` files along with your compiled `.css` files when you publish your 113 | site. 114 | 115 | ## .sass files 116 | 117 | As of version [v1.2](https://github.com/stevenschobert/metalsmith-sass/releases/v1.2.0), 118 | metalsmith-sass automatically handles `.sass` files, so you don't need to specify the `indentedSyntax` 119 | option. Though you might still need set options for `indentType` and `indentWidth` if you are 120 | using something other than 2 spaces for indentation. 121 | 122 | ## Credits 123 | 124 | Thanks to [Segment.io](http://github.com/segmentio) for creating and open-sourcing 125 | [Metalsmith](https://github.com/segmentio/metalsmith)! Also thanks to the whole community behind 126 | the [node-sass](https://github.com/andrew/node-sass) project. 127 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var sass = require('node-sass'), 5 | each = require('async/each'), 6 | path = require('path'), 7 | 8 | // from https://gist.github.com/stevenschobert/ca76531b46f2ac00cbd8 9 | extend = function extend() { 10 | var args = [].slice.call(arguments); 11 | args[0] = (typeof args[0] === 'object') ? args[0] : {}; 12 | 13 | for (var i=1; i ', 82 | err.file, 83 | ':', 84 | err.line, ':', err.column 85 | ].join('')); 86 | } else if (err) { 87 | error = new Error(err); 88 | } 89 | 90 | if (error) { 91 | done(error); 92 | return; 93 | } 94 | 95 | // add soure map 96 | if (result.map) { 97 | files[dest+'.map'] = { 98 | contents: result.map, 99 | mode: file.mode 100 | }; 101 | } 102 | 103 | // replace contents 104 | file.contents = result.css; 105 | 106 | // rename file extension 107 | files[dest] = file; 108 | 109 | delete files[filename]; 110 | done(); 111 | }); 112 | }, 113 | 114 | compileSass = function compileSass(config, files, metalsmith, done) { 115 | /** 116 | * Looks up different key names on `metalsmith` to support 117 | * old versions (< v1) of Metalsmith. At some point, I will remove 118 | * support for < v1 and remove the key lookups 119 | */ 120 | var directory = metalsmith.dir || metalsmith._directory, 121 | source = metalsmith._src || metalsmith._source, 122 | basePath = path.isAbsolute(source) ? source : path.join(directory, source); 123 | each(Object.keys(files), compile.bind(null, config, basePath, files), done); 124 | }, 125 | 126 | plugin = function plugin(options) { 127 | var config = options || {}; 128 | return compileSass.bind(null, config); 129 | }; 130 | 131 | // exposing node-sass types for custom functions. see: 132 | // https://github.com/stevenschobert/metalsmith-sass/pull#21 133 | plugin.types = sass.types; 134 | module.exports = plugin; 135 | }()); 136 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metalsmith-sass", 3 | "version": "2.0.0", 4 | "description": "Sass plugin for Metalsmith.", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "prepare": "install-peers", 8 | "test": "mocha --harmony --reporter spec test/test.js" 9 | }, 10 | "files": [ 11 | "lib/**/*.js" 12 | ], 13 | "repository": { 14 | "type": "git", 15 | "url": "git://github.com/stevenschobert/metalsmith-sass.git" 16 | }, 17 | "keywords": [ 18 | "metalsmith", 19 | "sass" 20 | ], 21 | "author": "Steven Schobert ", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/stevenschobert/metalsmith-sass/issues" 25 | }, 26 | "homepage": "https://github.com/stevenschobert/metalsmith-sass", 27 | "devDependencies": { 28 | "assert": "^2.0.0", 29 | "assert-dir-equal": "^1.0.1", 30 | "install-peers-cli": "^2.2.0", 31 | "metalsmith": "^2.3.0", 32 | "mocha": "^9.1.3", 33 | "rimraf": "^3.0.2" 34 | }, 35 | "peerDependencies": { 36 | "node-sass": ">= 4.13.0" 37 | }, 38 | "dependencies": { 39 | "async": "^3.2.2" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/fixtures/basic/expected/main.css: -------------------------------------------------------------------------------- 1 | .myclass { 2 | background: #eee; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/expected/oldfile.css: -------------------------------------------------------------------------------- 1 | .shouldnotchange { 2 | width: 50%; 3 | color: red; 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/basic/src/main.scss: -------------------------------------------------------------------------------- 1 | $color: #eee; 2 | 3 | .myclass { 4 | background: $color; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/src/oldfile.css: -------------------------------------------------------------------------------- 1 | .shouldnotchange { 2 | width: 50%; 3 | color: red; 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/dotfiles/expected/goodfile.css: -------------------------------------------------------------------------------- 1 | .shouldprint { 2 | background: #0ff; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/dotfiles/src/.badfile.scss: -------------------------------------------------------------------------------- 1 | $color: #ff0; 2 | 3 | .shouldnotprint { 4 | background: $color; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/dotfiles/src/goodfile.scss: -------------------------------------------------------------------------------- 1 | $color: #0ff; 2 | 3 | .shouldprint { 4 | background: $color; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/front-matter/expected/front-matter.css: -------------------------------------------------------------------------------- 1 | .shouldprint { 2 | background: #0ff; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/front-matter/src/front-matter.scss: -------------------------------------------------------------------------------- 1 | --- 2 | title: SASS file with YMAL Front-Matter, which is ignored by Metalsmith. 3 | --- 4 | 5 | $color: #0ff; 6 | 7 | .shouldprint { 8 | background: $color; 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/functions/expected/functions.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #000123; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/functions/src/functions.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: test('000'); 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/imports/expected/css/main.css: -------------------------------------------------------------------------------- 1 | .myclass { 2 | background: #eee; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/imports/src/css/main.scss: -------------------------------------------------------------------------------- 1 | @import 'vendor/part'; 2 | -------------------------------------------------------------------------------- /test/fixtures/imports/src/css/vendor/_part.scss: -------------------------------------------------------------------------------- 1 | $color: #eee; 2 | 3 | .myclass { 4 | background: $color; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/invalid/src/invalid.scss: -------------------------------------------------------------------------------- 1 | .invalid { 2 | aninvalidrule! 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/maps/expected/css/main.css: -------------------------------------------------------------------------------- 1 | .myclass{background:#eee} 2 | 3 | /*# sourceMappingURL=main.css.map */ -------------------------------------------------------------------------------- /test/fixtures/maps/expected/css/main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "main.css", 4 | "sources": [ 5 | "main.scss", 6 | "vendor/_part.scss" 7 | ], 8 | "sourcesContent": [ 9 | "@import 'vendor/part';\n", 10 | "$color: #eee;\n\n.myclass {\n background: $color;\n}\n" 11 | ], 12 | "names": [], 13 | "mappings": "ACEA,AAAA,QAAQ,AAAC,CACP,UAAU,CAHJ,IAAI,CAIX" 14 | } -------------------------------------------------------------------------------- /test/fixtures/maps/src/css/main.scss: -------------------------------------------------------------------------------- 1 | @import 'vendor/part'; 2 | -------------------------------------------------------------------------------- /test/fixtures/maps/src/css/vendor/_part.scss: -------------------------------------------------------------------------------- 1 | $color: #eee; 2 | 3 | .myclass { 4 | background: $color; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/outputDir/expected/nested/main.css: -------------------------------------------------------------------------------- 1 | .myclass { 2 | background: #eee; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/outputDir/expected/nested/sub/subpage.css: -------------------------------------------------------------------------------- 1 | .subpageclass { 2 | height: 1em; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/outputDir/src/scss/main.scss: -------------------------------------------------------------------------------- 1 | $color: #eee; 2 | 3 | .myclass { 4 | background: $color; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/outputDir/src/scss/sub/subpage.scss: -------------------------------------------------------------------------------- 1 | $height: 1em; 2 | 3 | .subpageclass { 4 | height: $height; 5 | } -------------------------------------------------------------------------------- /test/fixtures/partials/expected/main.css: -------------------------------------------------------------------------------- 1 | .shouldgetincluded { 2 | color: #ff0; 3 | } 4 | 5 | .myclass { 6 | background: #eee; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/partials/expected/not_partial.css: -------------------------------------------------------------------------------- 1 | .notpartial { 2 | color: #0f0; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/partials/src/_partial.scss: -------------------------------------------------------------------------------- 1 | .shouldgetincluded { 2 | color: #ff0; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/partials/src/_partial_with_underscore.scss: -------------------------------------------------------------------------------- 1 | .newpartial { 2 | color: #ff0; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/partials/src/main.scss: -------------------------------------------------------------------------------- 1 | @import 'partial'; 2 | 3 | $color: #eee; 4 | 5 | .myclass { 6 | background: $color; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/partials/src/not_partial.scss: -------------------------------------------------------------------------------- 1 | $color3: #0f0; 2 | 3 | .notpartial { 4 | color: $color3; 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/sass-type/expected/main.css: -------------------------------------------------------------------------------- 1 | .myclass { 2 | font: 100% Helvetica, sans-serif; 3 | color: #333; 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/sass-type/src/main.sass: -------------------------------------------------------------------------------- 1 | $font-stack: Helvetica, sans-serif 2 | $primary-color: #333 3 | 4 | .myclass 5 | font: 100% $font-stack 6 | color: $primary-color 7 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | var each = require('async/each'), 5 | assert = require('assert'), 6 | exists = require('fs').existsSync, 7 | join = require('path').join, 8 | metalsmith = require('metalsmith'), 9 | rm = require('rimraf'), 10 | types = require('node-sass').types, 11 | sass = require('..'), 12 | equal = require('assert-dir-equal'); 13 | 14 | describe('the plugin', function () { 15 | beforeEach(function (done) { 16 | var dirsToClean = [ 17 | join(__dirname, 'fixtures/basic/build'), 18 | join(__dirname, 'fixtures/partials/build'), 19 | join(__dirname, 'fixtures/outputDir/build'), 20 | join(__dirname, 'fixtures/dotfiles/build'), 21 | join(__dirname, 'fixtures/imports/build'), 22 | join(__dirname, 'fixtures/front-matter/build'), 23 | join(__dirname, 'fixtures/invalid/build'), 24 | join(__dirname, 'fixtures/maps/build'), 25 | join(__dirname, 'fixtures/sass-type/build') 26 | ]; 27 | each(dirsToClean, rm, done); 28 | }); 29 | 30 | it('should expose node-sass types', function() { 31 | assert.equal(sass.types, types); 32 | }); 33 | 34 | describe('core', function () { 35 | it('should support absolute source path with imports', function (done) { 36 | metalsmith(__dirname) 37 | .source(__dirname + '/fixtures/imports/src') 38 | .destination('fixtures/imports/build') 39 | .use(sass({ 40 | outputStyle: 'expanded' 41 | })) 42 | .build(function (err) { 43 | assert.equal(err, null, "There shouldn't be any error."); 44 | equal(join(__dirname, 'fixtures/imports/build'), join(__dirname, 'fixtures/imports/expected')); 45 | done(); 46 | }); 47 | }); 48 | 49 | it('should compile .scss files', function (done) { 50 | metalsmith(__dirname) 51 | .source('fixtures/basic/src') 52 | .destination('fixtures/basic/build') 53 | .use(sass({ 54 | outputStyle: 'expanded' 55 | })) 56 | .build(function (err) { 57 | assert.equal(err, null, "There shouldn't be any error."); 58 | equal(join(__dirname, 'fixtures/basic/build'), join(__dirname, 'fixtures/basic/expected')); 59 | done(); 60 | }); 61 | }); 62 | 63 | it('should compile .sass files', function (done) { 64 | metalsmith(__dirname) 65 | .source('fixtures/sass-type/src') 66 | .destination('fixtures/sass-type/build') 67 | .use(sass({ 68 | outputStyle: 'expanded' 69 | })) 70 | .build(function (err) { 71 | assert.equal(err, null, "There shouldn't be any error."); 72 | equal(join(__dirname, 'fixtures/sass-type/build'), join(__dirname, 'fixtures/sass-type/expected')); 73 | done(); 74 | }); 75 | }); 76 | 77 | it('should ignore partial files', function (done) { 78 | metalsmith(__dirname) 79 | .source('fixtures/partials/src') 80 | .destination('fixtures/partials/build') 81 | .use(sass({ 82 | outputStyle: 'expanded' 83 | })) 84 | .build(function (err) { 85 | if (err) { 86 | throw err; 87 | } 88 | equal(join(__dirname, 'fixtures/partials/build'), join(__dirname, 'fixtures/partials/expected')); 89 | done(); 90 | }); 91 | }); 92 | 93 | it('should compile with import statements', function (done) { 94 | metalsmith(__dirname) 95 | .source('fixtures/imports/src') 96 | .destination('fixtures/imports/build') 97 | .use(sass({ 98 | outputStyle: 'expanded' 99 | })) 100 | .build(function (err) { 101 | if (err) { 102 | throw err; 103 | } 104 | equal(join(__dirname, 'fixtures/imports/build'), join(__dirname, 'fixtures/imports/expected')); 105 | done(); 106 | }); 107 | }); 108 | 109 | it('should compile source maps if enabled', function (done) { 110 | metalsmith(__dirname) 111 | .source('fixtures/maps/src') 112 | .destination('fixtures/maps/build') 113 | .use(sass({ 114 | sourceMap: true, 115 | sourceMapContents: true 116 | })) 117 | .build(function (err) { 118 | if (err) { 119 | throw err; 120 | } 121 | equal(join(__dirname, 'fixtures/maps/build'), join(__dirname, 'fixtures/maps/expected')); 122 | done(); 123 | }); 124 | }); 125 | 126 | it('should ignore dotfiles', function (done) { 127 | metalsmith(__dirname) 128 | .source('fixtures/dotfiles/src') 129 | .destination('fixtures/dotfiles/build') 130 | .use(sass({ 131 | outputStyle: 'expanded' 132 | })) 133 | .build(function (err) { 134 | if (err) { 135 | throw err; 136 | } 137 | equal(join(__dirname, 'fixtures/dotfiles/build'), join(__dirname, 'fixtures/dotfiles/expected')); 138 | assert(!exists(join(__dirname, 'fixtures/dotfiles/build/.badfile.css'))); 139 | done(); 140 | }); 141 | }); 142 | 143 | it('should operate correctly around YAML front matter', function (done) { 144 | metalsmith(__dirname) 145 | .source('fixtures/front-matter/src') 146 | .destination('fixtures/front-matter/build') 147 | .use(sass({ 148 | outputStyle: 'expanded' 149 | })) 150 | .build(function (err) { 151 | if (err) { 152 | throw err; 153 | } 154 | equal(join(__dirname, 'fixtures/front-matter/build'), join(__dirname, 'fixtures/front-matter/expected')); 155 | assert(!exists(join(__dirname, 'fixtures/dotfiles/build/.badfile.css'))); 156 | done(); 157 | }); 158 | }); 159 | 160 | it('should correctly report errors to Metalsmith', function(done) { 161 | metalsmith(__dirname) 162 | .source('fixtures/invalid/src') 163 | .destination('fixtures/invalid/build') 164 | .use(sass({ 165 | outputStyle: 'expanded' 166 | })) 167 | .build(function (err) { 168 | assert(err.message && /aninvalidrule/.test(err.message)); 169 | assert(!exists(join(__dirname, 'fixtures/invalid/build/invalid.scss'))); 170 | done(); 171 | }); 172 | }); 173 | 174 | it('should accept custom functions', function(done) { 175 | metalsmith(__dirname) 176 | .source('fixtures/functions/src') 177 | .destination('fixtures/functions/build') 178 | .use(sass({ 179 | outputStyle: 'expanded', 180 | functions: { 181 | 'test($arg)': function(arg) { 182 | return new types.String('#' + arg.getValue() + '123'); 183 | } 184 | } 185 | })) 186 | .build(function (err) { 187 | if (err) { 188 | throw err; 189 | } 190 | equal(join(__dirname, 'fixtures/functions/build'), join(__dirname, 'fixtures/functions/expected')); 191 | done(); 192 | }); 193 | }); 194 | }); 195 | 196 | describe('the outputDir option', function () { 197 | it('should change the destination directory', function (done) { 198 | metalsmith(__dirname) 199 | .source('fixtures/outputDir/src') 200 | .destination('fixtures/outputDir/build') 201 | .use(sass({ 202 | outputStyle: 'expanded', 203 | outputDir: function(original) { 204 | return original.replace("scss", "nested"); 205 | } 206 | })) 207 | .build(function (err) { 208 | if (err) { 209 | throw err; 210 | } 211 | equal(join(__dirname, 'fixtures/outputDir/build'), join(__dirname, 'fixtures/outputDir/expected')); 212 | done(); 213 | }); 214 | }); 215 | }); 216 | }); 217 | }()); 218 | --------------------------------------------------------------------------------