Compiling files with laravel + elixir - css

I am taking over a laravel project that uses elixir to compile various sass, coffeescript, and javascript files:
elixir(function(mix) {
mix.sass('main.scss')
.coffee(['methods.coffee', 'details.coffee', 'cars.coffee', 'context-menu.coffee', 'content.coffee', 'projects.coffee', 'main.coffee'])
.styles(['main.css'], 'public/css/all.css', 'public/css')
.scripts(['app.js'], 'public/js/all.js', 'public/js')
.version(['css/all.css', 'js/all.js']);
});
My questions:
What is the destination of the files below after they are compiled?
.coffee(['methods.coffee', 'details.coffee', 'cars.coffee', 'context-menu.coffee', 'content.coffee', 'projects.coffee', 'main.coffee'])
Does the line below compile the app.js file as all.js and store it in public/js?
.scripts(['app.js'], 'public/js/all.js', 'public/js')
Similarly, does the line below compile the main.css file as all.css and store it in public/css?
.styles(['main.css'], 'public/css/all.css', 'public/css')
Thanks in advance!

By default, the task will place the compiled in:
sass = public/css/app.css
coffee = public/js/app.js
scripts= public/js/all.js
styles = public/css/all.css
UPDATE
To change the output path just pass a second argument to the method
e.g.
mix.styles([
'bundle.css'
], 'public/css/aloha');

Related

how to dynamically build watch task's targets?

using gurunt syncall, I want to dynamically sync every dir(and new dir created in the futrue) in project root except 'node_modules' dir to another dir.
using grunt watchall, I want to watch those dirs, when there are some changes in a dir, I want to automaticlly run the corresponding sync task.
here is my project root's structure:
├── Gruntfile.js
├── addon1
│   └── a.toc
├── adon3
│   └── 3.toc
├── node_modules
│   ├── grunt
│   ├── grunt-contrib-watch
│   └── grunt-sync
└── package.json
the grunt syncall command is ok, here is the result:
➜ testsync grunt syncall
Running "config" task
Running "sync:addon1" (sync) task
Running "sync:adon3" (sync) task
Done, without errors.
but the grunt watchall not ok. can you tell me why watchall tasks not work and how to fix it?
I start the command, and change and save the file '3.toc' in dir 'adon3', then grunt say:
➜ testsync grunt watchall
Running "config" task
Running "watch" task
Waiting...
>> File "adon3/3.toc" changed.
Running "sync:adon3" (sync) task
Verifying property sync.adon3 exists in config...ERROR
>> Unable to process task.
Warning: Required config property "sync.adon3" missing. Use --force to continue.
Aborted due to warnings.
here is my Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({});
var destdir = "/Users/morrxy/project/testdest/";
// dynamic config sync and watch's targets for every dir except for node_modules
grunt.registerTask('config', 'config sync and watch', function() {
grunt.file.expand({filter: 'isDirectory'},
['*', '!node_modules']).forEach(function(dir) {
// config sync's targets
var sync = grunt.config.get('sync') || {};
sync[dir] = {
files: [{
cwd: dir,
src: '**',
dest: destdir + dir
}]
};
grunt.config.set('sync', sync);
// config watch's target
var watch = grunt.config.get('watch') || {};
watch[dir] = {
files: dir + '/**/*',
// is next line has problem?
// running 'grunt watchall'
// when I change and save the file '3.toc' in dir 'adon3', terminal say:
// >> File "adon3/3.toc" changed.
// Running "sync:adon3" (sync) task
// Verifying property sync.adon3 exists in config...ERROR
// >> Unable to process task.
// Warning: Required config property "sync.adon3" missing.
// but why 'grunt syncall' can work?
tasks: 'sync:' + dir
};
grunt.config.set('watch', watch);
});
});
grunt.loadNpmTasks('grunt-sync');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('syncall', ['config', 'sync']);
grunt.registerTask('watchall', ['config', 'watch']);
};
Finally, I solved this problem. I add a github repo for this question. If you want test, you can clone it run it locally. https://github.com/morrxy/dynasync
The reason watchall can watch files changes but can't run the corresponding sync task is that when watch find files changed, the config for each sync is finnished running, so the config for that sync target is gone, we didn't save the running config any where. So to solve this problem, we could add the config task into the watch task before the sync task, like this tasks: ['config_sync', 'sync:' + dir].
in new Gruntfile.js, I split the config task to two task, one for config watch, one for config sync, in the watch task, using the config sync task. Here is the new Gruntfile.js
module.exports = function(grunt) {
var destdir = "/media/data/projects/dynasync_dest/";
grunt.loadNpmTasks('grunt-sync');
grunt.loadNpmTasks('grunt-contrib-watch');
// dynamic config sync's targets for every dir except for node_modules
grunt.registerTask('config_sync', 'dynamically config sync', function() {
grunt.file.expand({filter: 'isDirectory'},
['*', '!node_modules']).forEach(function(dir) {
// config this dir's sync target
var sync = grunt.config.get('sync') || {};
sync[dir] = {
files: [{
cwd: dir,
src: '**/*',
dest: destdir + dir
}]
};
grunt.config.set('sync', sync);
});
});
// dynamic config watch's targets for every dir except for node_modules
grunt.registerTask('config_watch', 'dynamically config watch', function() {
grunt.file.expand({filter: 'isDirectory'},
['*', '!node_modules']).forEach(function(dir) {
// config this dir's watch target
var watch = grunt.config.get('watch') || {};
watch[dir] = {
files: dir + '/**/*',
// this line solve the problem
// when find file change, first dynamically config sync and then sync the dir
tasks: ['config_sync', 'sync:' + dir]
};
grunt.config.set('watch', watch);
});
});
grunt.registerTask('syncall', ['config_sync', 'sync']);
grunt.registerTask('watchall', ['config_watch', 'watch']);
grunt.registerTask('default', ['watchall']);
};
This time, when watch find file changes, it can run the corresponding sync task. like this
grunt watchall
Running "config_watch" task
Running "watch" task
Waiting...
>> File "adon3/3.toc" changed.
Running "config_sync" task
Running "sync:adon3" (sync) task
Done, without errors.
Completed in 0.888s at Thu Apr 10 2014 14:01:26 GMT+0800 (CST) - Waiting...

