JavaScript 模組化方式的概念
每個文件就是一個模塊,有自己的作用域。在一個文件裡面定義的變數、function、類別,都是私有的。
目前 webpack 是使用 node.js 的環境上,需要透過 node.js 的方法來模組化 JS,node.js 是遵照 CommonJS 的模塊規範來處理模組化,像是變數、函式、class … 等方式,以 require() 方式引入使用。
以下有使用 node.js 模組化
- require('path'); 來說,就是將 path 方法功能引入使用。
- require('extract-text-webpack-plugin') 是將插件 extract-text-webpack-plugin 由 node_modules 中的模塊引入取用裡面的功能。
require() 就是由 node_modules 資料夾下的內容取出使用,將 JS 先包裝成一次到要使用時在引入使用。
JS 模組化方法一 (node.js 模組化方式):module.export = <模塊> (輸出) / var <名稱> = require(‘<模塊檔名>‘) (引入)
module.export = 模組輸出的概念
module.exports = 指的是將後面整段的程式碼 (物件、函式、或是設定等…) 傳由 node.js 或是 webpack 後讀取與使用裡面的內容。
以 webpack 的 webpack.config.js 設定檔中的 module.exports = {} 的設定使用概念一樣,傳由 node.js 或是 webpack 後讀取與編譯。
在專案資料夾的 src/js/ 資料夾下,再新增一支檔案命名為 Obj.js 檔,裡面的內容撰寫如下。
1 2 3 | module.exports = { name: "jimmy" } |
require() 引入指定路徑 module.exports 的模組檔來使用
require() 引入模組檔使用方式
使用注入點 index.js 使用 require() 接收 Obj.js 裡的 module.exports,在注入點 index.js 裡多加入撰寫的內容如下。
1 2 | var Obj = require('./Obj.js'); console.log(Obj); // 印出 Obj.js 裡的 { name: "jimmy" } |
以上內容處理後,使用 npm run dev 指令,透過 webpack 開啟 webpack-dev-server 查看結果。
下面所執行後所印出來的 {} 就是由 require() 所引入 module.expofts 的內容。
module.exports 模組內容除了物件也可以是函式,透過 require() 賦予的變數後方加 () 執行模組內的函式
module.exports = 的部份不只可以是個 {} 物件,也可以是一段函式。
1 2 3 | module.exports = function () { console.log('module'); } |
再使用 npm run dev 指令查看,結果會是一個函式。
module.exports = 的函式透過 require() 引入後,要執行直接在賦值的變數後面帶上 () 就可執行所匯入的函式。
1 2 3 | var Obj = require('./Obj.js'); console.log(Obj); // 印出 Obj.js 裡的 fn () {} Obj(); // 執行匯入模組中的函式 |
存檔後可以看到模組引入後所被執行的結果,直接印出 module 的字串。
module.exports = 之後所指定的模組內容匯出被引入使用是什麼就是什麼 (時是物件就是物件,而是函式就會是函式)
最後這裡可以了解透過 module.exports = 之後所指定的模組內容,如果是 {} 匯出後就是物件,而如果匯出是個 function() {} 對就是個個函式。
在模組化處理時,會把函式透過 module.exports = 拆解。
module.exports 模組化的函式,透過 require() 賦予的變數執行函式傳入字串參數,由模組化的函式執行產生結果
1 2 3 | module.exports = function (str) { console.log(srt); } |
1 2 | var Obj = require('./Obj.js'); Obj('jimmy'); // 執行匯入模組中的函式,將字串傳入模組化的函式中執行 |
執行結果,傳參數進入模組化的函式中,由函式執行出結果。
JS 模組化方法二 (JS ES6 模組化方式):export default 模塊 (輸出) / Import 名稱 from “<模組擋名>” (引入)
早期在 JavaScript ES6 模組還沒出來前,是使用以 CommonJS 模塊規範的 module.exports 方式使用。
更多細節可了解 huli – webpack 新手教學之淺談模組化與 snowpack (透過模組化概念了解 Node.js 如果使用 module.exports 與 require() 匯出匯入模組) 一文。
ES6 export default 模組化輸出方式與觀念
export default 一樣同 node.js 的 module.exports = 觀念一樣,是用來將模組的模塊輸出給 import 引入使用。
接著在專案路徑 src/js/ 資料夾下,新增 item.js 檔案,裡面用來撰寫 export default 輸出的內容,而一樣使用注入點 src/js/index.js 中透過 import 方式將模組引入使用。
import 引用後,不賦予變數直接使用
export default 是 ES6 的模組化輸出的方式,透過 import 的方式把外部的模塊匯入使用。
1 | export default console.log('ES6 export') |
在注人點 index.js 中加入引入模組檔,不賦予於其他變數上,可以直接將模塊內容引入直接執行。
1 | import './item.js'; // 執行結果印出 ES6 export |
import 引用後,賦予變數後使用
將輸出的模塊修改成物件資料,而注入點 index.js 引入賦予一個變數中來使用模塊檔中的物件。
1 2 3 | export default { name: 'Jimmy' } |
1 2 | import item from './item.js'; console.log('item.name: ', item.name); // 執行結果印出 item.name: Jimmy |
src/js/index.js 檔透過 import item from './item.js'; 將模塊引入後,使用 console.log(item) 會得到一個物件。
node.js 模組化方式與 JS ES6 模組化方式撰寫時注意項目
不可將 node.js 模組化方式 (module.exports = / require()) 與 JS ES6 模組化方式 (exrpot / import default) 共用
node.js 模組化方式與 JS ES6 模組化方式二者是不同的規範所產生出來的語法,共用上基本是可以但還是盡可能避免。
在撰寫 JS 程式時盡可能遵照一種規範來開發,才不會發生無法預期的錯誤。
webpack.config.js 不能使用 JS ES6 語法撰寫
webpack.config.js 是照 node.js 的模組化方式,本身不支援 JS ES6 寫法。
以 require() 的撰寫方式也照 node.js 的 require() 方式來寫。
自定 JS 模組推薦 JS ES6 (exrpot / import default) 模組化方式撰寫
但在撰寫自定 JS 模組時也比較推薦使用 JS ES6 (exrpot / import default) 模組化撰寫方式來寫模組。
babel 插件影響模組化開發撰寫方式,不降轉只能使用 require() 使用 ES5 方法來撰寫模組化
require 與 import
require => 是在 es6 出現前的模組化開發方式
import => 是 es6 出現後的模組化開發方式
如果在 webpack 或 webpack.config.js 檔沒有設定 babel 處理 JS 降轉,是無法使用 ES6 模組化的 import 方式來撰寫,只能使用 ES5 的 require() 的方法來撰寫模組化。