es6 模塊的導出、導入和工程自動化

演變過程

  • 經過script標籤引入文件<無模塊化>

缺點:容易形成代碼污染,命名衝突等問題前端

  • 服務端的node中引入了CommonJS的模塊化規範

特色:被加載的時候運行,輸出的是值的淺拷貝,具備緩存,下載加載時從內存中讀取vue

其導入採用同步加載方式,而文件存於服務器中,所以適用於服務端使用。而瀏覽器端須要從服務端請求,所以不瀏覽器端請求不適用這種方式node

經過module.exports對外暴露接口,使用require('文件路徑')引入模塊webpack

前端webpack打包時對CommonJS是支持的web

  • 異步加載AMD規範

特色:須要加載所有依賴以後再執行,適用於瀏覽器端的異步加載規範api

定義了兩個API: 導入:require([module],callback) ; 定義模塊:define(id,[depends],callback)數組

AMD規範的實現是require.jspromise

  • 按需加載CMD規範

特色:使用rquire,進行按需加載,CMD規範的實現sea.js瀏覽器

define(function(require, exports, module) {
      var $ = require('文件路徑');
      exports.doSomething = ...
      module.exports = ...
    })
    //AMD和CMD的比較
    // AMD
    define(['./a', './b'], function(a, b) {  // 依賴必須一開始就寫好 
       a.doSomething()    
       // 此處略去 100 行 
       b.doSomething()    
       ...
    });
    // CMD
    define(function(require, exports, module) {
       var a = require('./a')   
       a.doSomething()   
       // 此處略去 100 行 
       var b = require('./b') 
       // 依賴能夠就近書寫 
       b.doSomething()
       // ... 
    });
複製代碼
  • ES6模塊化

特色:異步加載,加載的爲值的引用,重複導入文件不會存在覆蓋,編譯時運行緩存

靜態導入模塊:import mydefault, * as mydefault, {foo,bar} from '模塊路徑' 返回函數或對象

動態導入模塊:import(路徑)返回promise

//導入js文件
    import('/modules/myModules.js')
    .then(module=>{
        //操做
    })
    //導入vue文件
    myComponent = ()=>import('/modules/myModules.vue')
    
    //均可以使用require來實現一樣的操做,但屬於同步加載,須要提早加載完成後運行
    require('/modules/myModules.js').default
    require('/modules/myModules.vue').default
    
複製代碼

工程自動化:require.context

是webpack的api,主要用來實現自動讀取模塊,實現工程自動化

require.context(directory,useSubdirectories,regExp)

參數以下
  • directory:String類型,掃描的文件夾的根路徑
  • useSubdirectories: Boolean類型,是否遍歷文件的子目錄
  • regExp:RegExp正則對象,匹配文件的正則
返回值是個函數,函數的屬性以下
  • resolve:Function類型,接收一個參數爲文件相對路徑;返回模塊
  • keys: Function類型,返回匹配成功的模塊名稱的數組
  • id:String類型,應用於module.hot.accept
使用示例

讀取correspondingFields文件夾下,全部子文件夾下,存在modules下的全部js文件,如圖:

代碼讀取以下:

// 導出全部js
const modulesFiles = require.context('./', true, /.*\/modules\/\w+\.js$/)
// console.log('modulesFiles', modulesFiles.keys())

// 導出table列
const tableColumnsModuleFiles = require.context('./', true, /.*\/tableColumns\/modules\/\w+\.js$/)
// console.log('modulesFiles', modulesFiles.keys())

// 導出table列
const detailModuleFiles = require.context('./', true, /.*\/detail\/modules\/\w+\.js$/)
// console.log('modulesFiles', modulesFiles.keys())

/** * 文件夾下的模塊 * @param {*} ModuleFiles :讀取的上下文 * 返回值是對象 * 例:{ * detail:{ * contract:模塊 * }, * tableColumns:{ * contract:模塊 * } * } */
function getModules(ModuleFiles) {
  const modules = ModuleFiles.keys().reduce((modules, modulePath) => {
    // console.log('modulePath', modulePath)
    const suffix = '\\.js$'
    const regExp = new RegExp(`^.*\\/(\\w+)\\/modules\\/(\\w+)${suffix}`)
    const result = regExp.exec(modulePath)// 匹配結果
    if (result.length >= 3) {
      const type = result[1]
      const moduleName = result[2]
      modules[type] ? Object.assign(modules[type], { [moduleName]: ModuleFiles(modulePath).default }) : modules[type] = { [moduleName]: ModuleFiles(modulePath).default }
    }
    return modules
  }, {})
  return modules
}

export const DetailModules = getModules(detailModuleFiles)
export const TableColumnsModules = getModules(tableColumnsModuleFiles)
export default getModules(modulesFiles)

複製代碼
相關文章
相關標籤/搜索