使用Grunt構建任務管理腳本(轉)

Grunt是構建Web開發的一個系統,但它建立比較困難。在這個指南中,你將學會如何配置Grunt建立一個現代的Web項目。當你完成教程中的配置以後,你的Gruntfile將具備:javascript

  • 從源目錄中向目標目錄複製文件;
  • 刪除構建文件;
  • 編譯Stylus文件和給他們添加前綴;
  • 編譯CoffeeScript
  • 壓縮CSSJavaScript文件;
  • 編譯Jade
  • 當文件修改後自動構建源文件;
  • 運行開發者服務器

Grunt具備一箇中文版本官網,若是你對Grunt感興趣,能夠點擊這裏查閱相關中文文檔。css

開始html

若是你尚未開始使用Grunt,你須要先安裝「Node.js」和「NPM」。你還須要經過在命令端中輸入命令npm install -g grunt-cli來安裝Grunt。這樣在你的系統中容許你在任何地方使用grunt命令使用你的Grunt。前端

建立一個package.json文件,並添加下面的內容:java

{
  "name": "grunt_tutorial",
  "description": "An example of how to set up Grunt for web development.",
  "author": "Landon Schropp (http://landonschropp.com)",
  "dependencies": {
    "grunt": "0.x.x",
    "grunt-autoprefixer": "0.2.x",
    "grunt-contrib-clean": "0.5.x",
    "grunt-contrib-coffee": "0.7.x",
    "grunt-contrib-connect": "0.4.x",
    "grunt-contrib-copy": "0.4.x",
    "grunt-contrib-cssmin": "0.6.x",
    "grunt-contrib-jade": "0.8.x",
    "grunt-contrib-jshint": "0.6.x",
    "grunt-contrib-stylus": "0.8.x",
    "grunt-contrib-uglify": "0.2.x",
    "grunt-contrib-watch": "0.5.x"
  },
  "engine": "node >= 0.10"
}

這個文件定義了您的項目做爲一個NPM包和您的項目所依賴須要的聲明。每一個聲明都有本身的一個版本號。例如,grunt-contrib-copy:"0.4.x"告訴NPM安裝0.4最新的版本grunt-contrib-copy包。在你的命令終端運行npm安裝你須要管理插件。node

複製git

一個好的運行腳本老是能讓源碼和文件分開。這樣分離容許你修改源文件而不會影響腳本。github

開始,你會讓Grunt從source目錄中複製文件到build目錄中。須要建立一個Gruntfile.js文件,並將下面的代碼複製到這個文件中:web

module.exports = function(grunt) {
  // 配置任務
  grunt.initConfig({
    copy: {
      build: {
        cwd: 'source',
        src: [ '**' ],
        dest: 'build',
        expand: true
      },
    },
  });
  // 加載任務
  grunt.loadNpmTasks('grunt-contrib-copy');
  // 定義任務
};

讓咱們來分解一下。在Node中,須要一個模塊,經過modules.exports函數來調取並返回值。在Gruntfile文件中經過modules.exports告訴Node定義Grunt配置,並返回一個函數。grunt.initConfig是一個方法,他接受一個參數:一個對象的屬性配置一個Grunt任務。ajax

在Grunt配置中,您已添加了一個copy任務。這個任務有一個子任務,叫build。在Grunt中,多個任務稱爲多任務。對於copy任務,你不須要此功能,但它仍然須要有至少一個子任務。

在Grunt建立子任務是文件數組格式。這種格式是Grunt提供源文件到一個任務的一個格式方法之一。cwd指向源文件的目錄都是相對的,和src指定源文件相似。**是一個通配符,用來匹配Grunt任何文件。dest是Grunt用來輸出結果任務。你將設置build目錄,告訴Grunt將內容複製到build目錄中。若是有一個source/index.html文件,這個配置將輸出build/index.html文件。最後,你設置expand參籹爲true來開啓這些選項。

