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)

复制代码
相关文章
相关标签/搜索