最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 模块化开发

    正文概述 掘金(大大大石头)   2021-02-09   400

    模块化开发

    模块化概述

    模块化开发是一种思想

    把复杂的代码按照功能的不同划分为不同的模块单独维护

    早期模块化演化进程

    1. 基于文件划分方式:
      • 原理:约定每个文件就是一个模块,按照功能划分
      • 缺点污染全局作用域,可能存在命名冲突、无法管理依赖关系,完全依赖约定
    2. 命名空间模式:
      • 原理:每个模块只暴露一个全局对象,内部成员全部挂载在全局对象上
      • 缺点:没有私有空间,模块成员仍然可以在外部访问或者修改
    3. IIFE(立即执行函数):
      • 原理:将整个模块使用函数包裹起来,把需要暴露的添加到window上,可以为模块提供私有空间,内部成员只能通过闭包的方式访问

    以上就是早起再没有工具和规范的情况下对模块化的落地方式

    模块化规范的出现

    模块化标准+模块加载器

    CommonJS规范

    • 一个文件就是一个模块
    • 每个模块有自己单独的作用域
    • 通过module.exprorts导出成员
    • 通过require函数加载模块

    以同步的方式加载模块,在node中没有问题,但在浏览器端会导致效率低下

    AMD - 异步模块定义规范

    Require.js库 - 实现了AMD规范的强大的模块加载器

    模块化开发

    define(模块名,[ 依赖项数组 ],function(依次对应依赖项导出的成员){ 通过return导出 })

    • define:声明模块
    • 参数1:模块名字
    • 参数2:依赖的模块
    • 参数3 - function(可选):可以看做创造了一个私有作用域,内部使用return导出

    模块化开发

    • require:关键字,导入模块

    缺点

    • AMD使用起来相对复杂
    • 模块划分如果过于细致,会导致模块js文件反复请求

    sea.js(淘宝) + CMD

    旨在模仿CommonJS的写法简化AMD的代码书写,但是后期被require.js兼容了

    模块化标准规范

    • node.js中遵循Common.JS的规范
    • 浏览器中遵循ES Modules规范

    ES Modules是ES2015定义的模块系统,目前是最主流的前端AMD规范,绝大多数浏览器已经原生支持

    ES modules特性

    使用方法:

    • 直接使用script添加type = module属性,就可以以ES modules标准执行js代码了

    基本特性:

    • 自动采用严格模式
    • 每个ESM模块都是单独的私有作用域,其他模块无法直接访问
    • ESM是通过CORS去请求外部js模块的,所有如果外部没有设置CORS允许就会返回跨域错误(注意cors不支持文件的方式访问,必须使用HTTP方式访问,这个问题一般遇不到,上线项目都是工作在http环境中的)
    • ESM的js标签会延迟执行(等待页面加载完成后执行)
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>ES Modules</title>
    </head>
    
    <body>
      <!-- module会自动启用严格模式 -->
      <script type="module">
        console.log(this) //undefined - 因为在module中自动启用了js严格模式,严格模式中不允许直接调用this
      </script>
    
      <!-- module内部上一个单独的 -->
      <script type="module">
        var a = 1
      </script>
      <script type="module">
        console.log(a)  //报错-a未定义,说明在这个模块里面是无法访问上一个module模块的a变量的,证明module模块内部是一个单独的作用域
      </script>
    
      <!-- module模块代码默认是延迟执行的,会在页面加载后执行 -->
      <script type="module">
        alert('我尝试阻塞下面p标签出现,如果无出现的同时p已经加载了,说明我的模块延迟执行了')  // 执行结果表明,在alert出现之前p就已经加载了
      </script>
      <p>我看看你能不能阻塞我</p>
    </body>
    
    </html>
    

    ESM导出用法

    • 导出模块:export 要导出接口
    • 导入模块:import { 导入的接口 } from js文件路径
    // 导出演示
    
    // exprot可以直接使用导出
    export var a = 1
    
    var b = 2,
      c = function () {
        console.log('fun')
      },
      d = 4,
      f = 5
    
    //也可以集中导出多个成员,更常用
    export {
      // 重命名
      // 使用as关键字对导出的成员重命名,导入使用新名字
      b as b_b,
      // 把成员的重命名改为default,这个成员就成了默认的导出成员,导入的时候就不能使用default,可以使用default as新名字创建新名字使用
      // c as default
    }
    
    // 直接使用默认导出
    export default d
    
    // 导入
    
    
    // 使用关键字import导入
    import {
      // 直接导入a
      a,
      // 如果重命名了导入时候使用新的名字
      b_b,
      // 如果重命名为default,那么default不能直接使用,需要重命名
      // default as c,
    } from './b.js'
    
     
    // 导入默认导出成员,不需要大括号,直接写新名字即可
    import d from './b.js'
    
    // 打印看一下
    console.log(a)
    console.log(b_b)
    // console.log(c)
    console.log(d)
    

    注意事项

    • export后面使用{}是固定语法,直接使用export后面导出的不是一个对象(虽然很像),是{}内部的多个值
    • 反之export default后面导出的只能是一个值,所以可以使用export default{a, b, c}的形式把多个值当作对象的成员导出
    • export导出的只是内容的引用关系,导入访问的时候还是要回到导出模块访问数据
    • 导出的成员是只读的,在导入之后不能修改

    导入用法和注意事项

    • 导入时候的from中必须写全完整路径,不能省略.js和前方的./,否则module会认为你在引入第三方模块
    • 除了相对路径,还可以使用绝对路径或者完整URL地址
    • 如果直接执行模块,那么{}内部不要写任何文字,就会执行模块且不会提取成员,或者直接写成import 路径
    • 如果想一次性提取一个js文件中的全部导出成员,使用import * as 新名字 from 路径可以全部将成员存在一个对象中,调用的时候使用对象的调用方式就可以访问成员了
    • import只能存在于顶层,不能出现在if、for等结构中
    • 如果想动态加载模块,可以使用import方法:import(路径).then(module){ console.log(module)}拿到成员
    • 如果一个模块同时导出了默认成员和具名成员,可以使用import 默认成员新名字,{a, b...} from 路径的方式同时导入

    ES Module直接导出导入的成员

    直接导出导入的模块,可以单独写一个桥梁文件index.js,把所有需要使用的模块通过这个文件统一导出

    // 使用export替换掉import集中导出模块,这样其他文件只需要导入这个文件即可
    // 如果使用default需要注意写法
    export {default as a} from './a.js' //或者 export a from './a.js'
    export {b} from './b.js'
    export {c} from './c.js'
    export {d} from './d.js'
    

    ES Modules浏览器环境Polyfill兼容性问题

    ES modules在早期浏览器或一些国产浏览器有兼容性问题

    解决方案:模块加载器

    github.com/ModuleLoade…

    原理是先把module代码读出来,然后交给babel编译成普通文件然后执行

    如果是IE可能还会报错promise未定义,还需要单独为ie设置一下,使用下面项目

    github.com/taylorhakes…

    注意:这个方法在支持ES6的浏览器中会被执行两次,所以使用script的新属性 - nomodule,给上面方法引入的js文件添加该属性,就只会在不支持ES6的浏览器上生效,支持ES6的浏览器不会执行两次

    日常工作后中不要使用这个方法兼容module,效率很低,真正生产阶段还是需要预先编译脚本

    ES Modules在node支持情况

    从node8.5开始就已经开始逐步支持EMS了,但是因为ESM和commonJS区别较大,所以目前使用common较多,目前node端的mudule还属于试验阶段,官方也不建议使用

    使用module语法:node --experimental-modules 文件

    可以通过module导入原生模块和第三方模块

    注意

    • 第三方模块都是导出一个对象,作为默认成员导出,所以不能直接使用具名成员的方法导入
    • 内置系统模块官方做了兼容,可以使用module具名导入模块
    • 使用时候需要吧js后缀名改为mjs

    node中的module和comminjs互导规则

    • ES Module可以导入commonJS模块
    • commonJS中不能导入ES Module模块
    • commonJS始终只会导出一个默认的的成员,所以ES Module导入的时候只能使用默认成员的方式导入

    node环境中两者差异 - ESM和CommonJS

    可以安装nodemon插件使用nodemon代替node进行启动,可以自动监控文件变化,自动启动

    在nodejs中,一些commonjs的用法已经不能使用,例如__dirname,已经不能访问当前文件目录,如果想使用,需要手动在mjs文件中引入path自动制作

    node新版本对于module的支持

    新版本nodejs中,对module作了进一步的支持,我们需要在package.json中添加"type": "module"字段,就可以让程序按照module方式运行,此时也不需要更改js文件为mjs了,但此时需要更改commonjs文件为cjs后缀

    babel兼容方案

    早期node版本可以使用babel编译兼容


    起源地下载网 » 模块化开发

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元