2
\$\begingroup\$

I am into building functional prototypes, but also for outputting CSS and JS, which means we have 2 times we build out our code, once as a demo with HTML files (we are using assemble.io) and another, where we are building out the files to be uploaded to production (an Enterprise CMS).

Most things about the build are the same, but the main difference is certain paths within the CSS need to change. I have set up a sass variable, and when building, I change it and then change it back when I'm done (I do it in place, because other tasks are moving the sass files around.)

The problem is this method just feels really wonky, and not at all extensible.

We are using a gruntfile that is mostly the same as the one provided with the yeoman webapp generator, with some of our specific tasks added for good measure.

Here are excerpts of the relevant sections of my Gruntfile:

  grunt.initConfig({
    //...

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= config.app %>',
          dest: '<%= config.dist %>',
          src: [
            '*.{ico,png,txt}',
            'images/{,*/}*.webp',
            '{,*/}*.html',
            'fonts/{,*/}*.*',
            'styles/fonts/{,*/}*.*'
          ]
        }, {
          src: 'node_modules/apache-server-configs/dist/.htaccess',
          dest: '<%= config.dist %>/.htaccess'
        }, {
          expand: true,
          dot: true,
          cwd: '<%= config.app %>/components/bootstrap-sass-official/assets/fonts/bootstrap',
          src: '*',
          dest: '<%= config.dist %>/fonts'
        }, {
          expand: true,
          dot: true,
          cwd: '<%= config.app %>/components/font-awesome/fonts/',
          src: '*',
          dest: '<%= config.dist %>/fonts'
        }]
      },
      styles: {
        expand: true,
        dot: true,
        cwd: '<%= config.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },

    // Run some tasks in parallel to speed up build process
    concurrent: {
      server: [
        'sass:server',
        'assemble'
      ],
      test: [
        'copy:styles'
      ],
      dist: [
        'sass',
        'copy:styles',
        'assemble',
        'imagemin',
        'svgmin'
      ]
    },
    replace: {
      prodSass: {
        src: ['<%= config.app %>/styles/utils/_variables.scss'],
        overwrite: true,
        replacements: [
          {
            from: '$site-root: $build-root',
            to: '$site-root: $prod-root'
          }
        ] 
      },
      prodSassRevert: {
        src: ['<%= config.app %>/styles/utils/_variables.scss'],
        overwrite: true,
        replacements: [
          {
            from: '$site-root: $prod-root',
            to: '$site-root: $build-root'
          }
        ] 
      }
    }
    //..
  });

  grunt.registerTask(
    'build', 
    'Build out the codez! takes an optional `env` parameter so we can build in different ways', 
    function(env){
      grunt.task.run(
        'clean:dist',
        'handlebars',
        'assemble',
        'wiredep'
      );

      // if 'prod' environment we need to do some variable modification 
      // before the sass is compiled (which happens in 'concurrent')
      if (env === 'prod'){
        grunt.task.run('replace:prodSass');
      }

      grunt.task.run(
        'concurrent:dist',
        'preprocess:html',
        'useminPrepare',
        'autoprefixer',
        'concat',
        'cssmin',
        'pixrem:dist',
        'uglify',
        'copy:dist',
        'modernizr',
        'usemin'
      );

      if (env === 'prod'){
        grunt.task.run('replace:prodSassRevert');
      }
    }
  );
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

Here is a trick I used a few weeks back when I ran into the same issue as you are (were?) having. Although I've used grunt-contrib-sass I think the trick should translate quite well to grunt-sass. What I basically did was to define two environment files with the same name and placed them in different folders. Next I configured Compass through Grunt to use different include paths (pointing to the two different folders) based on the build target. My scss file setup was pretty much as follows :

sass/
  dev/
    _env.scss
  dist/
    _env.scss

  component/
    _stuff.scss

  main.scss

and my main.scss file opened with the line

@import "env";

// use env variables from here on

Next, in my case, I defined two compass tasks in my Gruntfile which, based on environment, would either add sass/dev or sass/dist to the include path, e.g. :

compass : {
  options : {
    sassDir : '<%= project.app %>/sass',
    // ... and other options
  },
  dev : {
    options : {
      importPath : ['<%=project.app%>/sass/dev']
    }
  },
  dist : {
    options : {
      importPath : ['<%=project.app%>/sass/dist']
    }
  }
}

Now by executing either compass:dist or compass:dev tasks the include paths differ which in turn result in the inclusion of the desired set of environment variables. For grunt-sass the same thing should be possible by setting the includePaths property (rather than importPath in grunt-contrib-sass). Hope that helps!

\$\endgroup\$
1
  • 3
    \$\begingroup\$ In my assessment, this answer is a decent answer for the question, but the question is the issue, the question is about how to build/deploy code, rather than the code itself. The question is/was not really looking for a code review, and, as a result, did not get one. \$\endgroup\$
    – rolfl
    Jun 29, 2015 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.