grunt.loadNpmTasks("grunt-contrib-copy")告訴Grunt從grunt-contrib-copy包中加載任務。這給咱們一個copy命令,您能夠在你的命令控制檯中經過grunt copy命令實現複製功能。

Clean

如今你有一個build目錄,他是用來完成clean任務。而後你將下面的配置複製到裏面:

clean: {
  build: {
    src: [ 'build' ]
  },
},

就像copy,你設置了一個clean目標和任務配置,clean配置了一個src,設置了build,用來移除build目錄。

接下來使用grunt.loadNpmTask("grunt-contrib-clean"),加載一個clean任務,容許你在命令終端運行grunt clean命令。

grunt.loadNpmTasks('grunt-contrib-clean');

Build

若是你有一個build任務,在複製新的源文件以前須要先刪除舊的build,這並非很好,讓咱們來添加一個任務。

// 定義任務
grunt.registerTask(
  'build', 
  'Compiles all of the assets and copies the files to the build directory.', 
  [ 'clean', 'copy' ]
);

這個registerTask方法建立了一個新的任務。第一參數,build,定義了這個任務的名稱。第二個用來描述這個任務。最後一個參數是一個將要運行的任務數組,這個build任務,先運行clean任務,接着運行copy任務。

Stylus

Stylus是一種CSS預處理語言。它在CSS上加強了幾個功能,包括添加變量、嵌套和函數等功能。

stylus: {
  build: {
    options: {
      linenos: true,
      compress: false
    },
    files: [{
      expand: true,
      cwd: 'source',
      src: [ '**/*.styl' ],
      dest: 'build',
      ext: '.css'
    }]
  }
},

這個任務與其餘的任務稍有不一樣。這仍然是build的一子任務,但他包含兩個屬性:optionsfilesoptions指定了想要完成任務的行爲。咱們添加了兩個選擇項:compress決定CSS輸出是否被壓縮和linenos在Stylus源文件中選擇器添加行號。

files在格式化文件以前設置了一些數組參數。運行這個任務後,source目錄下的.styl文件擴展編譯輸出文件.css

如今stylus任務是將CSS文件輸出到build目錄,沒有任何理由將Stylus文件複製到build目錄任何地方。讓咱們修改copy配置來阻止這樣的事情發生。

copy: { build: { cwd: 'source', src: [ '**', '!**/*.styl' ], dest: 'build', expand: true },
},

在文件路徑的開始處能夠防止Grunt的匹配模式。別忘了在build任務中添加stylus

grunt.registerTask(
  'build', 
  'Compiles all of the assets and copies the files to the build directory.', 
  [ 'clean', 'copy', 'stylus' ]
);

Autoprefixer

Autoprefixer是Stylus尤物移人編譯成CSS後,給CSS3屬性添加前綴插件。他是一個強大的庫,正如NibCompass

繼續添加autoprefixer配置:

autoprefixer: { build: { expand: true, cwd: 'build', src: [ '**/*.css' ], dest: 'build' }
},

注意到模式了嗎?這個配置很是相似於其餘任務。一個明顯的差別是cwddest兩個都設置爲build。使用的autoprefixer輸出的文件和讀取的文件在同一個目錄中。

和前面的同樣,你也須要加載autoprefixer任務。

grunt.loadNpmTask('grunt-autoprefixer');

不是把全部的CSS任務添加到build中,建立一個添加樣式的新任務和將任務添加到build中。

// 配置任務
grunt.registerTask(
  'stylesheets', 
  'Compiles the stylesheets.', 
  [ 'stylus', 'autoprefixer' ]
);

grunt.registerTask(
  'build', 
  'Compiles all of the assets and copies the files to the build directory.', 
  [ 'clean', 'copy', 'stylesheets' ]
);

CSS壓縮

客戶端加載一羣龐大的CSS文件文件,會真正的減慢網站加載時間。幸運的是grunt-contrib-cssmin包能夠將CSS文件壓縮,並將多個文件合併成一個單一的文件。咱們再次開始配置。

