Setting up auto compile for Stylus - css

I have installed node.js/stylus/nib on my mac and I can manually compile .styl file to .css on the command line. I also know there is this stylus.middleware() things that keeps coming up when I search for how to setup auto-compiling when the .styl changes, however I have no idea how I am supposed to implement it (I have never used node.js before).
What file do I put that code in?
How do I start this code so it is always run?
I think I am missing a few things on the node side to be able to set this up.

From the command line you can use:
stylus -w folder/
or just for another example:
stylus -w styl/*.styl -o css/
It will watch for changes and compile all *.styl files that live under that folder.

If you installed stylus as a global package (npm install stylus -g) you have a stylus binary on your system.
$ stylus -h
Usage: stylus [options] [command] [< in [> out]]
[file|dir ...]
Commands:
help [<type>:]<prop> Opens help info at MDC for <prop> in
your default browser. Optionally
searches other resources of <type>:
safari opera w3c ms caniuse quirksmode
Options:
-i, --interactive Start interactive REPL
-u, --use <path> Utilize the stylus plugin at <path>
-U, --inline Utilize image inlining via data uri support
-w, --watch Watch file(s) for changes and re-compile
-o, --out <dir> Output to <dir> when passing files
-C, --css <src> [dest] Convert css input to stylus
-I, --include <path> Add <path> to lookup paths
-c, --compress Compress css output
-d, --compare Display input along with output
-f, --firebug Emits debug infos in the generated css that
can be used by the FireStylus Firebug plugin
-l, --line-numbers Emits comments in the generated css
indicating the corresponding stylus line
--include-css Include regular css on #import
-V, --version Display the version of stylus
-h, --help Display help information

This briefly covers some Node basics.
0. Organizing code. It is a convention to put your main Node application code into a file called app.js in the project root.
Inside app.js things are grouped into two general parts:
synchronous initializations: require modules, build directories, read configs, db connections, etc. Things that block, so they must exist or die quickly.
asynchronous app tasks: start server, background processes, auto-compile CSS & JS, routing, i/o, etc. Things that are in the event loop.
1. Compile Stylus to CSS when you build the app. We need to require the stylus module. Usually this is done at the top of the app.js to keep dependencies together.
var stylus = require('stylus');
The first time that Node runs app.js, you need this JS module to build your CSS. This is the basic idea:
stylus.render(stylus-code-string, function(err, css) {
if (err) throw err;
console.log(css);
});
Here is the official Stylus Javascript API.
To use the power of Node, you should read a stylus file using fs module into a buffer, then convert it to a string, and finally pass it into stylus.render(). Then, send the result into a destination file. Since this is part of the build process, it can be synchronous. But this is not really your question...
2. Auto-compile CSS with Stylus as a background process.
This function spawns a child_process that watches a single .styl file and compiles the included .styl files into a .css file. You do not need a module for this, only install the stylus executable so that it runs on the command line. (You have already done this). This example was made with stylus version 0.5.0. Also, the folder paths that you use (ex. build/styles and styles) need to exist.
function watchStyles(sourcefile, destinationfolder) {
var Stylus = child_process.spawn('stylus', ['--sourcemap', '-w', sourcefile, '--out', destinationfolder]);
Stylus.stdout.pipe(process.stdout); // notifications: watching, compiled, generated.
Stylus.stderr.pipe(process.stdout); // warnings: ParseError.
Stylus.on('error', function(err) {
console.log("Stylus process("+Stylus.pid+") error: "+err);
console.log(err);
});
// Report unclean exit.
Stylus.on('close', function (code) {
if (code !== 0) {
console.log("Stylus process("+Stylus.pid+") exited with code " + code);
}
});
}
Next, you need to call this function sometime after you start your app. Pass in your master .styl file as the source. Then the destination directory where you want your CSS to go.
// check that you passed '-w' parameter
if (process.argv[2] && (process.argv[2] == "-w")) {
watchStyles('styles/app.styl', 'build/styles');
}
Start the app by running:
$ node app.js -w
It helps to organize your .styl files under one app.styl so that the contents of your app.styl looks like this:
#import 'layout'
#import 'header'
#import 'main'
#import 'footer'
#import 'modal'
#import 'overrides'

** I end up here yesterday and didn't find the right answer. So this follow up is for anyone else who follows the same path as me... **
I had a problem setting stylus command line up too. I kept trying to install stylus globally
$ npm install -g stylus
and would get errors. I had it working in one project with grunt-contrib-stylus but via command line I wasn't getting anything to work.
Even $stylus --version didn't return anything. I tried to update npm and it broke npm, so I ended up reinstalling node to reinstall npm. Then I was able to do a fresh install of $ sudo npm install -g stylus and could get the --version.
I also had to reinstall grunt and everything else I had installed globally via npm...

First, install stylus locally npm install stylus --save-dev if you haven't.
Create a startup script that builds your stylesheet and rebuilds whenever change detected in your main stylus file:
startup.js
var fs = require('fs')
var stylus = require('stylus')
// Define input filename and output filename
var styleInput = __dirname + '/dev/stylus/main.styl'
var styleOutputFilename = 'main.css'
var styleOutput = __dirname + '/static/' + styleOutputFilename
var stylusPaths = [__dirname + '/dev/stylus', __dirname + '/dev/stylus/libs']
// Build stylesheet on first execute
buildStyles(styleInput, styleOutput, stylusPaths)
// Watch stylus file for changes.
fs.watch(styleInput, function(eventType, filename) {
if (filename) {
buildStyles(styleInput, styleOutput, stylusPaths)
} else {
console.log('no filename found. probably platform doesnt support it.');
}
});
function buildStyles(input, output, paths) {
stylus(fs.readFileSync(input, 'utf-8'))
.set('paths', paths)
.set('include css', true)
.set('watch', true)
.render(function(err, css) {
if (err) throw err;
fs.writeFile(output, css, (err) => {
if (err) throw err;
console.log('👍 Stylesheet built successfully.');
});
});
}
Type node startup.js in the terminal. You will see a message "Stylesheet built successfully." whenever you change your main stylus file.
There is good documentation about stylus javascript api in their website.

OK I edited my answer because you do not want to make a homepage and then connect-assets makes no sense and can not help you... but maybe this,...
http://thechangelog.com/post/3036532096/stylus-expressive-robust-feature-rich-css-language
on that site you find at the bottom a video which shows close to the end how to use stylus via command line...
HTH and sorry for the misunderstanding...

Related

How use bootstrap-sass efficiently?

I'm currently discovering modules with npm, and I went to use bootstrap-sass. Now that the modules were downloaded, I was looking for a solution to compile scss into the static folder of the application, and also the js bootstrap files.
But according to npmjs documentation of the modules, I can't found a simple solution which is not to move the js files myself and compile the scss bootstrap files from node_modules with something like node-sass.
What is the simplest way to use this module correctly and with the possibility to custom ?
Edit :
For now, I am using the following scripts/files :
"compile-js": "browserify assets/static/js/main.js | uglifyjs > assets/static/js/bundle.js",
"compile-sass": "node-sass assets/scss/app.scss assets/static/css/app.css --output-style compressed"
app.scss
#import "../../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap-sprockets.scss";
#import "../../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss";
main.js
global.jQuery = require("jquery")
const bootstrap = require('bootstrap-sass');
I've never used bootstrap-sass before, but the documentation implies that a build tool to preprocess the SCSS is a prerequisite for using this module. While it's no longer the shiniest tool in the shed, Gulp is very capable of handling this task as well as moving the files from node_modules to your project root directory for you.
Here's a breakdown of one approach to implement this:
Create three subfolders in your project root directory and call them sass, css and javascript.
Create a file in the sass folder and call it app.scss. Open it and paste this: #import './node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss';. When the file is converted into CSS, all of the Bootstrap modules will be there. Beneath the #import statement on line 1, feel free to write whatever style rules you want.
Assuming you have already run npm init and have a package.json file in your project directory, run npm install gulp -D in your terminal. This installs gulp (my task runner of choice!).
Run npm install gulp-sass --save-dev. This installs the gulp plugin that will preprocess the Bootstrap SASS into CSS.
Create a file in your root directory (not in any of the subfolders) called gulpfile.js
Copy and paste this text into gulpfile.js:
(note: for this to work, your SASS and CSS folders must be called sass and css, respectively, unless you change their names in the following code.)
var gulp = require('gulp');
var sass = require('gulp-sass');
gulp.task('sass-to-css', function () {
return gulp.src('./sass/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./css'));
});
gulp.task('javascript', function () {
return gulp.src('./node_modules/bootstrap-sass/assets/javascripts/bootstrap.min.js')
.pipe(gulp.dest('./javascript'));
});
gulp.task('default', ['sass-to-css', 'javascript']);
Lastly, run the command gulp in your terminal to execute the gulpfile, which will do two things:
Preprocess and move all of the SASS into your css folder.
Copy bootstrap.min.js from node_modules into your project's javascript folder.
Of course, don't forget to link to these assets in your HTML.
I whipped up this gulpfile on the fly and it works on my machine, but if you decide to try this approach then feel free to ask if something throws an error. Best of luck on your project.

How i can use scss with Underscore theme

I've been looking for many hours at how to use SCSS in the Underscore theme that I downloaded with _sassify.
When I open the folder and I see the style.css and the folder with scss files, the theme use css but I want change and use the scss file.
I don't understand how to use it.
What is the process to use scss? Can someone help me with this?
Thanks
You have to use a preprocessor to compile scss to css. The theme uses css, this will not change. You do your changes in scss - then scss compiles to css. A preprocessor can be part of your IDE, you can use programs like Koala, Scout, Prepros or you use the sass command line.
You should start reading here:
http://sass-lang.com
Try compiling your first .scss files in a test directory with help of http://sass-lang.com/guide:
sass input.scss output.css
Then start tweaking _s.
I spent a few days how to change styles in Underscore Theme with scss files to css file. Earlier I worked with Gulp so I wanted to create gulpfile that will work. I created normal file with Gulp which at first didn't work - it worked in cmd, but on Wordpress nothing changed. But after adding a plugin WP-SCSS finally it works! So thanks a lot for your answer Jonathan and for helping me to find this plugin. Maybe it will help someone, so below I add the code from the gulpfile.
// gulpfile.js
var gulp = require("gulp"),
sass = require("gulp-sass"),
postcss = require("gulp-postcss"),
autoprefixer = require("autoprefixer"),
cssnano = require("cssnano"),
sourcemaps = require("gulp-sourcemaps");
function style() {
return (
gulp
.src(paths.source.src)
.pipe(sourcemaps.init())
.pipe(sass())
.on("error", sass.logError)
.pipe(postcss([autoprefixer(), cssnano()]))
.pipe(sourcemaps.write())
.pipe(gulp.dest(paths.source.dest))
);
}
// $ gulp style
exports.style = style;
var paths = {
source: {
// By using styles/**/*.sass we're telling gulp to check all folders for any sass file
src: "sass/**/*.scss",
// Compiled files will end up in whichever folder it's found in (partials are not compiled)
dest: "."
}
};
function watch() {
gulp.watch("sass/**/*.scss", style);
}
// $ gulp watch
exports.watch = watch
You need to follow the steps from this page https://github.com/Automattic/_s
Setup
To start using all the tools that come with _s you need to install the necessary Node.js and Composer dependencies :
$ composer install
$ npm install
Available CLI commands
_s comes packed with CLI commands tailored for WordPress theme development :
composer lint:wpcs : checks all PHP files against PHP Coding Standards.
composer lint:php : checks all PHP files for syntax errors.
composer make-pot : generates a .pot file in the languages/ directory.
npm run compile:css : compiles SASS files to css.
npm run compile:rtl : generates an RTL stylesheet.
npm run watch : watches all SASS files and recompiles them to css when they change.
npm run lint:scss : checks all SASS files against CSS Coding Standards.
npm run lint:js : checks all JavaScript files against JavaScript Coding Standards.
npm run bundle : generates a .zip archive for distribution, excluding development and system files.
I'm not sure about the Underscore theme specifically, but I have used this plugin in the past and I really like it. It lets you use SCSS with any theme and automatically compiles the files for you.

