0

I'm working on a project and I've checked a couple downloads left and right and I can accross Grunt. It's a tool which I would like to use without a doubt.

I've setup a basic Grunt file that enables livereload to work, so whenever I change my .html files, the page is refreshed.

That's all working good. See the snippet below which given you an overview of my current Gruntfile.js

'use strict';

var mountFolder = function (connect, dir) {
    return connect.static(require('path').resolve(dir));
};

// The main entry point for the Grunt configuration file.
module.exports = function(grunt) {

    // Load all the grunt tasks which are defined in the 'package.json' file.
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // Initial grunt configuration.
    grunt.initConfig({

        // grunt-express configuration.
        // Grunt-Express will serve files from the folder listed in the 'bases' property on the specified hostname
        // and port.
        express: {
            all: {
                options: {
                    bases: ['source'],
                    port: 8080,
                    hostname: "0.0.0.0",
                    livereload: true
                }
            }
        },

        // grunt-watch configuration.
        // Grunt-Watch will monitor the project files.
        watch: {
            all: {
                options: {livereload: true },
                files: [
                    '**/*.html'   // Refresh when any HTML file is being updated in any folder.
                ]
            }
        },

        // grunt-open configuration.
        // Grunt-Open will open your browser at the project url's.
        open: {
            all: {
                // The port is loaded dynamically here through the 'express.all.options.port' property.
                path: 'http://localhost:<%= express.all.options.port %>'
            }
        }
    });

    // Creates the various grunt tasks that needs to be executed.
    grunt.registerTask('server', [
        'express',
        'open',
        'watch'
    ]);
};

Now, in my project I'm using SASS (scss) files and I know that to compile those files I need a plugin called https://github.com/gruntjs/grunt-contrib-sass

In the directory structure of my application I'm having a 'source' folder, and off course I don't want to have 'css' files in there.

So, how can I place a link in my HTML that points to a css file that will be generated by the grunt task?

I'm thinking about compiling the scss files to a temp folder, but in my HTML file, I don't want to put 'temp/...' links. They should be mounted or something else.

Anyone knows how to achieve what I want?

Kind regards

Complexity
  • 5,682
  • 6
  • 41
  • 84
  • Hi there, this http://stackoverflow.com/questions/21859082/how-to-setup-gruntfile-js-to-watch-for-sass-compass-and-js should help? – JBux Jul 06 '15 at 11:33
  • Hi there. Thanks for your answer but I don't see how that should help me. It's only giving me information on how to setup the watch and compile the sass files. It doesn't give any information on how to work with the temp folders in order to make livereload work. – Complexity Jul 06 '15 at 11:39

2 Answers2

1

In response to your comment, you want to remove 'all' from watch and replace with something like:

options: {
    livereload: true
},
html: {
    files: ['**/*.html']
},
css: {
    files: ['**/css/*.css']
},
sass: {
    options: {
        livereload: false
    },
    files: ['**/sass/*.scss'],
    tasks: ['sass']
}

Grunt will watch all the folders specified and perform the tasks you've defined, but will only livereload when html files or css files have changed.

This means you won't see a reload when you save scss files, but once they've been compiled to css you will see a reload. This is because you have explicitly told grunt not to livereload sass files.

