How to make Grunt configuration variables accessible to CoffeeScript files? - javascript

This is my Gruntfile:
'use strict';
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
grunt.initConfig({
site: grunt.file.readYAML('_config.yml'),
coffee: {
dist: {
files: [{
expand: true,
cwd: "<%= site.src %>/assets/scripts",
src: "{,*/}*.coffee",
dest: "<%= site.tmp %>/assets/scripts",
ext: ".js"
}]
}
}
});
grunt.registerTask('default', ['coffee']);
}
I want to have app/assets/scripts/globals.coffee look something like this:
jQuery ($) ->
window.Site = "<%= site %>"
How can I interpolate the site variable in CoffeeScript files?
I tried using plugins like grunt-contrib-handlebars and grunt-contrib-jst, but those generate JST files which I think isn't what I want.

Looks to me like a combination of Yaml and Assemble's Data would do what you need.
http://assemble.io/docs/Data.html
FTA:
YAML example
Here is the same in YAML format:
my-template.yml
title: Assemble
author: Brian Woodward
And this template:
my-template.hbs
<h1>{{ title }}</h1>
You can adapt that to insert a script tag at the top of the page that sets window.Site = {{site.name}}.

Related

Does this part of Gruntfile combine multiple files to one?

I have a Grunt file with the following content:
module.exports = function(grunt) {
// require('load-grunt-tasks')(grunt);
/* global process */
// configures browsers to run test against
// any of [ 'PhantomJS', 'Chrome', 'Firefox', 'IE']
var TEST_BROWSERS = ((process.env.TEST_BROWSERS || '').replace(/^\s+|\s+$/, '') || 'PhantomJS').split(/\s*,\s*/g);
// project configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
config: {
app: 'app',
sources: 'lib',
tests: 'test'
},
release: {
options: {
tagName: 'v<%= version %>',
commitMessage: 'chore(project): release v<%= version %>',
tagMessage: 'chore(project): tag v<%= version %>'
}
},
browserify: {
options: {
browserifyOptions: {
builtins: false
},
bundleOptions: {
detectGlobals: false,
insertGlobalVars: [],
debug: true
}
},
watch: {
files: {
'<%= config.app %>/bpmn-viewer.js': [ '<%= config.app %>/bpmn.js', 'index.js' ]
},
options: {
watch: true
}
},
standaloneViewer: {
files: {
'<%= config.app %>/bpmn-viewer.js': [ '<%= config.app %>/bpmn.js', 'index.js' ]
},
options: {
alias: [
'jquery:jquery',
'lodash:lodash',
'index.js:bpmn-js-diffing',
'<%= config.app %>/bpmn.js:bpmn-js'
]
}
},
},
jsdoc: {
dist: {
src: [ '<%= config.sources %>/**/*.js' ],
options: {
destination: 'docs/api',
plugins: [ 'plugins/markdown' ]
}
}
}
});
// tasks
grunt.registerTask('test', [ 'karma:single' ]);
grunt.registerTask('auto-test', [ 'karma:unit' ]);
// grunt.registerTask('default', [ 'jshint', 'test', 'browserify:standaloneViewer', 'jsdoc' ]);
grunt.registerTask('default', [ ]);
};
I know that somewhere in this file there must be an expression that minifies the code (I inherited the code from someone else, therefore I don't know how it works). The resulting file is called bpmn-viewer.js.
Could the lines
standaloneViewer: {
files: {
'<%= config.app %>/bpmn-viewer.js': [ '<%= config.app %>/bpmn.js', 'index.js' ]
},
mean that the files '<%= config.app %>/bpmn.js', 'index.js' should be combinded to <%= config.app %>/bpmn-viewer.js?
If possible, please provide links to the documentation that describes it.
There is some information missing, like the project you forked off and the package.json dependencies.
Luckily, I found https://github.com/bpmn-io/bpmn-js-diffing and that's probably the project you forked. Lets note that this project is very old and so are its dependencies, which I had to fix for it to work, so the versioning alone might change my results from yours.
What I didn't find were minified contents. The file app/bpmn-viewer.js is the concatenation result. The multiple files are concat into this one, yes, but there's only the browserify header that is always minified within bpmn-viewer.js.
First off, you commented load-grunt-tasks and the "default" grunt task, so I'm not sure you really ran grunt of this Gruntfile.js. Commenting it out cannot work, because there are no calls to grunt.loadNpmTasks as far as I'm aware, grunt plugins are not loaded without any loading instruction.
Now to the documentation. You are right that the concatenation happens because of the files field. This is part of Grunts Task definition layout.
Browserify analyzes the given files and concats them into one. That's the abstract description, more of that in the browserify handbook.
Still keep in mind: The versions of your forked project are very old.
So here's what I could find out in short:
No, the contents are not minified
A browserify header (which are minified) and the source map contents are added to the final file
If you really have minified content, please provide the package.json dependencies and the real running Gruntfile.js.

Grunt / Babel error: Unable to write "dist" file (Error code: EISDIR)

I am new to Grunt and all its plugins, but I want to learn and setup some awesome front-end tools. With that said, I have been following the Grunt docs and some's similar issue with Grunt and Babel via Github, but I seem to keep getting the following traceback:
Running "babel:dist" (babel) task
Warning: Unable to write "dist" file (Error code: EISDIR). Use --force to continue.
Aborted due to warnings.
Any clearer explanation to this newbie would be HIGHLY appreciated. I'm new to programming in JS and setting up DevOps, so some helpful tips and best practices are encouraged.
Setup:
js_practice/ (Root Project)
|----package.json
All the distributions and packages
|---node_modules/
Server-Side (Node) support
|---es6/
| ------ test.js
|---dist/
Client (browser) support
|----public/
|---es6/ (this is within the public folder)
| ----- test2.js
|---dist/ (this is within the public folder)
Here is my current code:
Grunt file.js
module.exports = function(grunt) {
// All of your Grunt code must be specified inside this function!
// Setup configuration...
// Load tasks...
// Define tasks...
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
babel: {
options: {
sourceMap: true,
presets: ['babel-preset-es2015']
},
dist: {
files: [
// Node source
{
src: ['es6/**/*.js'],
dest: 'dist'},
// Browser source
{
src: ['public/es6/**/*.js'],
dest: 'public/dist'},
],
},
},
browserify: {
dist: {
options: {
transform: [["babelify", { "stage": 0 }]]
},
files: {
"build/bundle.js": "src/main.js"
}
}
},
jshint: {
scripts: {
src: ['scripts/**.js', 'lib/**.js']
},
tests: { // We can have more than one jshint task, this ones called `jshint:tests`
src: 'tests/**.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
},
scripts: {
expand: true,
cwd: 'scripts/',
src: '**.js',
dest: 'build/',
ext: '.min.js'
}
},
watch: {
scripts: {
files: ['**/*.js'],
tasks: ['jshint'],
},
styles: {
files: 'styles/**.less',
task: 'less:styles'
}
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-babel');
grunt.registerTask('default', ['babel','browserify','jshint']);
grunt.registerTask('build', ['jshint', 'uglify']);
};
Just expanding on what I said in the comments
Any clearer explanation to this newbie would be HIGHLY appreciated.
Nodejs is trying to write a file called dist, but produces an error because a directory with this name exists.
The cause of this is found in the babel task.
files: [{
src: ['es6/**/*.js'],
dest: 'dist'
},
// Browser source
{
src: ['public/es6/**/*.js'],
dest: 'public/dist'
}]
You have to tell Babel to take each file in es6/, transform them and place the new files in the dist/ folder. As it stand now, the transformer tries to create a file called dist. Rewriting it to
files: [{
expand: true,
cwd: 'es6/'
src: ['**/*.js'],
dest: 'dist/'
},
// Browser source
{
expand: true,
cwd: 'public/es6/'
src: ['**/*.js'],
dest: 'public/dist/'
}]
should yield a better result, but play around with it. Like I mentioned, I haven't used Grunt in a while. Take a look at the documentation on building the files object
And like I said in the comments, use jshint or other such tools (eslint is all the hype...) to keep your own code neat. Don't waste time by running a jshint task on lib files that you probably don't want to fix yourself anyway. And always run jshint on the source files, not files that are transformed by babel or browserify. It's just a tool to help you write better code, not some generator.

Save jade file to html with same name

Trying to get jade to save my jade files as HTML files while keeping the same file name.
So the file views/index.jade should save as dist/index.html
Same for additional files.
I am using grunt-contrib-jade
The jade configuration of my Gruntfile:
module.exports = function(grunt){
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jade: {
compile: {
options: {
pretty: true
},
files: {
'dist/*.html': ['views/*.jade']
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-jade');
grunt.registerTask('default', ['jade']);
};
But it just saves the file as *.html
I think it's doing what you are telling it to do.
Try this for configuration of the jade task:
jade: {
compile: {
options: {
pretty: true
},
files: [{
expand: true, // setting to true enables the following options
cwd: '/jade', // src matches are relative to this path
src: ['{,*/}*.jade'], // matches *.jade in cwd and 1 level down
dest: 'dist/', // destination prefix
ext: '.html' // replace existing extensions with this value
}]
}
}
here is is some information about building file lists dynamically with Grunt.

Include in nunjucks (grunt-nunjucks-2-html) are based on an incorrect path

I'm using Nunjucks with grunt/node via the grunt plugin grunt-nunjucks-2-html
My root path is where the gruntfile is, so it's look like this:
./src
index.html
expo.html
./inc
head.html
header.html
My gruntfile config looks like this :
nunjucks: {
render: {
files: [
{
expand: true,
cwd: 'src/',
src: "*.html",
dest: pathbuild,
ext: ".html"
}
]
}
},
in my index.html I have this:
{% include "inc/head.html" %}
When I try grunt nunjucks, this is what I get
Warning: (unknown path) Error: template not found: inc/head.html
Use --force to continue.
That can be solved if I change path to "src/inc/head/html" but I don't get why I need to specified this, seems not logical to me.
Do you have something to teach to me that I've missed so hard?
Thanks.
I had the same issue and after looking at the plugin code, I noticed that the template path had to be supplied as an array:
nunjucks: {
options: {
paths: ['templates'], // 'templates' as a string can now be passed (30Oct2014)
data: grunt.file.readJSON('results.json')
},
render: {
files: [
{
expand: true,
cwd: "templates/",
src: "*.html",
dest: "build/",
ext: ".html"
}
]
}
}
I've sent a pull request (https://github.com/vitkarpov/grunt-nunjucks-2-html/pull/4) so if it gets accepted, we'll be able to supply the template path as a string.
Update 30-Oct-14: The pull request has been merged, so a string or array can be passed to options.paths.

Compile and merge coffeescript and javascript using grunt

I have included a library written in Javascript, and also have some coffeescript code which depends on these libraries.
When I publish using GRUNT I want to create a single Javascript file which is made by combining all the JS and Coffee files together. Apparently neither grunt-contrib-uglifyjs nor Grunt-contrib-coffee supports such kind of behavior. What is the solution to this problem?
You can use concat to do that.
For example, in your Gruntfile.js:
module.exports = function(grunt) {
return grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// EDIT: TO COMPILE YOUR COFFEESCRIPT
coffee: {
"default": {
src: paths.coffee_src,
dest: paths.js_dir,
options: {
preserve_dirs: true,
base_path: paths.coffee_dir
}
}
},
concat: {
options: {
separator: ';'
},
dist: {
src: ['assets/javascripts/libs/underscore/underscore.js', 'assets/javascripts/libs/jquery/jquery.js', 'assets/javascripts/libs/json2/json2.js', 'assets/javascripts/libs/handlebars-wycats/dist/handlebars.js', 'assets/javascripts/libs/backbone/backbone.js', 'assets/javascripts/libs/marionette/lib/backbone.marionette.js', 'assets/javascripts/*.js', 'assets/javascripts/utilities/*.js', 'assets/javascripts/models/*.js', 'assets/javascripts/collections/*.js', 'assets/javascripts/modules/**/**/*.js'],
dest: '<%= pkg.name %>.js'
}
},
// ...
// EDIT: TO MINIFY YOUR CONCATENATED JS
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
// ...
Here I'm concatenating all files in that order (starting with underscore.js), so, you'll have a single js file with all those files, in the specific order that you desire.
Check this documentation for more information.
Grunt is a nodejs file and execute like nodejs. So try this:
require('child_process').exec('coffee --compile --output lib/ src/', function () {
/*add callback or use execSync */
});
Just edit coffee command.

Categories