How do I make sure grunt only selects files (not folders)?

I'm trying to concatenate all the JS libraries in our project into a single file. So I've set up a concat task in grunt, with the following file selector:
dist : {
src : ["public/lib/**/*.js"],
dest : "public/lib.concat.js"
}
So far so good. However, we use sprintf.js in our project. So there is a sprintf.js directory inside of public/lib and that directory is matched by the src selector in grunt.
The result of that is:
$ grunt
Running "concat:dist" (concat) task
Warning: Unable to read "public/lib/sprintf.js" file (Error code: UNKNOWN). Use --force to continue.
I'm aware that I could simply pick a different name for the sprintf.js directory, but I would like to know if there is a way to tell grunt to only select actual files, not directories.
Use filter option to ignore directories:
dist : {
src : ["public/lib/**/*.js"],
dest : "public/lib.concat.js",
filter: function(filepath) {
return !grunt.file.isDir(filepath);
}
}
it should be even easier. you can just exclude with an exclamation pointer:
dist : {
src : ["public/lib/**/*.js", "!public/lib/sprintf.js" ],
dest : "public/lib.concat.js"
}

Can I call js module in grunt configuration file gruntfile.coffee?

I'm using gruntjs to building my project. I want to utilize js module for multi-projects i.e. multi-gruntfile.
I see the API and search grunt plugins but not find what I want. It seems the only way is taking advantage of grunt.config and load-grunt-tasks plugin.
So I created js module file in the tasks folder and set configuration data in it like the following(by coffeescript):
module.exports = (grunt) ->
_ret=null
environmentObj=
test: "test"
verify: "beta"
formal: "release"
grunt.config.set('executeCustomTasks', (arg, arg1, arr) ->
str = constructPromptStr();
_ret = getVerInfo(arg1, arg)
setArg()
...
)
setArg = ->
if _ret.verName is 'formal'
_ret.verName = ''
grunt.config.set('state',_ret.verName)
grunt.config.set('date',_ret.verNum)
and call it like this:
grunt.task.registerTask('default', 'execute tasks by param by grunt cli', (arg, arg1) ->
grunt.config.get('executeCustomTasks')(arg, arg1,getTasksArr(arg))
)
Is what I do correct? Is it the best practice?
Best Regards
I understand now. grunt.task.loadTasks(path) can Load task-related files so I can create and reference the files in the path.
reference links:
http://gruntjs.com/api/grunt.task
https://github.com/cowboy/wesbos/commit/5a2980a7818957cbaeedcd7552af9ce54e05e3fb

