引子

前言

  • 一个 HTML 文件中引入了  a.js  和  b.js ,如何解决两个文件中同名变量的问题?
  • 一个 HTML 文件中引入了  a.js  和  b.js ,  如何解决污染全局变量的问题?
  • 一个 HTML 文件中引入了  a.js  和  b.js ,且  b.js 依赖于  a.js 中的一个变量,手动维护引入文件的先后顺序?

 

ES6之前的解决方案

使用 IIFE

 

(function() { // 使用IIFE隔离作用域
  let a = 1
  let b = 2
})()

 

 

使用AMD (asynchronous Module Definition 异步模块定义),代表库  require.js

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <script src="js/require.js" data-main="js/main.js"></script>
</body>
</html>
  • main.js 中需要使用 require 方法获取依赖的文件名(不能文件名后缀),将将每个文件所暴露的对象按顺序注入到回函函数参数中
    // 获取向外暴露的文件 然后将暴露的对象按顺序注入到回调函数中
    require(['rectangle', 'circle'], function (rectangle, circle) {
      console.log('矩形面积', rectangle.area(10, 5))
      console.log('圆形面积', circle.area(10));
    })

     

  • rectangle.js 中使用 define 方法定义向外暴露的对象 
    /**
     * 计算矩形面积
     */
    define(function() {
      function area(length, width) {
        return length * width
      }
      return { // 向外暴露对象
        area
      }
    })

     

  • circle.js 中也使用 define 方法向外暴露对象,给 require 方法使用 
    /**
     * 计算圆的面积
     */
    define(function() {
      function area(r) {
        return Math.PI * r * r
      }
      return { // 向外暴露对象
        area
      }
    })

     

  • 使用 AMD 可以解决文件之间变量同名问题,文件之间相互依赖问题、污染全局变量问题
  • AMD暴露规范指的是什么? define 函数参数中传递一个回调函数,该回调函数返回一个对象

 使用CMD (common module module 通用模块定义),代表 seajs 、 node.js

  • 引入 sea.js 并指定入口文件  main.js
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
    </head>
    <body>
    <script src="js/sea.js"></script>
    <script>
      seajs.use('./js/main.js')
    </script>
    </body>
    </html>

     

  • 在 入口文件 mina.js 中通过  require 引入 circle.js  和 rectangle.js  并使用其中的 area 方法 
    define(function (require, exports, module) {
      const c = require('./circle.js')
      const r = require('./rectangle.js')
      console.log(c.area(10)); // 314
      console.log(r.area(10, 20)); // 200
    })

     

  • 定义 circle.js 方法 
    define(function (require, exports, module) {
      function area(r) {
        return 3.14 * r * r
      }
      exports.area = area
    })

     

  • 定义 rectangle.js 方法 
    define(function (require, exports, module) {
      function area (length, width) {
        return length * width
      }
      exports.area = area
    })

     

  • node.js 中不用写 define 函数是因为被封装了

AMD 和 CMD 区别

  • AMD 中的 require 方法加载模块异步的,require 函数中的依赖项全部加载完毕后,才会执行回调函数
  • CMD 中的 require 方法加载模块是同步的

ES6的 module 模块化

  • ES6从语言层面上支持了模块化功能( 指定 script 标签的 type 属性为 module ) 
    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport"
            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
    </head>
    <body>
    <script src="./js/a.js" type="module"></script>
    </body>
    </html>

     

  • 使用 import 导入模块 
    import { b } from './b.js'
    
    console.log(b)

     

  • 使用 export 导出模块 
    export let b = 1

     

posted @ 2022-03-09 22:57  霸哥yyds  阅读(39)  评论(0)    收藏  举报