Skip to content

Commit

Permalink
Move code from PostCSS
Browse files Browse the repository at this point in the history
  • Loading branch information
ai committed May 16, 2015
0 parents commit 0597811
Show file tree
Hide file tree
Showing 9 changed files with 373 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .eslintrc
@@ -0,0 +1,20 @@
{
"rules": {
"no-unused-expressions": [0],
"no-underscore-dangle": [0],
"no-reserved-keys": [2],
"no-multi-spaces": [0],
"no-extra-parens": [2],
"no-unused-vars": [2],
"no-loop-func": [0],
"key-spacing": [0],
"max-len": [2, 80],
"strict": [0],
"indent": [2],
"quotes": [2, "single", "avoid-escape"],
"curly": [0]
},
"env": {
"node": true
}
}
8 changes: 8 additions & 0 deletions .gitignore
@@ -0,0 +1,8 @@
.DS_Store
*~

npm-debug.log
node_modules/
.bundle/

cache/
5 changes: 5 additions & 0 deletions .travis.yml
@@ -0,0 +1,5 @@
sudo: false
language: node_js
node_js:
- iojs
- "0.12"
3 changes: 3 additions & 0 deletions Gemfile
@@ -0,0 +1,3 @@
source "https://rubygems.org"

gem 'sass'
10 changes: 10 additions & 0 deletions Gemfile.lock
@@ -0,0 +1,10 @@
GEM
remote: https://rubygems.org/
specs:
sass (3.4.13)

PLATFORMS
ruby

DEPENDENCIES
sass
47 changes: 47 additions & 0 deletions gulpfile.js
@@ -0,0 +1,47 @@
var gulp = require('gulp');
var path = require('path');
var fs = require('fs-extra');

// Lint

gulp.task('lint', function () {
var eslint = require('gulp-eslint');
return gulp.src(['*.js'])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});

// Benchmark

gulp.task('clean', function (done) {
fs.remove(path.join(__dirname, '/cache'), done);
});

gulp.task('bootstrap', function (done) {
var cache = path.join(__dirname, 'cache', 'bootstrap.css');
if ( fs.existsSync(cache) ) return done();

var load = require('load-resources');
load('github:twbs/bootstrap:dist/css/bootstrap.css', '.css', function (f) {
fs.outputFile(cache, f, done);
});
});

gulp.task('preprocessors', ['bootstrap'], function () {
var bench = require('gulp-bench');
var summary = require('gulp-bench-summary');
return gulp.src('./preprocessors.js', { read: false })
.pipe(bench())
.pipe(summary('PostCSS'));
});

gulp.task('parsers', ['bootstrap'], function () {
var bench = require('gulp-bench');
var summary = require('gulp-bench-summary');
return gulp.src('./parsers.js', { read: false })
.pipe(bench())
.pipe(summary('PostCSS'));
});

gulp.task('default', ['lint']);
31 changes: 31 additions & 0 deletions package.json
@@ -0,0 +1,31 @@
{
"private": true,
"dependencies": {
"postcss-simple-vars": "0.3.0",
"gulp-bench-summary": "0.1.0",
"load-resources": "0.1.0",
"postcss-nested": "0.3.1",
"postcss-mixins": "0.3.0",
"postcss-calc": "4.0.1",
"gonzales-pe": "3.0.0-27",
"gulp-eslint": "0.12.0",
"gulp-bench": "1.1.0",
"gulp-util": "3.0.4",
"node-sass": "3.1.1",
"through2": "0.6.5",
"stylecow": "6.5.0",
"gonzales": "1.0.7",
"fs-extra": "0.18.3",
"postcss": "4.1.10",
"mensch": "0.3.1",
"stylus": "0.51.1",
"rework": "1.0.1",
"cssom": "0.3.0",
"less": "2.5.0",
"myth": "1.4.0",
"gulp": "3.8.11"
},
"scripts": {
"test": "gulp"
}
}
76 changes: 76 additions & 0 deletions parsers.js
@@ -0,0 +1,76 @@
/* Results on Fedora 21, Intel 5Y70, 8 GB RAM and SSD:
PostCSS: 37 ms
CSSOM: 38 ms (1.0 times slower)
Mensch: 39 ms (1.0 times slower)
Rework: 67 ms (1.8 times slower)
Stylecow: 120 ms (3.2 times slower)
Gonzales: 173 ms (4.6 times slower)
Gonzales PE: 935 ms (25.0 times slower)
*/

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

var example = path.join(__dirname, 'cache', 'bootstrap.css');
var css = fs.readFileSync(example).toString();

var CSSOM = require('cssom');
var rework = require('rework');
var mensch = require('mensch');
var postcss = require('postcss');
var stylecow = require('stylecow');
var gonzales = require('gonzales');
var gonzalesPe = require('gonzales-pe');