cssmin: { build: { files: { 'build/application.css': [ 'build/**/*.css' ] }
  }
},

使用文件數組格式,這個配置使用Grunt的文件對象格式,將幾個文件指定到一個目的地。全部build目錄下的CSS文件壓縮後輸出到build/application.css

加載CSS壓縮任務包而且將stylesheets添加到任務中。

grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask(
  'stylesheets', 
  'Compiles the stylesheets.', 
  [ 'stylus', 'autoprefixer', 'cssmin' ]
);

CoffeeScript

CoffeeScript是編譯JavaScript一種奇特的語言。他有乾淨、漂亮的語法,包括類名和隱藏大量JavaScript不足的一面。

將CoffeeScript加入到項目中很是容易。首先,添加到配置中:

coffee: { build: { expand: true, cwd: 'source', src: [ '**/*.coffee' ], dest: 'build', ext: '.js' }
},

將源文件中的CoffeeScript文件,改變他們的擴展名爲.js,並將他們輸出到build目錄中。接下來,經過grunt-contrib-coffee加載任務包。

grunt.loadNpmTasks('grunt-contrib-coffee');

scripts任務加載到build任務中:

grunt.registerTask(
  'scripts', 
  'Compiles the JavaScript files.', 
  [ 'coffee' ]
);

grunt.registerTask(
  'build', 
  'Compiles all of the assets and copies the files to the build directory.', 
  [ 'clean', 'copy', 'stylesheets', 'scripts' ]
);

再次,你須要添加一個copy擴展,由於CoffeeScript文件並無複製到build目錄中。

copy: { build: { cwd: 'source', src: [ '**', '!**/*.styl', '!**/*.coffee' ], dest: 'build', expand: true },
},

Uglify

cssmin同樣,Uglify壓縮JavaScript文件,並將壓縮成一個文件。這裏是他的配置:

uglify: {
  build: {
    options: {
      mangle: false
    },
    files: {
      'build/application.js': [ 'build/**/*.js' ]
    }
  }
},

默認狀況之下,UglifyJS將使你的腳本用更短的名字來取代變量和函數名。若是你的項目代碼是自已的那仍是很方便的,若是要共享到另外一個項目中,會帶來問題。設置false將會關掉這種行爲。

cssmin任務同樣,這個任務也須要添加文件對象格式。

加載任務包,並像scripts任務將uglify添加到任務中:

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask(
  'scripts', 
  'Compiles the JavaScript files.', 
  [ 'coffee', 'uglify' ]
);

清理

當你運行grunt build,除了build/application.cssbuild/application.js以外,其餘全部的CSS和JavaScript文件都會掛在build目錄下。既然你不須要他們,能夠添加子任務刪除它們,下面的是clean配置:

clean: { build: { src: [ 'build' ] },
  stylesheets: { src: [ 'build/**/*.css', '!build/application.css' ] },
  scripts: { src: [ 'build/**/*.js', '!build/application.js' ] },
},

當你運行這個任務,哪果你沒有指定子任務,Grunt會運行這些任務。若是你運行grunt clean,將執行clean:buildclean:stylesheetsclean:scripts。若是clean不能刪除一個文件,它只是會忽略它,這個並非什麼問題。

注意build/application.cssbuild/application.js排除了stylesheetsscripts的子任務。你並不想刪除他們,這些畢竟是努力工做得來的。

更新任務時,使用適應的子任務:

// define the tasks
grunt.registerTask(
  'stylesheets', 
  'Compiles the stylesheets.', 
  [ 'stylus', 'autoprefixer', 'cssmin', 'clean:stylesheets' ]
);

grunt.registerTask(
  'scripts', 
  'Compiles the JavaScript files.', 
  [ 'coffee', 'uglify', 'clean:scripts' ]
);

grunt.registerTask(
  'build', 
  'Compiles all of the assets and copies the files to the build directory.', 
  [ 'clean:build', 'copy', 'stylesheets', 'scripts' ]
);

Jade