Browserify failing with cannot find module "lodash" error for some files

I am running browserify for an app.js located at some path and it fails everytime with cannot find module lodash from [PATH].
Running "browserify:build" (browserify) task
Error: Cannot find module 'lodash' from '/var/lib/jenkins/buildcode/output/mydir/app_store_richUI/cartridge/js'
Warning: Error running grunt-browserify. Use --force to continue.
The [PATH] is same where the app.js file is present. But, if I change the file name to some other js file at same path, it works. So, the scene is that it succeeds for some js file and fails for others at same path.
Can someone suggest something ?
I have the Browserify.js script installed globally.
Browserify.js
module.exports = {
build: {
files: {
'<%= settings["local.build.dir"] %>/output/<%= grunt.config("build") %>/app_eyeconic_richUI/cartridge/static/default/js/eyeconic.app.js':'<%= settings["local.build.dir"] %>/output/<%= grunt.config("build") %>/app_eyeconic_richUI/cartridge/js/app.js'
},
}
}
The path is shown correctly in the logs with other files. It fails only with app.js file
It was a very trivial issue but took quite some time to resolve.
The issue was that the build suite was at a different location than the build source.
The browserify task contained require statements and it searches for modules in the parent directories so it was not able to find the required module.
After copying the build suite at the same path as the source, it worked.
So currently, my gruntfile.js(and other files/folders in the suite), exports and output directory at are same path.

