如何在其他任务之前运行Gulp任务

时间:2014-08-20 13:00:26

标签: gulp

我是Gulp构建系统的新手,到目前为止,我发现定义任务(与替代方案相比)非常简洁直观,直到我不得不开始订购任务......

我想,这是一个非常常见的用例:我尝试在运行其他构建任务之前运行一个干净的任务。

我首先天真地写了这样的东西(coffeescript):

gulp.task 'dist', ['clean:dist', 'copy-libs:dist', 'minify']

问题当然是所有相关任务都是并行运行的,并且无法保证后续任务在清理任务之前不会运行。

那么,解决方案是什么?

1 个答案:

答案 0 :(得分:2)

好的,回答我自己的问题:

社区中的某些人建议使用依赖系统。 因此,我必须重新编写我的所有任务,并使它们依赖于干净的任务。

但我希望有时在没有运行清理任务的情况下运行这些任务。 这意味着我必须复制这些任务(一个版本和一个没有依赖关系)。

坦率地说,对我而言,这违背了使用Gulp的目的,因为我使用Gulp主要是因为它的简洁性,可读性(特别是用CoffeeScript编写时)和代码而不是配置'方法

所以,我现在的解决方案是使用run-sequence插件和merge-stream来实现这一点,同时保留一个可读且紧凑的构建文件(见下文)。

gulp.task 'dist', -> runSequence 'clean:dist', ['copy-libs:dist', 'minify']

看起来Gulp 4将使用' runSeries'和' runParallel'功能

请注意,我使用 merge-stream 插件,因为我的一个任务(copy-libs)处理多个流。而且,这里有一个非常好的建议,你的所有任务都应该返回一个流,只有一个流(因此合并流)。


这是我的完整构建文件:

# Load all required libraries
gulp = require 'gulp'
del = require 'del'
coffee = require 'gulp-coffee'
less = require 'gulp-less'
changed = require 'gulp-changed'
uglify = require 'gulp-uglify'
cssmin = require 'gulp-minify-css'
htmlmin = require 'gulp-htmlmin'
size = require 'gulp-filesize'
runSequence = require 'run-sequence'
merge = require 'merge-stream'

typeIsArray = Array.isArray || ( value ) -> return {}.toString.call( value ) is '[object Array]'
bower = (value) -> # prefix the given path/array with the bower directory
    if !typeIsArray value then "bower_components/" + value else value.map (str) -> bower str

gulp.task 'clean:development', (cb) ->
    del [
        "src/js/*.js", "!src/js/data.js" # in development, delete all .js files except data.js
        "src/css/main.css", "src/css/sidebar.css", "src/css/bootstrap*"
        "src/fonts/"
        "src/js/libs/"
    ], cb

gulp.task 'clean:dist', (cb) ->
    del "build/", cb

gulp.task 'coffee', ->
    gulp.src "src/js/main.coffee"
        .pipe coffee()
        .pipe gulp.dest "src/js"

gulp.task 'less', ->
    gulp.src "src/css/main.less"
        .pipe less()
        .pipe gulp.dest "src/css"

gulp.task 'copy-libs:development', -> # install and copy only the required bower files to the right directory (under src/)
    merge( # here we have to merge the streams otherwise only the latest one will be returned
        gulp.src bower [
                "jquery/dist/*",
                "angular/angular*.{js,js.map}"
                "angular-sanitize/*.{js,js.map}"
                "angular-animate/*.{js,js.map}"
                "bootstrap/dist/js/*"]
            .pipe changed "src/js/libs"
            .pipe gulp.dest "src/js/libs"
        gulp.src bower "bootstrap/dist/fonts/*"
            .pipe changed "src/fonts"
            .pipe gulp.dest "src/fonts"
        gulp.src bower ["bootstrap/dist/css/bootstrap.css*", "bootstrap/dist/css/bootstrap.min.css"]
            .pipe changed "src/css"
            .pipe gulp.dest "src/css"
    )

gulp.task 'watch', ->
    gulp.watch "src/js/main.coffee", ['coffee']
    gulp.watch "src/css/main.less", ['less']

gulp.task 'minify', ['coffee', 'less'], ->
    merge(
        gulp.src "src/js/main.js"
            .pipe uglify()
            .pipe gulp.dest "build/js"
        gulp.src "src/css/main.css"
            .pipe cssmin()
            .pipe gulp.dest "build/css"
        gulp.src "src/index.html"
            .pipe htmlmin {collapseWhitespace: true, removeComments: true}
            .pipe gulp.dest "build"
    )

gulp.task 'copy-libs:dist', ['copy-libs:development'], ->
    # the 'base' option here is used to keep the structure under the src/ directory (otherwise it is flattened)
    gulp.src ["js/data.js", "js/libs/*", "fonts/*", "css/bootstrap.min.css"], {cwd: "src", base: "src"}
        .pipe size()
        .pipe gulp.dest "build"


# Main tasks
gulp.task 'default', -> console.log 'no-op default task'
gulp.task 'clean', ['clean:development', 'clean:dist']
gulp.task 'development', -> runSequence 'clean:development', ['copy-libs:development', 'coffee', 'less', 'watch']
gulp.task 'dist', -> runSequence 'clean:dist', ['copy-libs:dist', 'minify']