標籤:
原文地址:Setting up an ES6 Project Using Babel and Browserify
JavaScript的發展日新月異,ES6很快就要接管JS了。很多著名的架構像AngularJS 2、React Native已經開始支援ES6了。我們是時候準備擁抱變化了,所以我們應該開始在幾乎所有的瀏覽器支援之前使用ES6碼代碼了。
本文將要介紹如何使用Babel和Browerify來建立項目並且編寫能夠運行在老版本瀏覽器上的現代代碼。Babel將ES6代碼編譯為大多數瀏覽器(包括IE9)支援的ES5代碼。Browserify可以讓我們遵循CommonJS規範書寫代碼,然後經過封裝在瀏覽器中使用。
建立package.json檔案
首先,我們看一下我們將要建立的Demo的檔案結構。
項目的根目錄下,有兩個檔案:Gruntfile.js和package.json,兩個檔案夾dist和modules。modules檔案夾下包括用ES6編寫的所有模組,dist檔案夾下包含編譯和打包後的ES5檔案。我沒有在檔案夾裡包含.gitignore檔案是因為它只是一個工具檔案沒什麼亂用。
現在我們來建立package.json檔案,一個標準的package.json包含許多欄位,比如description、version、author還有其他神馬的,但在這個項目我們唯寫一些比較重要的。
package.json內容如下:
{ "name": "browserify-babel-demo", "main": "dist/module.js", "devDependencies": { "grunt": "^0.4.5", "babelify": "^6.1.0", "grunt-browserify": "^3.8.0", "grunt-contrib-watch": "^0.6.1" }}
從上述檔案可以看到,項目中使用到的有:
- Grunt JavaScript任務構建工具
- grunt-browserify Grunt browserify任務
- babelify Browserify的babel轉換器
- grunt-contrib-watch 監聽JavaScript的每次改變然後選擇性的執行任務,在我們的例子中,檔案每次改變都要執行Browserify任務。
devDependencies中的模組只在開發環境中使用,而不是在代碼運行過程中。模組的版本號碼可以根據使用設定。
現在在項目根目錄下運行 npm install來安裝package.json中聲明的相依模組,如果你還不熟悉npm,建議你讀一下這篇文章。
(譯者註:要想使用最新版本的相依模組,可以不事先在package.json檔案寫好,執行如下命令安裝:npm install grunt --save-dev,安裝完成後相依模組會自動出現在package.json中)。
建立Gruntfile.js
本文假設你已經瞭解Grunt,並且知道Gruntfile.js是如何和Grunt工作的。如果不熟悉,我建議在閱讀下面的內容前,看一下這篇文章。
使用ES6書寫的JavaScript檔案可以使用js或者es6作為副檔名,這裡為了簡潔,統一使用js作為副檔名,Gruntfile.js代碼如下:
module.exports = function (grunt) { grunt.initConfig({ browserify: { dist: { options: { transform: [ ["babelify", { loose: "all" }] ] }, files: { // if the source file has an extension of es6 then // we change the name of the source file accordingly. // The result file‘s extension is always .js "./dist/module.js": ["./modules/index.js"] } } }, watch: { scripts: { files: ["./modules/*.js"], tasks: ["browserify"] } } }); grunt.loadNpmTasks("grunt-browserify"); grunt.loadNpmTasks("grunt-contrib-watch"); grunt.registerTask("default", ["watch"]); grunt.registerTask("build", ["browserify"]);};
我們定義了兩個Grunt任務:
- grunt default/grunt:當我們在項目根目錄運行這個命令,這個任務會監聽modules檔案夾下所有JS檔案的變化。當檢測到任何變化時,Grunt都會執行Browserify任務。任務終斷之前,watch任務會一直運行。Ctrl+C來終斷任務。
- grunt build:Browserify任務運行一次後停止。
Browserify任務每一次執行都會將modules檔案下的所有ES6代碼打包成一個JavaScript檔案,然後通過Babelify將ES6代碼轉換成ES5代碼。
從上面的代碼看到,我們給babelify的設定是loose:"all",是因為我們希望轉換出的ES5代碼和我們寫的ES6代碼能夠足夠的接近,而不是嚴格的按照規範,這樣,對ES6初學者來說更容易調試。Babel提供的所有選項見這裡。
寫點ES6代碼
這個demo只使用一點ES6的特性,比如import和export。如果你想深入學習ES6,可以看看SitePoint上的這些文章。你將會學習到ES6提供的那些新奇而且令人激動的特性。
在我們的demo裡我們將在modules檔案夾下建立兩個檔案,index.js和import.js,前面一個檔案是項目的主檔案,後一個檔案作為一個模組提供了所有的函數和變數。也就是說,index.js會從import.js中匯入(import)所有的函數和變數。
import.js檔案如下:
var sum = (a, b = 6) => (a + b);var square = (b) => { return b * b;};var variable = 8;class MyClass { constructor(credentials) { this.name = credentials.name; this.enrollmentNo = credentials.enrollmentNo } getName() { return this.name; }}export { sum, square, variable, MyClass };
import.js作為一個模組,對外提供了一個變數、一個類和函數運算式(箭頭函數書寫)。模組中定義的函數和變數對外是不可見的,除非顯式的匯出(export)他們。你可以使用export關鍵字。在import.js的最後一行,我們到處了sum、square、variable、MyClass。
在index.js檔案中,我們使用import關鍵字匯入import.js中的所有函數和變數,index.js成為了項目的主檔案。從下面的index.js檔案內容可以看到,我們是怎麼使用匯入的square函數和MyClass的。我們可以從任意多的檔案中匯入任何變數和方法。
import {sum, square, variable, MyClass} from ‘./import‘;// 25console.log(square(5));var cred = { name: ‘Ritesh Kumar‘, enrollmentNo: 11115078}var x = new MyClass(cred);//Ritesh Kumarconsole.log(x.getName());
如果我們想匯入一個es6副檔名的模組,那麼我們必須在import中寫完整的檔案名稱。看下面的例子:
// if file extension of the importing file is .js// both below mentioned methods workimport { sum, square, variable, MyClass } from ‘./import‘;import { sum, square, variable, MyClass } from ‘./import.js‘//if file extension of the importing file is .es6// its mandatory to add the extensionimport { sum, square, variable, MyClass } from ‘./import.es6‘;
假如我們正在使用Browserify,我們依然可以使用require()方法匯入符合CommonJS規範的模組。例如:我們想使用匯入jQuery作為一個模組,可以這樣:
var $ = require(‘path/to/jquery‘);$(window).click(function(){ //do something});
Babel可以轉換ES6到ES5,但不能打包模組。Browserify登場!
ES6的import、export結合require方法使得我們可以自由的用模組來組織我們的用戶端代碼,同時又可以使用新版本的JavaScript書寫我們的代碼。
只要我們在終端運行grunt命令就會:
- Browserify把所有的檔案打包成一個JavaScript檔案
- 打包後的檔案通過Babelify轉換成為ES5代碼
- 產生一個名為module.js的檔案,可以運行在所有的現在瀏覽器上,包括IE9
那麼module.js長啥樣呢,看:
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module ‘"+o+"‘");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){"use strict";exports.__esModule = true;function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var sum = function sum(a) { var b = arguments[1] === undefined ? 6 : arguments[1]; return a + b;};var square = function square(b) { "use strict"; return b * b;};var variable = 8;var MyClass = (function () { function MyClass(credentials) { _classCallCheck(this, MyClass); this.name = credentials.name; this.enrollmentNo = credentials.enrollmentNo; } MyClass.prototype.getName = function getName() { return this.name; }; return MyClass;})();exports.sum = sum;exports.square = square;exports.variable = variable;exports.MyClass = MyClass;},{}],2:[function(require,module,exports){‘use strict‘;var _import = require(‘./import‘);console.log((0, _import.square)(5)); //25var cred = { name: ‘Ritesh Kumar‘, enrollmentNo: 11115078};var x = new _import.MyClass(cred);console.log(x.getName());},{"./import":1}]},{},[2]);
這個檔案可以和其他普通的檔案一樣用在你的Web頁面裡,如果你願意,你也可以使用其他的Grunt任務,比如grunt-uglify、grunt-rev或者其他的任務,對module.js進行操作,操作完成後,你就可以在html頁面中使用了。
<!-- Usage of the final bundled file in html --><script src="path/to/module.js"></script>
結論
本文介紹了如何使用JavaScript的新特性來建立項目,此外,我還介紹了如何使用grunt-browserify和babelify來配置Grunt任務,我們建立了一個樣本項目來展示他們如何工作,ES6代碼如何轉換為ES5代碼。
我希望你喜歡這篇文章,並且期待著你的評論。你也可以來這裡把玩一下這個樣本項目。
[譯]使用Babel和Broserify建立你的ES6項目