scss builder for cloud9 web editor

Hey there :) I'm trying to figure out how I can make a scss builder for cloud9. I could only find something for less here on stackoverflow.
I'm trying to get main.scss in my scss folder to be compiled into main.css in a css folder at the same level.
The builder:
{
"caption" : "SCSS",
"cmd": ["scss", "$file", "-x", "${file/\\.scss/\\.css/}"],
"selector": "source.scss"
}
Error:
OptionParser::InvalidOption: invalid option: -x
Use --trace for backtrace.
I think the way you're using the Cloud9 builder is correct, however, I couldn't find the -x option within scss. Here's what scss -h gives me:
Usage: scss [options] [INPUT] [OUTPUT]
Description:
Converts SCSS or Sass files to CSS.
Common Options:
-I, --load-path PATH Specify a Sass import path.
-r, --require LIB Require a Ruby library before running Sass.
--compass Make Compass imports available and load project configuration.
-t, --style NAME Output style. Can be nested (default), compact, compressed, or expanded.
-?, -h, --help Show this help message.
-v, --version Print the Sass version.
Watching and Updating:
--watch Watch files or directories for changes.
The location of the generated CSS can be set using a colon:
scss --watch input.scss:output.css
scss --watch input-dir:output-dir
--poll Check for file changes manually, rather than relying on the OS.
Only meaningful for --watch.
--update Compile files or directories to CSS.
Locations are set like --watch.
-f, --force Recompile every Sass file, even if the CSS file is newer.
Only meaningful for --update.
--stop-on-error If a file fails to compile, exit immediately.
Only meaningful for --watch and --update.
Input and Output:
--sass Use the indented Sass syntax.
--sourcemap=TYPE How to link generated output to the source files.
auto (default): relative paths where possible, file URIs elsewhere
file: always absolute file URIs
inline: include the source text in the sourcemap
none: no sourcemaps
-s, --stdin Read input from standard input instead of an input file.
This is the default if no input file is specified.
-E, --default-encoding ENCODING Specify the default encoding for input files.
--unix-newlines Use Unix-style newlines in written files.
Always true on Unix.
-g, --debug-info Emit output that can be used by the FireSass Firebug plugin.
-l, --line-numbers Emit comments in the generated CSS indicating the corresponding source line.
--line-comments
Miscellaneous:
-i, --interactive Run an interactive SassScript shell.
-c, --check Just check syntax, don't evaluate.
--precision NUMBER_OF_DIGITS How many digits of precision to use when outputting decimal numbers.
Defaults to 5.
--cache-location PATH The path to save parsed Sass files. Defaults to .sass-cache.
-C, --no-cache Don't cache parsed Sass files.
--trace Show a full Ruby stack trace on error.
-q, --quiet Silence warnings and status messages during compilation.
Here's something that should work for you:
{
"cmd" : ["scss", "$file", "$file_path/../css/$file_base_name.css"],
"info" : "Building $file_path/$file_name",
"selector": "source.scss"
}
Where $file is the full path, $file_path is the directory path, and $file_base_name is the name of your file without the extension. You can take a look at the other variables available to you here.

