├── .gitignore
├── tests
├── util
│ ├── _vars.scss
│ ├── indented.sass
│ ├── basic.scss
│ ├── imports-old.scss
│ ├── imports.scss
│ ├── mock-importer-factory.js
│ ├── mock-importer.js
│ └── integration.js
├── settings.js
├── indented.js
├── import-events.js
├── style-tag.js
└── custom-importers.js
├── .travis.yml
├── .github
├── ISSUE_TEMPLATE.md
└── workflows
│ └── run-test.yml
├── LICENSE
├── lib
├── browser.js
└── index.js
├── package.json
├── README.md
└── history.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/tests/util/_vars.scss:
--------------------------------------------------------------------------------
1 | $color: red;
2 | $background: blue;
3 |
--------------------------------------------------------------------------------
/tests/util/indented.sass:
--------------------------------------------------------------------------------
1 | body
2 | color: red
3 | background: blue
4 |
--------------------------------------------------------------------------------
/tests/util/basic.scss:
--------------------------------------------------------------------------------
1 | body {
2 | color: red;
3 | background: blue;
4 | columns: 300px 2;
5 | }
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "6"
4 | - "7"
5 | - "8"
6 | notifications:
7 | email: false
8 |
--------------------------------------------------------------------------------
/tests/util/imports-old.scss:
--------------------------------------------------------------------------------
1 | @import 'vars';
2 |
3 | body {
4 | color: $color;
5 | background: $background;
6 | }
7 |
--------------------------------------------------------------------------------
/tests/util/imports.scss:
--------------------------------------------------------------------------------
1 | @import 'resolve-to-vars';
2 |
3 | body {
4 | color: $color;
5 | background: $background;
6 | }
7 |
--------------------------------------------------------------------------------
/tests/util/mock-importer-factory.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const mockImporter = require('./mock-importer')
3 | module.exports = function () {
4 | module.exports.count++
5 | return mockImporter
6 | }
7 |
8 | module.exports.count = 0
9 |
10 |
--------------------------------------------------------------------------------
/tests/util/mock-importer.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const importedFiles = new Set()
3 | module.exports = function (file) {
4 | importedFiles.add(file)
5 | if (file === 'resolve-to-vars')
6 | return {file: 'tests/util/_vars.scss'}
7 | return null
8 | }
9 |
10 | // Expose for assertions
11 | module.exports.importedFiles = importedFiles
12 |
--------------------------------------------------------------------------------
/tests/settings.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* eslint-env mocha */
3 | const assert = require('assert')
4 | const integration = require('./util/integration')
5 |
6 | it('settings', integration(__dirname + '/util/basic.scss', {
7 | autoInject: false,
8 | sass: {
9 | outputStyle: 'expanded'
10 | },
11 | postcss: {
12 | autoprefixer: {}
13 | }
14 | }, function (context, done) {
15 | let css = context.exports
16 | assert.equal(typeof css, 'string', 'exported raw css')
17 | assert.notEqual(css.indexOf('-moz'), -1, 'postcss plugins ran')
18 | done()
19 | }))
20 |
--------------------------------------------------------------------------------
/tests/indented.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* eslint-env mocha */
3 | const assert = require('assert')
4 | const integration = require('./util/integration')
5 |
6 | it('supports indented syntax (.sass)', integration(__dirname + '/util/indented.sass', {
7 | // empty
8 | }, function (context, done) {
9 | let applied = context.window.getComputedStyle(context.document.body)
10 | assert.equal(context.exports.tagName, 'STYLE', 'created tag and add it to the document head
7 | * @param {string} cssText
8 | * @param {object?} options
9 | * @return {Element}
10 | */
11 | createStyle: function (cssText, options) {
12 | var container = document.head || document.getElementsByTagName('head')[0]
13 | var style = document.createElement('style')
14 | options = options || {}
15 | style.type = 'text/css'
16 | if (options.href) {
17 | style.setAttribute('data-href', options.href)
18 | }
19 | if (style.sheet) { // for jsdom and IE9+
20 | style.innerHTML = cssText
21 | style.sheet.cssText = cssText
22 | }
23 | else if (style.styleSheet) { // for IE8 and below
24 | style.styleSheet.cssText = cssText
25 | }
26 | else { // for Chrome, Firefox, and Safari
27 | style.appendChild(document.createTextNode(cssText))
28 | }
29 | if (options.prepend) {
30 | container.insertBefore(style, container.childNodes[0]);
31 | } else {
32 | container.appendChild(style);
33 | }
34 | return style
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "scssify",
3 | "version": "4.0.0",
4 | "description": "Sass browserify transformer",
5 | "repository": "cody-greene/scssify",
6 | "main": "./lib/index.js",
7 | "browser": "./lib/browser.js",
8 | "files": [
9 | "lib/"
10 | ],
11 | "scripts": {
12 | "watch": "mocha tests/*.js -bwR min",
13 | "test": "mocha tests/*.js -bR tap"
14 | },
15 | "keywords": [
16 | "browserify",
17 | "browserify-transform",
18 | "css",
19 | "postcss-runner",
20 | "sass",
21 | "scss",
22 | "transform"
23 | ],
24 | "author": "Chris Hoage",
25 | "license": "MIT",
26 | "engines": {
27 | "node": ">=14"
28 | },
29 | "eslintConfig": {
30 | "root": true,
31 | "extends": "./node_modules/@cody-greene/eslint-config/strict.yml",
32 | "env": {
33 | "node": true,
34 | "es6": true
35 | }
36 | },
37 | "devDependencies": {
38 | "@cody-greene/eslint-config": "3.3.3",
39 | "autoprefixer": "^10.4.0",
40 | "jsdom": "^21.1.0",
41 | "mocha": "^10.2.0",
42 | "postcss": "^8.4.0"
43 | },
44 | "dependencies": {
45 | "resolve": "^1.1.6",
46 | "sass": "^1.59.2"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/custom-importers.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* eslint-env mocha */
3 | const assert = require('assert')
4 | const integration = require('./util/integration')
5 | const importSpy = require('./util/mock-importer').importedFiles
6 | const factory = require('./util/mock-importer-factory')
7 |
8 | before(function setup() {
9 | importSpy.clear()
10 | })
11 |
12 | it('loads custom importer files', integration(__dirname + '/util/imports.scss', {
13 | autoInject: false,
14 | sass: {
15 | importer: 'tests/util/mock-importer.js'
16 | }
17 | }, function (context, done) {
18 | const [firstFile] = Array.from(importSpy)
19 | assert.equal(firstFile, 'resolve-to-vars', 'import spy was loaded')
20 | done()
21 | }))
22 |
23 | it('loads importer from factory function every time it runs', function (done) {
24 | // this mimics browserify + factor-bundle calling the transform several times in a single process
25 | let file = __dirname + '/util/imports.scss'
26 | let config = {
27 | autoInject: false,
28 | sass: {
29 | importerFactory: 'tests/util/mock-importer-factory.js'
30 | }
31 | }
32 | integration(file, config, function (context, done) {
33 | integration(file, config, function (context, done) {
34 | let count = factory.count
35 | assert.equal(count, 2, 'factory not called expected number of times')
36 | done()
37 | })(done)
38 | })(done)
39 | })
40 |
--------------------------------------------------------------------------------
/tests/util/integration.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const scssify = require('../../lib')
3 | const JSDOM = require('jsdom').JSDOM
4 | const fs = require('fs')
5 | const vm = require('vm')
6 | const CLIENT_HELPER_CODE = fs.readFileSync('lib/browser.js', 'utf8')
7 |
8 | /**
9 | * @param {string} src Absolute path to a scss file
10 | * @param {object} config scssify parameters
11 | * @param {function} callback(context, assert)
12 | * @param {function?} prepare(context)
13 | * @return {function} Pass this to tape('test-name', fn)
14 | */
15 | function createIntegrationTest(src, config, callback, prepare) {
16 | if (!config._flags) config._flags = {}
17 | return function (done) {
18 | fs.createReadStream(src)
19 | .on('error', done)
20 | .pipe(scssify(src, config))
21 | .on('error', done)
22 | .once('data', function (transformed) {
23 | let doc = new JSDOM(null, {runScripts: 'dangerously'})
24 | let helperModule = {exports: {}}
25 | let cssModule = {exports: {}}
26 | vm.runInNewContext(CLIENT_HELPER_CODE, {
27 | window: doc.window,
28 | document: doc.window.document,
29 | module: helperModule
30 | })
31 | if (prepare) prepare({
32 | window: doc.window,
33 | document: doc.window.document,
34 | exports: cssModule.exports
35 | })
36 | vm.runInNewContext(transformed.toString(), {
37 | window: doc.window,
38 | document: doc.window.document,
39 | module: cssModule,
40 | require: function (req) {
41 | if (req === 'scssify') return helperModule.exports
42 | throw new Error('sandboxed module: unexpected require(...)')
43 | }
44 | })
45 | callback({
46 | window: doc.window,
47 | document: doc.window.document,
48 | exports: cssModule.exports
49 | }, done)
50 | })
51 | }
52 | }
53 |
54 | module.exports = createIntegrationTest
55 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### scssify
2 | Browserify transfomer to compile [sass][] stylesheets. Features:
3 | - Inject a `