目標:了解一下前端模塊化的知識
內容:用於記錄一些心得。(前端模塊化)
正文:
一、JavaScript原始功能
在網頁開發的早期,JS作為一種腳本語言,做一些簡單的表單驗證或者動畫實現,那個時候代碼還是很少的,一般是直接寫在<script>標簽中。
二、存在問題
隨着AJAX異步請求的出現,慢慢形成了前后端的分離。客戶端需要完成的事情越來越多,代碼量也是與日俱增。為了應對代碼量的劇增,我們通常會將代碼組織在多個JS文件中,進行維護。但是這種維護方式,依然不能避免一些災難性的問題。比如說全局變量同名問題(因為一個大的項目是多人完成的,需要導入每個人寫的代碼匯總);另外,這種代碼的編寫方式對JS文件的依賴順序幾乎是強制性的,也無法避免全局變量同名問題。
三、模塊化雛形(早期的模塊化)
之前解決上述的問題的方法有匿名函數,類似於(function () {} )()的格式。但是代碼的復用性又不得不降低了,甚至不可復用。所以在ES5中可以通過把需要可復用的代碼添加到一個對象,通過匿名函數的返回這個對象(使用模塊作為出口,暴露到外面的屬性和方法,不需要暴露的直接定義),並用某個變量去接收這個返回對象,這個變量就是模塊。然后在別的文件導入這個模塊,就可以使用這個模塊的代碼了。
幸運的是,前端模塊化開發以及有了很多既有的規范,以及對應的實現方案。
常見的模塊化規范有:CommonJS(通過node實現),AMD,CMD,也有ES6的Modules。(tips:模塊化包括導出和導入)
四、CommonJS(webpack也使用這個,因為也是依賴node環境)
CommonJS的導出:(注意是要在node環境下,要用node底層解析module.exports)
1 module.exports = { 2 flag: ture, 3 test(a, b) { 4 return a + b 5 }, 6 demo(a, b) { 7 return a - b 8 } 9 }
CommonJS的導入:(moduleA是剛剛導出文件的文件名(可加路徑))
1 //CommonJS模塊 2 let {test, demo, flag} = require('moduleA') 3 //等同於 4 let _mA = require('moduleA'); 5 let test = _mA.test; 6 let demo = _mA.demo; 7 let flag = _mA.flag;
五、ES6的Modules
export(導出)/import(導入)
當我們在引入別人JS文件時,用<script src="xxx.js'>,當我們在script標簽下使用type=‘module’時,這意味着我們是按照模塊化使用這個xxx.js文件。相當於這個文件是在一個模塊內,有着自己獨立的作用域。
export(導出了模塊對外提供的接口)。可以導出變量,函數,類(ES6提供了class類)。或者是導出一個默認的東西,讓導入者自己來命名(export default),這樣的好處就是導入者可以不必知道要導入的模塊代碼的名字。
1 //info.js 2 export let name = 'coco' 3 export let age = 18 4 //另一種寫法 5 // let name = 'coco' 6 // let age = 18 7 // export {name, age} 8 export function logInfo (value){ 9 return console.log(value) 10 } 11 export class Person { 12 constructor(name, age){ 13 this.name = name; 14 this.age = age; 15 } 16 run(){ 17 console.log('I am a class') 18 } 19 } 20 // export logInfo, Person} 21 //默認導出只能有一個 22 const address = 'abc'; 23 export default address
import(導入,加載對應模塊)。導入之后就可以對應使用了。通過*可以導入模塊中所有的export變量,但是通常情況下我們需要個*用as起一個別名,方便后續使用。
1 //func.js 2 import {name, age} from 'info.js' 3 import{logInfo, Person} from 'info.js' 4 //默認導出adress並命名為add 5 import add from 'info.js'
6 //import * as info from './info'
7 //console.log(info.name, info.age)