JS模块化 笔记

简介

模块化的好处:

  • 避免命名冲突
  • 更好的分离,按需加载
  • 更高复用性
  • 高可维护性

产生的问题:

  • 请求过多
  • 依赖模糊
  • 难以维护

modular

1. 全局function模式
let msg = "feidu";
function f1() {
  console.log("01-f1: " + msg);
}
<script src="./01.js"></script>
<script>
    f1(); // 01-f1: feidu
    // 数据可以修改,不安全
    msg = "jianrong";
    f1(); // 01-f1: jianrong
</script>
2. namespace模式:简单对象封装
let obj = {
  msg: "feidu",
  f1() {
    console.log("01-f1: " + this.msg);
  },
};
<script src="./01.js"></script>
<script>
    obj.f1(); // 01-f1: feidu
    // 数据还是可以修改
    obj.msg = "jianrong";
    obj.f1(); // 01-f1: jianrong
</script>
3. IIFE模式:匿名函数自调用
(function (window) {
  let msg = "feidu";
  function f1() {
    console.log("01-f1: " + msg);
  }
  window.m = { f1 };
})(window);
<script src="./01.js"></script>
<script>
    m.f1(); // 01-f1: feidu
    // 此时无法访问数据
</script>
4. IIFE增强
(function (window) {
  let msg = "feidu";
  function f1() {
    console.log("01-f1: " + msg);
  }
  window.f = f1;
})(window);
<script src="./01.js"></script>
<script>
    f(); // 01-f1: feidu
    // 此时无法访问数据
</script>

CommonJS

  • 每一个JS文件都可以当做一个模块
  • 在服务器端:模块的加载是运行时同步加载的
  • 在浏览器端:模块需要提前编译打包处理
导出模块
module.exports = value
exports.xxx = value

引入模块
let m1 = require("./modules/module1");

服务器端实现:Node.js

let m1 = require("./modules/module1");
let m2 = require("./modules/module2");
let m3 = require("./modules/module3");

m1.f1(); // module1
m2(); // module2
m3.f1(); // module3
module.exports = {
  msg: "module1",
  f1() {
    console.log(this.msg);
  },
};
module.exports = function () {
  console.log("module2");
};
exports.f1 = function () {
  console.log("module3");
};

浏览器端实现:Browserify

<!-- 模块的编写方式同上 -->
<!-- 直接引入的话浏览器不认识require方法 -->
<!-- <script src="./js/src/app.js"></script> -->
<!-- 
    使用命令编译:npx browserify JS模块化/js/src/app.js -o JS模块化/js/dist/bundle.js 
    然后在页面上引入编译的js文件
-->
<script src="./js/dist/bundle.js"></script>

AMD

  • 专门用于浏览器端,模块的加载是异步的
定义没有依赖的模块
define(function() {
    return 模块
})

定义有依赖的模块
define([module1, module2], function(m1, m2) {
    return 模块
})

引入使用模块
require([module1, module2], function(m1, m2) {
    使用 m1, m2
})

实例

define(function () {
  let name = "dataService";
  function getName() {
    return name;
  }
  return { getName };
});
define(["dataService"], function (dataService) {
  let msg = "alterer";
  function showMsg() {
    console.log(msg, dataService.getName());
  }
  return { showMsg };
});
(function () {
  requirejs.config({
    baseUrl: "js/modules",
    paths: {
      // 配置模块名字与路径的对应,文件名不加 .js
      // 如果不配置baseUrl,此时的路径相对于app.js
      // dataService: "./modules/dataService",
      // alterer: "./modules/alterer",

      // 如果配置baseUrl,路径相对于根目录
      dataService: "dataService",
      alterer: "alterer",
    },
  });
  requirejs(["alerter"], function (alterer) {
    alterer.showMsg();
  });
})();
<!-- 绑定主模块和requirejs -->
<script data-main="./js/app.js" src="./js/libs/require.js"></script>

使用第三方模块

requirejs.config({
  baseUrl: "js/modules",
  paths: {
    // 要注意模块是否支持AMD 以及模块名称的问题
    jquery: "jquery-1.10.1",
    angular: "angular"
  },
  shim: {
    angular: {
      exports: "angular",
    },
  },
});

CMD

  • 专门用于浏览器端,模块的加载是异步的
  • 模块使用时才会加载执行
定义没有依赖的模块
define(function(require, exports, module) {
    exports.xxx = value
    module.exports = value
})

定义有依赖的模块
define(function(require, exports, module) {
    同步引入依赖模块
    let module2 = require('./module2) 
    异步引入依赖模块
    require.async('./module3', function(m3) {

    })
    exports.xxx = value
})

引入使用模块
define(function (require) {
    let m2 = require('./module2) 
    let m4 = require('./module4) 
    m2.show()
    m4.show()
})

<script src="./js/libs/sea.js"></script>
<script>
	seajs.use('./js/modules/main.js')
</script>

ES6

参考:模块化 章节
https://blog.csdn.net/Alice_Lee_Lee/article/details/120845338

补充 babel 说明:

  • 配置文件:.babelrc 这是一个json文件,配置内容可以参考官网
  • babel 将代码转换为 ES5 的,但是代码中仍旧包含 Node中require 的语法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值