JBux
  • 1,394
  • 8
  • 17
  • Thanks for your comment but I'm totally new. You mind explain why and how that's helping my problem? – Complexity Jul 06 '15 at 11:55
  • Thanks. Note fully there, but getting close. Let's say that in my HTML file I reference a css file. This is working correctly, but I would like livereload to compile my SASS files to a specific directory. And now without changing the paths in my HTML file I would like to see the changes. In a Yeoman app, this is done through middleware and mounting. However I'm using the grunt-express plugin and don't know how it should be done there. – Complexity Jul 06 '15 at 12:02
  • You're not getting livereload to compile anything. Livereload just finds changes you've specified and reloads the page to reflect them. It is your sass task that decides where the files will be. The documentation describes how to do this https://github.com/gruntjs/grunt-contrib-sass#compile-files-in-a-directory Your HTML file should reference the compiled css files in the public directory. – JBux Jul 06 '15 at 12:10
  • Hello again. Thanks for comments but here's you are wrong. I know that SASS plugin does says where the compiled files should go. But there's a plugin that can mount folders to another folder. Let's say that you have 2 folders in your project. 'Source' and 'Build'. Then your index files will point to the compiled css files in your build folder. But when you're debugging (AKA running a grunt task named debug) your page should automatically takes the compiled files from withint the source folder, you see what I mean? Take a look at an example Yeoman app. But this uses not the updated watch. – Complexity Jul 06 '15 at 12:18
  • I'm not even sure that that is possible. As far as I'm aware, you must compile the `.scss` files to `.css` for them to be included in the html. Sorry I couldn't help, maybe someone else will know. You could use https://github.com/yeoman/grunt-usemin but there's still a temporary folder being created. – JBux Jul 06 '15 at 12:32
  • A temporary folder is fine. But I need a grunt task, that based on the task, will load css files from a different location. Do you understand what I mean? – Complexity Jul 06 '15 at 12:45
  • I honestly don't. The problem you're trying to solve isn't really clear to me. EDIT: Are you saying you want the html file to have a variable folder reference based on the output directory defined in the grunt file? – JBux Jul 06 '15 at 12:46
  • That's correct. That's exactely what I want. I when I execute a build command the path should be changed accordingly and the same goes for debugging. I'm sorry to hear that my question wasn't correct in the first place. – Complexity Jul 06 '15 at 12:55
  • Sorry I couldn't be any help. The only thing I could find - and bear in mind I've not done this before - is http://www.nitinh.com/2013/05/getting-started-with-grunt-bower/ – JBux Jul 06 '15 at 13:21
  • Thanks will have a look. I'll accept your answer because you definitely gave me some ideas. – Complexity Jul 06 '15 at 13:21
0

after some search in the deep internet, I've managed to found a solution to this particular problem.

First, let me describe again what I would like to achieve since it wasn't clear in the first place I've found in the comments on my original question.

Application
|-- Source
|   |-- Styles
|   |   |-- main.scss
|   |-- Scripts
|   |   |-- core.js
|   |-- index.html 

So, you can clearly see in my application's structure that I'm hosting the source code under the folder source, obvious, isn't it. The styles directory in that folder contains a SASS stylesheet (*.scss). I don't want to have any css file in that because I'm not writing css files, in writing sass files.

Now, I do have grunt task which compiles my sass into plain css:

sass: {
  all: {
    files: {
       '.tmp/styles/main.css' : 'source/styles/main.scss'
            }
  }
}

So, this task will take the file main.scss and compile it into a directory `.tmp/styles/main.css'

Note that this task is only executed with a specific grunt-debug task.

When I'm building on release, the css file will be placed in release/styles/main.css

Now, I'm having an index.html file which references the stylesheet:

<link rel="stylesheet" href="styles/main.css"/>

As you might guess, this won't work, because when I'm debugging, the index file is in the source folder while the styles directory only contains my SASS file.

I'm using grunt-express as the server:

    express: {
        all: {
            options: {
                port: 9000,
                hostname: "0.0.0.0",
                bases: ['source'],
                livereload: true
            }
        }
    },

Now, to make the server really load the css file, the only thing that I needed to do was changing the bases path to:

bases: ['source', '.tmp']

The grunt-express configuration then looks something like:

express: { all: { options: { port: 9000, hostname: "0.0.0.0", bases: ['source', '.tmp'], livereload: true } } },

By using this code, the grunt-express will serve files that are stored in the 'source' directory and in the '.tmp' directory.

Complexity
  • 5,682
  • 6
  • 41
  • 84