Grunt-newer with Grunt-uglify and Bower

I've got a project using Grunt and Bower. Grunt-uglify will concatenate/minify files from the Bower directory to the deploy/scripts.js folder. I'm using Grunt-newer so it will only update deploy/scripts.js if new files are added or changed. Everything works great...except...
When I add a new library with Bower, file date reflects when the file was uploaded to the Bower library (or whoever is hosting it), not the date it was create on my computer. Thus, Grunt-newer sees the new Bower libraries are being older than deploy/scripts.js and does not update the file.
One--cumbersome--solution is to open the new library .js file, and resave it. It modifies the file dates and thus, grunt-newer will create the deploy/script.js file. However, the usefulness of Bower seems moot with such an awkward solution.
You can use Bower hooks in order to manipulate the files modification time. This is kind of a hack but can achieve what you are looking for.
You will need to register a postinstall hook and pass the list of updated components as an argument. When the script is called, the % will be replaced with a space-separated list of components being installed or uninstalled.
The hooks should be registered in the .bowerrc file:
{
"scripts": {
"postinstall": "hook.sh %"
}
}
Then you will need a script which iterates over the components and changes the modification time of the files.
For example a shell script:
#!/bin/bash
for var in "$#"
do
find "./bower_components/$var" -exec touch {} \;
done
Here is another example of a node.js script for the same purpose:
var fs = require('fs');
var path = require('path')
var components = process.argv.slice(2)
components.forEach(function (comp) {
var comp_path = path.join(process.cwd(),"bower_components",comp);
var files = fs.readdirSync(comp_path);
files.forEach(function(file) {
fs.utimesSync(path.join(comp_path, file), new Date(), new Date());
});
});

Resources