Jade是HTML模板語言。經過grunt-contrib-jade包將Jade添加到你的項目中:

jade: {
  compile: {
    options: {
      data: {}
    },
    files: [{
      expand: true,
      cwd: 'source',
      src: [ '**/*.jade' ],
      dest: 'build',
      ext: '.html'
    }]
  }
},

styluscoffee任務同樣,jade配置也使用了文件數組。在options內設置了data對象。當Jade文件編譯時,這個對象傳遞到每一個模板中。這很是方便,例如建立單獨的開發或動態生成內容。

和前面的同樣,你須要在copy添加擴展:

copy: { build: { cwd: 'source', src: [ '**', '!**/*.styl', '!**/*.coffee', '!**/*.jade' ], dest: 'build', expand: true },
},

別忘了在build中添加grunt-contrib-jade任務:

grunt.loadNpmTasks('grunt-contrib-jade');
grunt.registerTask(
  'build', 
  'Compiles all of the assets and copies the files to the build directory.', 
  [ 'clean:build', 'copy', 'stylesheets', 'scripts', 'jade' ]
);

Watch

你的Gruntfile如今已經很強大了,但不是很好,由於你每次都得去運行grunt build。使用grunt-contrib-watch,就不須要每次運行。讓咱們來配置一個這樣的任務,你會看到源代碼,並自動構建他們的變化。

watch: { stylesheets: { files: 'source/**/*.styl', tasks: [ 'stylesheets' ] },
  scripts: { files: 'source/**/*.coffee', tasks: [ 'scripts' ] },
  jade: { files: 'source/**/*.jade', tasks: [ 'jade' ] },
  copy: { files: [ 'source/**', '!source/**/*.styl', '!source/**/*.coffee', '!source/**/*.jade' ], tasks: [ 'copy' ] }
},

stylesheetsscriptsjade子任務能夠監測到Stylus,CoffeeScript和Jade文件變化和運行各自的任務。在copy任務中測試全部剩下文件並將其複製到build目錄下。

再次,你須要加載Grunt任務。

grunt.loadNpmTasks('grunt-contrib-watch');

開發者服務器

沒有Web服務器開發環境是一個不完整的。grunt-contrib-connect包是一個全功能的靜態文件服務器,用於你的項目中很是的完美。

connect: { server: { options: { port: 4000, base: 'build', hostname: '*' }
  }
},

你配置的主機服務器build目錄在4000端口上。默認狀況之下,在你本地主機上鍊接服務器是localhost。你能夠設置hostname*能夠從任何地方訪問服務器。

和前面的同樣,你須要給NPM任務中添加載加任務項。

grunt.loadNpmTasks('grunt-contrib-connect');

若是你在命令終端嘗試運行grunt connect,服務器運行,而後立刻中止。這是由於默認狀況下,Grunt connet任務不會一直運行下去,你須要瞭解如何修改這個問題。

默認

在全部任務之中運行單個任務,並不很完美。default任務是這樣設置:

grunt.registerTask(
  'default', 
  'Watches the project for changes, automatically builds them and runs a server.', 
  [ 'build', 'connect', 'watch' ]
);

default任務運行build建立一個初始的build,而後它開始鏈接服務器,最後它會運行watch,監測文件變化和從新構建。由於watch一直在運行,因此服務器一直在運行。在你的控制檯上運行grunt,而後到http://localhost:4000查看你的項目。

總結

在這篇教程中咱們已經討論了不少,但Grunt還有不少事情能夠作。對於一個完整的Grunt列表插件,能夠查看Grunt插件網站

擴展閱讀

譯者手語:整個翻譯依照原文線路進行,並在翻譯過程略加了我的對技術的理解。若是翻譯有不對之處,還煩請同行朋友指點。謝謝!

英文原文:http://www.sitepoint.com/writing-awesome-build-script-grunt/

中文譯文:http://www.w3cplus.com/tools/writing-awesome-build-script-grunt.html

相關文章
相關標籤/搜索