Grunt - Queueing a task to run after a previous task completes

时间:2016-02-12 20:26:54

标签: javascript css gruntjs minify task-queue

I looked at the official Grunt documentation for creating tasks here

http://gruntjs.com/creating-tasks

I have two tasks that I want to do, but the second one cannot run until after the first one completes. That's because the second task takes the output from the first task and uses it to create new output.

To break it down

My project involves Bootstrap, so it has a lot of unused code. My first objective is to remove the unused code with var sampleData = [{ "approvable": true, "id": 4938, "order_number": "3948948392893", "order_template": "AJHSFJKHAS-SDJAS", "size": "45mb", "size_sort": 4500, "ad_type": "testadtype", "production_status": "yep!" } ]; var makeCampaignApproveModal = function () { var $approveParams; var $approveComments = $('#approveComments'); var $approveCampaignForm = $('#approveCampaignForm'); var $campaignApprove = $('#campaignApprove'); var $approveCampaignHeader = $campaignApprove.children('h3'); var $ratingStars = $('#ratingStars'); var $ratingStar = $('.ratingStar'); var $ratingApproveCampaign = $('#ratingApproveCampaign'); var $ratingCancelCampaign = $('#ratingCancelCampaign'); var init = function () { makeCampaignBulkOrders(sampleData); //bindings $ratingStar.mouseover(function (e) { var $this = $(this); $this.prevAll().addClass('active'); $this.nextAll().addClass('inactive'); }); $ratingStar.mouseout(function (e) { var $this = $(this); $this.prevAll().removeClass('active'); $this.nextAll().removeClass('inactive'); }); $ratingStar.on("click", function (e) { e.preventDefault(); var $this = $(this); //style prevs $this.addClass('selected'); $this.prevAll().addClass('selected'); $this.nextAll().removeClass('selected'); $ratingStars.data('rating', $this.attr('rel')); }); $ratingApproveCampaign.on("click", function (e) { e.preventDefault(); var approveHandler = Portal.Details.synchronousRatingHandler; utils.makeProxyCall((actionQueryPath + '/proof/approve'), approveHandler, Portal.Details.proofReturnE); callInProgress(); return false; }); $ratingCancelCampaign.on("click", function (e) { e.preventDefault(); $campaignApprove.modality('close'); }); $campaignApprove.addClass('initted'); }; //init if (!$campaignApprove.hasClass('initted')) { init(); } aep.utils.setupForm($approveCampaignForm, true, false); $ratingStars.data(); $ratingApproveCampaign.text($l(2019)); $approveCampaignHeader.html($l(2018) + '<span class="actionModalObjectNumber"></span>'); updateModalHeader($campaignApprove); var curRating = actionDetails['rating']; $ratingStar.each(function () { var $this = $(this); if ($this.attr('rel') <= curRating) { $this.addClass('selected'); } else { $this.removeClass('selected'); } }); $ratingStars.data('rating', curRating); $campaignApprove.modality(modalConfig); }; var makeCampaignBulkOrders = function (coData) { var $campaignBulkOrders = $('#campaignBulkOrders'); var $campaignBulkOrdersTable = $('#bulk-ords-table'); var DTConfig = { 'bDestroy': true, 'bAutoWidth': true, 'iDisplayLength': -1, 'bPaginate': false, 'sScrollY': '200px', 'bScrollCollapse': true, 'oLanguage': { 'sSearch': $l(1024) } }; var coData = sampleData || []; var coMap = getTableMapBulkOrders(); var cDTConfig = DTConfig; cDTConfig['aaData'] = coData; cDTConfig['aaColumns'] = coMap; cDTConfig['aaSorting'] = [[1, 'desc']]; cDTConfig['sScrollY'] = ''; cDTConfig['bScrollCollapse'] = false; $campaignBulkOrders.find('.tableLoading').hide(); $campaignBulkOrdersTable.dataTable(cDTConfig).fnDraw(); cDTConfig['aaSorting'] = []; }; var getTableMapBulkOrders = function () { return [{ oid: 'approvable', 'sTitle': '', 'mDataProp': function (source, type, val) { if (type == "display") { return '<input type="checkbox" class="campaign-order-approval" rel="' + source.id + '" />'; } return source.id; }, 'sClass': 'checkbox' }, { oid: 'order_number', 'sClass': 'order_number', 'mDataProp': function (source, type, val) { var ordNumber = '<a class="detailsLink" href="/portal/details/#orders/' + source.id + '">' + source.order_number + '</a><a href="" title="' + $l(2092) + '" class="orderActionsLink" rel="' + source.id + '"></a>'; if (type == 'display') { return ordNumber; } return source['order_number']; }, 'sTitle': $l(2089), 'sClass': 'orderNumber' }, { oid: 'order_template', 'mDataProp': 'order_template', 'sTitle': $l(2048), 'sClass': 'order_template' }, { oid: 'fileSize', 'mDataProp': function (source, type, val) { if (type == "sort") { return source['size_sort']; } return source['size']; }, 'sTitle': $l(2099), "sType": "numeric", 'sClass': 'file_size' }, { oid: 'ad_type', 'mDataProp': 'ad_type', 'sTitle': $l(2045), 'sClass': 'ad_type' }, { oid: 'production_status', 'mDataProp': 'production_status', 'sTitle': $l(2097), 'sClass': 'production_status' } ]; }; . I would then take the output from this new css file and minify it with uncss.

Here was the exact example from gruntjs

cssmin

I tried to apply this to my code here

grunt.registerTask('foo', 'My "foo" task.', function() {
  // Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order.
  grunt.task.run('bar', 'baz');
  // Or:
  grunt.task.run(['bar', 'baz']);
});

This means that when grunt.registerTask('default', 'uncss', function() { grunt.task.run('cssmin'); }); is entered, the default is to run the grunt task first, wait for it to complete, then run the uncss task. However I got this output

Running "default" task

Running "cssmin:css" (cssmin) task

1 file created. 3.38kb -> 2.27kb

Done, without errors

Here is my cssmin

initConfig

In other words, I have two stylesheets in my folder. One contains the custom styles I created, and another contains Bootstrap minified. By running uncss: { dist: { files: { 'directory/assets/stylesheets/tidy.css': ['directory/*.html', 'directory/views/*.html'] } } }, cssmin: { css: { files: { 'directory/assets/stylesheets/styles.min.css': ['directory/assets/stylesheets/styles.css'] } } } , I will get a new css file named uncss.

The cssmin task is supposed to look for this tidy.css file and minify it resulting in a new tidy.css file.

I can get this to work, but I have to manually run one task and then run another one. How can I automate this to have them run in sequence

3 个答案:

答案 0 :(得分:1)

first, best practice is to use npm package to load all tasks automatically:

struct style {

    static let withIcon = style(
    iconName = x.png,
    textColor: white
}

class iconLabel {
    createLabel() {
         label = UILabel()
          addSubview(label)
         //deal with constraints
    }
    createIcon() {
         icon = UIImageView
          addSubview(icon)
         //deal with constraints
    }
}

here are two grunt tasks:

// Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

and here is how you run one after the other

one: {
      wake up...
    },

two: {
      dress up...
    },

答案 1 :(得分:1)

You're close. When registering your alias task pass an array of tasks in the sequence you desire instead of a single task.

dependencies {
    implementation 'com.android.volley:volley:1.1.0'
}

Alternatively, the sequence can be specified via the CLI:

grunt.registerTask('default', ['uncss', 'cssmin']);

答案 2 :(得分:0)

It turns out part of the problem was I was specifying the wrong file under cssmin.

Changing my cssmin config to

listlen = 6;
nsamp = 4;
Table[Floor[Mod[# - 1, listlen^i]/listlen^(i - 1) + 1], {i, nsamp, 
     1, -1}] & /@ Range[listlen^nsamp] ==
  Tuples[Range[listlen], nsamp] 

and then registering the tasks in an array solved it

cssmin: {
    css: {
        files: {
            'directory/assets/stylesheets/styles.min.css': ['directory/assets/stylesheets/tidy.css']
            }
        }
    }

Note that the tasks must be specified in that order.