module.exports = {
name: 'Bootstrap',
maxTime: 15,
tests: [
{
name: 'Rework',
fn: function () {
rework(css).toString();
}
},
{
name: 'PostCSS',
defer: true,
fn: function (done) {
postcss.parse(css, { from: example }).toResult();
done.resolve();
}
},
{
name: 'CSSOM',
fn: function () {
CSSOM.parse(css).toString();
}
},
{
name: 'Mensch',
fn: function () {
mensch.stringify( mensch.parse(css) );
}
},
{
name: 'Gonzales',
fn: function () {
gonzales.csspToSrc( gonzales.srcToCSSP(css) );
}
},
{
name: 'Gonzales PE',
fn: function () {
gonzalesPe.parse(css).toString();
}
},
{
name: 'Stylecow',
fn: function () {
var file = new stylecow.Reader(new stylecow.Tokens(css));
stylecow.Root.create(file).toString();
}
}
]
};
173 changes: 173 additions & 0 deletions preprocessors.js
@@ -0,0 +1,173 @@
/* Results on io.js 2.0, Fedora 21, Intel 5Y70, 8 GB RAM and SSD:
PostCSS: 36 ms
Rework: 77 ms (2.1 times slower)
libsass: 136 ms (3.8 times slower)
Less: 160 ms (4.4 times slower)
Stylus: 167 ms (4.6 times slower)
Stylecow: 208 ms (5.7 times slower)
Ruby Sass: 1084 ms (30.1 times slower)
*/

var exec = require('child_process').exec;
var path = require('path');
var fs = require('fs');

var example = path.join(__dirname, 'cache', 'bootstrap.css');
var css = fs.readFileSync(example).toString();

css = css.replace(/\s+filter:[^;\}]+;?/g, '');
css = css.replace('/*# sourceMappingURL=bootstrap.css.map */', '');

// PostCSS
var postcss = require('postcss');
var processor = postcss([
require('postcss-nested'),
require('postcss-simple-vars'),
require('postcss-calc')(),
require('postcss-mixins')
]);
var pcss = css;
pcss += '$size: 100px;';
pcss += '@define-mixin icon { width: 16px; height: 16px; }';
for ( var i = 0; i < 100; i++ ) {
pcss += 'body { h1 { a { color: black; } } }';
pcss += 'h2 { width: $size; }';
pcss += 'h1 { width: calc(2 * $size); }';
pcss += '.search { fill: black; @mixin icon; }';
}

// Myth
var myth = require('myth');
var rcss = css;
rcss += ':root { --size: 100px; }';
for ( var i = 0; i < 100; i++ ) {
rcss += 'body h1 a { color: black; }';
rcss += 'h2 { width: var(--size); }';
rcss += 'h1 { width: calc(2 * var(--size)); }';
rcss += '.search { fill: black; width: 16px; height: 16px; }';
}

// Stylecow
var stylecow = require('stylecow');
stylecow.loadPlugin('variables').loadPlugin('nested-rules').loadPlugin('calc');
var cowcss = css;
cowcss += ':root { --size: 100px; }';
for ( var i = 0; i < 100; i++ ) {
cowcss += 'body { h1 { a { color: black; } } }';
cowcss += 'h2 { width: var(--size); }';
cowcss += 'h1 { width: calc(2 * var(--size)); }';
cowcss += '.search { fill: black; width: 16px; height: 16px; }';
}

// Sass
var libsass = require('node-sass');
var scss = css;
scss += '$size: 100px;';
scss += '@mixin icon { width: 16px; height: 16px; }';
for ( var i = 0; i < 100; i++ ) {
scss += 'body { h1 { a { color: black; } } }';
scss += 'h2 { width: $size; }';
scss += 'h1 { width: 2 * $size; }';
scss += '.search { fill: black; @include icon; }';
}
var scssFile = path.join(__dirname, 'cache', 'bootstrap.scss');
fs.writeFileSync(scssFile, scss);

// Stylus
var stylus = require('stylus');
var styl = css;
styl += 'size = 100px;';
styl += 'icon() { width: 16px; height: 16px; }';
for ( var i = 0; i < 100; i++ ) {
styl += 'body { h1 { a { color: black; } } }';
styl += 'h2 { width: size; }';
styl += 'h1 { width: 2 * size; }';
styl += '.search { fill: black; icon(); }';
}

// Less
var less = require('less');
var lcss = css;
lcss += '@size: 100px;';
lcss += '.icon() { width: 16px; height: 16px; }';
for ( var i = 0; i < 100; i++ ) {
lcss += 'body { h1 { a { color: black; } } }';
lcss += 'h2 { width: @size; }';
lcss += 'h1 { width: 2 * @size; }';
lcss += '.search { fill: black; .icon() }';
}

module.exports = {
name: 'Bootstrap',
maxTime: 15,
tests: [
{
name: 'libsass',
fn: function () {
libsass.renderSync({ data: scss });
}
},
{
name: 'Rework',
defer: true,
fn: function (done) {
myth(rcss, { features: { prefixes: false } });
done.resolve();
}
},
{
name: 'PostCSS',
defer: true,
fn: function (done) {
processor.process(pcss, { map: false }).then(function () {
done.resolve();
});
}
},
{
name: 'Stylecow',
defer: true,
fn: function (done) {
var file = new stylecow.Reader(new stylecow.Tokens(cowcss));
var ast = stylecow.Root.create(file);
stylecow.run(ast);
ast.toString();
done.resolve();
}
},
{
name: 'Stylus',
defer: true,
fn: function (done) {
stylus.render(styl, { filename: example }, function (err) {
if ( err ) throw err;
done.resolve();
});
}
},
{
name: 'Less',
defer: true,
fn: function (done) {
less.render(lcss, function (err) {
if ( err ) throw err;
done.resolve();
});
}
},
{
name: 'Ruby Sass',
defer: true,
fn: function (done) {
var command = 'sass -C --sourcemap=none ' + scssFile;
var dir = __dirname;
exec('cd ' + dir + '; bundle exec ' + command,
function (error, stdout, stderr) {
if ( error ) throw stderr;
done.resolve();
});
}
}
]
};

0 comments on commit 0597811

Please sign in to comment.