browserify 簡介javascript
編寫 CommonJS 模塊示例html
編寫 ES6 Module 模塊示例前端
總結 CommonJs 和 ES6 Modulejava
參考文檔node
概要:本篇文章的主要任務是使用 ES6 語法來編寫 CommonJs 模塊化和使用 ES6 提供的 Module 來實現模塊化,跟着下面的步驟一步一步來:github
編寫 CommonJS 模塊示例npm
編寫 ES6 Module 模塊示例json
"Browserify lets you require('modules') in the browser by bundling up all of your dependencies." - Browserify.org
上面的描述是摘自 browserify 官網;用通俗的話講就是:browserify 是一個瀏覽器端代碼模塊化工具,能夠處理模塊之間的依賴關係,讓服務器端的 CommonJS 格式的模塊能夠運行在瀏覽器端
browserify的原理:
處理代碼依賴,將模塊打包到一塊兒


打包爲單個文件存在的問題:
暫時用不到的代碼也會被打包,體積大,首次加載速度慢
只要一個模塊更新,整個文件緩存失效
注:暫時用不到的代碼指不一樣的頁面有不一樣的 JS 文件,不須要在當前頁面引用其餘頁面的代碼即爲暫時用不到的代碼
Browserify的解決方案:
entry point,入口點技術;每一個入口點打包一個文件,兩個入口點的相同依賴模塊單獨打包爲common.js
安裝 browserify
npm install --global browserify
引入 browserify
import browserify from 'browserify'
基本配置
glup.taks('browserify', function() { browserify({ //先處理依賴,入口文件 entries: ['./foo.js','./main.js'], //進行轉化 transform: [] }) .bundle() // 多個文件打包成一個文件 .pipe(source()) // browserify的輸出不能直接用作gulp輸入,因此須要source進行處理 .pipe(gulp.dest('./')); })
npm install --save-dev vinyl-source-stream vinyl-buffer gulp-sourcemaps
vinyl-source-stream
: browserify的輸出不能直接用着gulp的輸入,vinly-source-stream 主要是作一個轉化
vinyl-buffer
: 用於將vinyl流轉化爲buffered vinyl文件(gulp-sourcemaps及大部分Gulp插件都須要這種格式)
gulp-sourcemaps
: Source map就是一個信息文件,裏面儲存着位置信息。也就是說,轉換後的代碼的每個位置,所對應的轉換前的位置,便於調試
Watchify
: 加速 browserify 編譯
/ |-- dist/ |-----bundle.js |-- src/ |-----foo.js |-----main.js |--gulpfile.babel.js |--package.json
foo.js
, main.js
$ touch foo.js main.js
CommonJS 規範是爲了解決 JavaScript 的做用域問題而定義的模塊形式,能夠使每一個模塊在它自身的命名空間中執行。該規範的主要內容是,模塊必須經過 module.exports 導出對外的變量或接口,經過 require() 來導入其餘模塊的輸出到當前模塊做用域中。
// foo.js // 定義foo.js模塊,經過 module.exports 導出對外的變量或接口 let variable = 8; let sum = (a, b = 6) => (a + b); let square = (b) => { return b * b; }; module.exports.variable = variable; module.exports.sum = sum; module.exports.square = square;
// mian.js // 經過 require() 來導入 foo.js 模塊 var bar = require('./foo') console.log(bar); // Object console.log(bar.variable); // 8 console.log(bar.sum(1)); // 7 console.log(bar.square(5)); // 25
上面咱們使用 ES6
的語法寫了兩個模塊,分別是 foo.js
和 main.js
; 在 foo.js
中經過 module.exports
導出對外的變量或接口;在 main.js
中經過 require()
來導入 foo.js
模塊,那咱們就能夠在 mian.js
模塊中使用 foo.js
中的變量和接口了。這就是一個最基本的 CommonJs
示例了
browserify
經過第一小節的學習,咱們知道要在瀏覽器中運行 CommonJs
風格的模塊代碼,就須要藉助 browserify
來做爲轉換工具,下面咱們在 gulp.babel.js
中來配置 browserify
:
// set browserify task gulp.task('browserify',()=> { browserify({ entries: ['src/js/main.js','src/js/foo.js'], debug: true, // 告知Browserify在運行同時生成內聯sourcemap用於調試 }) .transform("babelify", {presets: ["es2015"]}) .bundle() .pipe(source('bundle.js')) .pipe(buffer()) // 緩存文件內容 .pipe(sourcemaps.init({loadMaps: true})) // 從 browserify 文件載入 map .pipe(sourcemaps.write('.')) // 寫入 .map 文件 .pipe(gulp.dest('dist/js')) .pipe(notify({ message: 'browserify task complete' })); })
gulp-browserify
上面的代碼主要是 CommonJs 模塊化的寫法,咱們再來看看最近火熱的 ES6 提供的 Module;讓咱們使用 ES6 Module 來改寫上面的代碼:
// foo.js // 定義foo.js模塊,經過 exports 導出對外的變量或接口 let variable = 8; let sum = (a, b = 6) => (a + b); let square = (b) => { return b * b; }; export { variable, sum, square };
// main.js // 測試一: // 經過 import 來導入 foo.js 模塊 import {variable, sum, square} from './foo'; console.log(variable); // 8 console.log(sum(1)); // 7 console.log(square(5)); // 25 // 測試二: // 直接引用整個 foo 模塊 import bar from './foo'; console.log(bar); // 輸出值是undefined,後面作解釋 // 測試三: // 經過 ES6 的語法加載整個 foo模塊 import * as bar from './foo' console.log(bar); // Object
根據 CommonJS 規範,一個單獨的文件就是一個模塊。每個模塊都是一個單獨的做用域,也就是說,在一個文件定義的變量(包括函數和類),都是私有的,對其餘文件是不可見的
經過 module.exports
對象,定義對外接口,其餘文件加載該模塊,實際上就是讀取 module.exports
變量
經過 require
命令加載模塊文件,而後返回該模塊的exports對象
經過 export
命令用於規定模塊的對外接口
經過 import
命令用於加載其餘模塊提供的功能
在ES6中使用 import
取代 require
在ES6中使用 export
取代 module.exports
ES6 在編譯時就能肯定模塊的依賴關係,以及輸入和輸出的變量,而 CommonJs 只能在運行時肯定模塊的依賴關係以及輸入和輸出的變量。
運行時加載: CommonJS 模塊就是對象;即在輸入時是先加載整個模塊,生成一個對象,而後再從這個對象上面讀取方法,這種加載稱爲「運行時加載」
編譯時加載: ES6 模塊不是對象,而是經過 export 命令顯式指定輸出的代碼,輸入時採用靜態命令的形式。即在輸入時能夠指定加載某個輸出值,而不是加載整個模塊,這種加載稱爲「編譯時加載」
注:上面提到 ES6 加載模塊時是採用指定加載某個輸出值的形式,若是你要想加載整個模塊,你能夠這麼作:import * as customName from './moduleFileName';