Grunt Concat cannot write to file

Just installed latest Grunt on Ubuntu 12.04. Here is my gruntfile:
module.exports = function(grunt){
//project configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
slides : {
src : ['src/top.html', 'src/bottom.html'],
dest : ['build/index.html']
}
}
});
//enable plugins
grunt.loadNpmTasks('grunt-contrib');
grunt.registerTask('default', ['concat:slides']);
}
This creates the build/ directory fine, but gives me the output of:
Running "concat:slides" (concat) task Warning: Unable to write
"build/index.html" file (Error code: undefined). Use --force to
continue.
I tried running chmod 777 on the directory, as I thought it might have something to do with permissions, but that didn't seem to change anything.
How can I make it so Grunt will write to build/index.html?
Figured it out:
//Does not work
dest : ['build/index.html']
Works as a string, but not an array:
//Works
dest : 'build/index.html'
I changed tasks/concat.js to accept arrays for dest:
// Write the destination file.
// If f.dest is an array take the first element
var dest = ([].concat(f.dest))[0]
grunt.file.write(dest, src);
but later I decided to use the files form instead of src/dest:
files: { 'dest.js': ['a.js', 'b.js'] }

Compass/Sinatra Loading Modules

I'm trying to load the CSS3 and reset modules within my SCSS files, but I'm getting an error when trying to import any Compass-specific module.
Sinatra App:
require 'rubygems'
require 'sinatra'
require 'sass'
require 'compass'
configure do
set :scss, {:style => :compact, :debug_info => false}
Compass.add_project_configuration(File.join(Sinatra::Application.root, 'config', 'compass.rb'))
end
get '/css/:name.css' do
content_type 'text/css', :charset => 'utf-8'
scss(:"stylesheets/#{params[:name]}" )
end
style.scss:
#import "compass/reset";
#import "compass/css3";
Error Message:
Sass::SyntaxError at /css/style.css
File to import not found or unreadable: compass/reset. Load path: /Users/work/repos/mysite
Is there a gem I can install to automatically pull these modules, or do I have to move the Compass files into my Sinatra application?
After a correct configuration in your compass.rb, usually is enough to add something like:
get '/stylesheets/:name.css' do
content_type 'text/css', :charset => 'utf-8'
sass params[:name].to_sym, Compass.sass_engine_options
end
to your routes. Sinatra Integration, Sample project, or something you may consider useful: Better Compass integration for Sinatra (extracted from BigBand)
In a modular Modular App I use something like:
module Assets
# #Sass/Compass Handler
class Stylesheets < Sinatra::Base
register CompassInitializer
get '/stylesheets/:name.css' do
content_type 'text/css', :charset => 'utf-8'
sass params[:name].to_sym, Compass.sass_engine_options
end
end
end
and I have in my lib folder a file compass_plugin.rb
module CompassInitializer
def self.registered(app)
require 'sass/plugin/rack'
Compass.configuration do |config|
config.project_path = Padrino.root
config.sass_dir = "app/stylesheets"
config.project_type = :stand_alone
config.http_path = "/"
config.css_dir = "public/stylesheets"
config.images_dir = "public/images"
config.javascripts_dir = "public/javascripts"
config.output_style = :compressed
end
Compass.configure_sass_plugin!
Compass.handle_configuration_change!
app.use Sass::Plugin::Rack
end
end
which is shamelessly stolen from Padrino framework
I think you should just:
$ gem install compass
$ compass create

Resources