Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

broccoli-eyeglass

Package Overview
Dependencies
Maintainers
1
Versions
84
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

broccoli-eyeglass - npm Package Compare versions

Comparing version 2.1.1 to 2.1.2

test/fixtures/basicProject/input/styles/_unused.scss

95

lib/broccoli_sass_compiler.js
var path = require("path");
var fs = require("fs");
var mkdirp = require("mkdirp");
var CachingWriter = require("broccoli-caching-writer");
var BroccoliPlugin = require("broccoli-plugin");
var MergeTrees = require("broccoli-merge-trees");
var Eyeglass = require("eyeglass");
var sass = require("node-sass");

@@ -10,3 +12,6 @@ var glob = require("glob");

var EventEmitter = require("chained-emitter").EventEmitter;
var FSTree = require("fs-tree-diff");
var walkSync = require("walk-sync");
function unique(array) {

@@ -160,4 +165,17 @@ var o = {};

//
function BroccoliSassCompiler(inputTrees, options) {
CachingWriter.call(this, inputTrees, options);
function BroccoliSassCompiler(inputTree, options) {
if (Array.isArray(inputTree)) {
if (inputTree.length > 1) {
console.warn("Support for passing several trees to BroccoliSassCompiler has been removed.\n" +
"Passing the trees to broccoli-merge-trees with the overwrite option set,\n" +
"but you should do this yourself if you need to compile CSS files from them\n" +
"or use the node-sass includePaths option if you need to import from them.");
inputTree = new MergeTrees(inputTree, {overwrite: true, annotation: "Sass Trees"});
} else {
inputTree = inputTree[0];
}
}
options = options || {};
options.persistentOutput = true;
BroccoliPlugin.call(this, [inputTree], options);

@@ -168,2 +186,5 @@ this.sass = sass;

this.currentTree = new FSTree();
this.dependencies = {};
moveOption(this.options, this, "cssDir", "sassDir",

@@ -197,3 +218,3 @@ "optionsGenerator", "fullException",

}
BroccoliSassCompiler.prototype = Object.create(CachingWriter.prototype);
BroccoliSassCompiler.prototype = Object.create(BroccoliPlugin.prototype);
BroccoliSassCompiler.prototype.constructor = BroccoliSassCompiler;

@@ -310,23 +331,65 @@ BroccoliSassCompiler.prototype.logCompilationSuccess = function(details, result) {

// function timeSince(time) {
// var delta = process.hrtime(time);
// var deltaNS = delta[0] * 1e9 + delta[1];
// return (deltaNS / 1e6).toFixed(2) + " ms";
// }
BroccoliSassCompiler.prototype.build = function() {
var inputPaths = this.inputPaths;
var inputPath = this.inputPaths[0];
var outputPath = this.outputPath;
// TODO: add inputPaths (incl sassDir for the first) to the includePaths option
var self = this;
var files = {};
for (var i = 0; i < inputPaths.length; i++) {
// TODO: handle indented syntax files.
files[inputPaths[i]] = removePathPrefix(inputPaths[i], this.filesInTree(inputPaths[i]));
// var startTime = process.hrtime();
var entries = walkSync.entries(inputPath);
if (this.options.includePaths) {
this.options.includePaths.forEach(function(p) {
entries = entries.concat(walkSync.entries(p));
});
}
// TODO: limit concurrency?
var promises = inputPaths.reduce(function (results, srcPath) {
return results.concat(self.compileTree(srcPath, files[srcPath], outputPath));
}, []);
var eyeglass = new Eyeglass(this.options);
var moduleKeys = Object.keys(eyeglass.modules.collection);
for (var m = 0; m < moduleKeys.length; m++) {
var moduleSassEntries = walkSync.entries(eyeglass.modules.collection[moduleKeys[m]].sassDir);
entries = entries.concat(moduleSassEntries);
}
return RSVP.all(promises);
var nextTree = new FSTree.fromEntries(entries, {sortAndExpand: true});
var currentTree = this.currentTree;
this.currentTree = nextTree;
var patches = currentTree.calculatePatch(nextTree);
//console.log("Building Cache State took", timeSince(startTime));
var self = this;
this.events.on("compiled", function(details, result) {
var depFiles = result.stats.includedFiles;
for (var i = 0; i < depFiles.length; i++) {
self.dependencies[details.sassFilename] =
self.dependencies[details.sassFilename] || new Set();
self.dependencies[details.sassFilename].add(depFiles[i]);
}
});
// TODO: handle indented syntax files.
var treeFiles = removePathPrefix(inputPath, this.filesInTree(inputPath));
treeFiles = treeFiles.filter(function(f, i) {
if (self.dependencies[f] === undefined) {
return true;
}
for (var p = 0; p < patches.length; p++) {
var entry = patches[p][2];
if (self.dependencies[f].has(path.join(entry.basePath, entry.relativePath))) {
return true;
}
}
});
return RSVP.all(self.compileTree(inputPath, treeFiles, outputPath));
};
module.exports = BroccoliSassCompiler;

16

package.json
{
"name": "broccoli-eyeglass",
"description": "Sass compiler for Broccoli with Eyeglass Integration",
"version": "2.1.1",
"version": "2.1.2",
"author": "Chris Eppstein <chris@eppsteins.net>",

@@ -23,10 +23,13 @@ "main": "lib/index.js",

"dependencies": {
"broccoli-caching-writer": "^3.0.3",
"broccoli-merge-trees": "^1.1.4",
"broccoli-plugin": "^1.2.2",
"chained-emitter": "^0.1.2",
"colors": "^1.0.3",
"eyeglass": "^1.0.0",
"eyeglass": "^1.1.0",
"fs-tree-diff": "^0.5.2",
"glob": "^5.0.3",
"mkdirp": "^0.5.1",
"node-sass": "^3.9.3",
"rsvp": "^3.0.21"
"rsvp": "^3.0.21",
"walk-sync": "^0.3.1"
},

@@ -37,2 +40,3 @@ "devDependencies": {

"eyeglass-dev-eslint": "*",
"fixturify": "^0.3.0",
"grunt": "^0.4.5",

@@ -44,4 +48,6 @@ "grunt-release": "^0.12.0",

"gulp-mocha": "^2.2.0",
"jshint": "^2.8.0"
"jshint": "^2.8.0",
"mocha": "^3.0.2",
"rimraf": "^2.5.4"
}
}

@@ -15,2 +15,4 @@ /* Copyright 2016 LinkedIn Corp. Licensed under the Apache License, Version 2.0 (the "License");

var fs = require("fs");
var rimraf = require("rimraf");
var fixturify = require("fixturify");
var broccoli = require("broccoli");

@@ -26,10 +28,17 @@ var RSVP = require("rsvp");

function fixtureSourceDir(name) {
return path.resolve(__dirname, "fixtures", name, "input");
return path.resolve(fixtureDir(name), "input");
}
function fixtureOutputDir(name) {
return path.resolve(__dirname, "fixtures", name, "output");
return path.resolve(fixtureDir(name), "output");
}
function makeFixtures(name, files) {
var dirname = fixtureDir(name);
fs.mkdirSync(dirname);
fixturify.writeSync(dirname, files);
return dirname;
}
function build(builder) {

@@ -164,8 +173,236 @@ return RSVP.Promise.resolve()

/*
moveOption(this.options, this, "cssDir", "sassDir",
"optionsGenerator", "fullException",
"verbose", "renderSync",
"discover", "sourceFiles");
*/
describe("caching", function() {
afterEach(function() {
var tmpDirs = glob.sync(path.join(path.resolve(__dirname, "fixtures"),"**", "*.tmp"));
tmpDirs.forEach(function(tmpDir) {
rimraf.sync(tmpDir);
});
});
it("caches when an unrelated file changes", function() {
var sourceDir = fixtureSourceDir("basicProject");
var compiledFiles = [];
var compiler = new EyeglassCompiler(sourceDir, {
cssDir: ".",
optionsGenerator: function(sassFile, cssFile, options, cb) {
compiledFiles.push(sassFile);
cb(cssFile, options);
}
});
var builder = new broccoli.Builder(compiler);
return build(builder)
.then(function(outputDir) {
assertEqualDirs(outputDir, fixtureOutputDir("basicProject"));
assert.equal(1, compiledFiles.length);
var unusedSourceFile = path.join(sourceDir, "styles", "_unused.scss");
fs.writeFileSync(unusedSourceFile, "// changed but still not used.");
return build(builder).then(function(outputDir2) {
assert.equal(outputDir, outputDir2);
assert.equal(1, compiledFiles.length);
});
});
});
it("doesn't cache when there's a change", function() {
var sourceDir = fixtureSourceDir("basicProject");
var compiledFiles = [];
var compiler = new EyeglassCompiler(sourceDir, {
cssDir: ".",
optionsGenerator: function(sassFile, cssFile, options, cb) {
compiledFiles.push(sassFile);
cb(cssFile, options);
}
});
var builder = new broccoli.Builder(compiler);
return build(builder)
.then(function(outputDir) {
assertEqualDirs(outputDir, fixtureOutputDir("basicProject"));
assert.equal(1, compiledFiles.length);
var sourceFile = path.join(sourceDir, "styles", "foo.scss");
var originalSource = fs.readFileSync(sourceFile);
var newSource = "@import \"used\";\n" +
"$color: blue;\n" +
".foo {\n" +
" color: $color;\n" +
"}\n";
var newExpectedOutput = ".foo {\n" +
" color: blue; }\n";
fs.writeFileSync(sourceFile, newSource);
return build(builder)
.then(function(outputDir2) {
assert.equal(outputDir, outputDir2);
var outputFile = path.join(outputDir2, "styles", "foo.css");
assert.equal(newExpectedOutput, fs.readFileSync(outputFile));
assert.equal(2, compiledFiles.length);
})
.finally(function() {
fs.writeFileSync(sourceFile, originalSource);
});
});
});
it("busts cache when file reached via includePaths changes", function() {
var projectDir = makeFixtures("projectDir.tmp", {
"project.scss": '@import "external";'
});
var includeDir = makeFixtures("includeDir.tmp", {
"external.scss": ".external { float: left; }"
});
var expectedOutputDir = makeFixtures("expectedOutputDir.tmp", {
"project.css": ".external {\n float: left; }\n"
});
var compiledFiles = [];
var compiler = new EyeglassCompiler(projectDir, {
cssDir: ".",
includePaths: [includeDir],
optionsGenerator: function(sassFile, cssFile, options, cb) {
compiledFiles.push(sassFile);
cb(cssFile, options);
}
});
var builder = new broccoli.Builder(compiler);
return build(builder)
.then(function(outputDir) {
assertEqualDirs(outputDir, expectedOutputDir);
assert.equal(1, compiledFiles.length);
compiledFiles = [];
fixturify.writeSync(includeDir, {
"external.scss": ".external { float: right; }"
});
fixturify.writeSync(expectedOutputDir, {
"project.css": ".external {\n float: right; }\n"
});
return build(builder)
.then(function(outputDir2) {
assert.equal(outputDir, outputDir2);
assert.equal(compiledFiles.length, 1);
assertEqualDirs(outputDir2, expectedOutputDir);
});
});
});
it("busts cache when file mode changes", function() {
var projectDir = makeFixtures("projectDir.tmp", {
"project.scss": '@import "external";'
});
var includeDir = makeFixtures("includeDir.tmp", {
"external.scss": ".external { float: left; }"
});
var expectedOutputDir = makeFixtures("expectedOutputDir.tmp", {
"project.css": ".external {\n float: left; }\n"
});
var compiledFiles = [];
var compiler = new EyeglassCompiler(projectDir, {
cssDir: ".",
includePaths: [includeDir],
optionsGenerator: function(sassFile, cssFile, options, cb) {
compiledFiles.push(sassFile);
cb(cssFile, options);
}
});
var builder = new broccoli.Builder(compiler);
return build(builder)
.then(function(outputDir) {
assertEqualDirs(outputDir, expectedOutputDir);
assert.equal(1, compiledFiles.length);
compiledFiles = [];
fs.chmodSync(path.join(includeDir, "external.scss"), parseInt("755", 8));
return build(builder)
.then(function(outputDir2) {
assert.equal(outputDir, outputDir2);
assert.equal(compiledFiles.length, 1);
assertEqualDirs(outputDir2, expectedOutputDir);
});
});
});
it("busts cache when an eyeglass module is upgraded", function() {
var projectDir = makeFixtures("projectDir.tmp", {
"project.scss": '@import "eyeglass-module";'
});
var eyeglassModDir = makeFixtures("eyeglassmod.tmp", {
"package.json": "{\n" +
' "name": "is_a_module",\n' +
' "keywords": ["eyeglass-module"],\n' +
' "private": true,\n' +
' "eyeglass": {\n' +
' "exports": false,\n' +
' "name": "eyeglass-module",\n' +
' "sassDir": "sass",\n' +
' "needs": "*"\n' +
" }\n" +
"}",
"sass": {
"index.scss": ".eyeglass-mod { content: eyeglass }"
}
});
var expectedOutputDir = makeFixtures("expectedOutputDir.tmp", {
"project.css": ".eyeglass-mod {\n content: eyeglass; }\n"
});
var compiledFiles = [];
var compiler = new EyeglassCompiler(projectDir, {
cssDir: ".",
optionsGenerator: function(sassFile, cssFile, options, cb) {
compiledFiles.push(sassFile);
cb(cssFile, options);
},
eyeglass: {
modules: [
{path: eyeglassModDir}
]
}
});
var builder = new broccoli.Builder(compiler);
return build(builder)
.then(function(outputDir) {
assertEqualDirs(outputDir, expectedOutputDir);
assert.equal(1, compiledFiles.length);
compiledFiles = [];
fixturify.writeSync(eyeglassModDir, {
"sass": {
"index.scss": ".eyeglass-mod { content: eyeglass-changed }"
}
});
fixturify.writeSync(expectedOutputDir, {
"project.css": ".eyeglass-mod {\n content: eyeglass-changed; }\n"
});
return build(builder)
.then(function(outputDir2) {
assert.equal(outputDir, outputDir2);
assert.equal(compiledFiles.length, 1);
assertEqualDirs(outputDir2, expectedOutputDir);
});
});
});
it("busts cache when an eyeglass asset changes");
it("busts cache when options used for compilation are different");
it("busts cache when a file higher in the load path order is added");
it("removes a css file when the corresponding sass file is removed");
it("preserves cache across builder instances?");
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc