JS模块化

模块化发展进程

一:function方式

优缺点
  • 缺点:无安全性、污染Global(模块内变量声明为window属性)。
代码示例
  • module1
var data = 'module_data';
//let data_ = 'module_data';
function fn(){
    console.log(data);
    //console.log(data_);
}
  • test.html
<script type='text/javascript' src='module1.js'></script>
<script type='text/javascript'>
var data = 'window_data';
//let data_ = 'window_data';// let方式声明的与模块中的同名变量,运行报错重复声明(IDE检测不会爆红提示)。
  fn();
</script>
  • 运行结果
    在这里插入图片描述

二:namespace方式

优缺点
  • 优点:模块内变量声明为自定义对象属性,不污染全局变量。
  • 缺点:不能私有变量、无安全性(模块外仍可以直接修改模块内变量值)。
代码示例
  • module2
let obj = {
  data:"module_data",
    fn(){
        console.log(this.data);
    }
};
  • test.html
<script type='text/javascript' src='module2.js'></script>
<script type='text/javascript'>
obj.fn();
obj.data = 'window_data';
obj.fn();
</script>
  • 运行结果
    在这里插入图片描述

三:IIFE模式

IIFE : immediately-invoked function expression(立即调用函数表达式)

优缺点
  • 优点:可以私有变量、选择性暴露。
  • 缺点:不够强大,缺少模块引用功能。
代码示例
  • module3
(function(window){
    let publicData = 'public_data';
    let privateData = 'private_data';
    function publicFn(){
        console.log(privateData);
    }
    window.module3 ={publicData,publicFn}
})(window);
  • test.html
<script type='text/javascript' src='module3.js'></script>
<script type='text/javascript'>
  console.log(module3.publicData);
module3.publicFn();
</script>
  • 运行结果
    在这里插入图片描述

四;IIFE模式增强(现代模块实现的基石)

优缺点
  • 优点:私有变量、选择性暴露、引用模块。
  • 缺点:网页加载变慢(js文件增多导致http请求增多)、模块间的引用模糊难以维护。
代码示例
  • module4
(function(window,$){
    let publicData = 'public_data';
    let privateData = 'private_data';
    function publicFn(){
        console.log(privateData);
    }
    function jqueryTest(){
        $('body').css('background', 'red')
    }
    window.module4 ={publicData,publicFn,jqueryTest}
})(window,$);
  • test.html
<script type='text/javascript' src='jquery-1.10.1.js'></script>
<!--被引用的模块必须保证先被引入-->
<script type='text/javascript' src='module4.js'></script>
<script type='text/javascript'>
console.log(module4.publicData);
  module4.publicFn();
  module4.jqueryTest();
</script>
  • 运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VIllOr0f-1583725390681)(C:\Users\ASUS\Desktop\md笔记\尚硅谷前端\5规范集成\模块化\assets\1583724204077.png)]

模块化规范

可以解决由于模块化而带来的js请求过多以及模块的依赖管理问题。

CommonJS

服务器端(node)
浏览器端
  • 编译打包:模块需要提前编译打包处理(合并模块、转译commonJS语法)。
  • src/dist:编译打包前和编译打包后的代码文件夹(代码修改后需再次编译打包);
特点
  • 代码简洁:使用第三方工具一次编译打包即可,无不相关业务代码。
  • 无需配置
  • 修改麻烦:每次修改后都要再次编译打包
代码示例
  • 目录结构
    在这里插入图片描述
  • js/src/moduleAttr.js
/**
 * 函数向模块内传递的形参有require、module、exports。
 * 使用exports.xxx = value向外暴露一个对象。
 */
let privateData = 'private_data';
exports.publicData = 'public_data';
exports.publicFn = function(){
    console.log('attr_'+privateData);
};
  • js/src/moduleObj.js
/**
 * 函数向模块内传递的形参有require、module、exports。
 * 使用module.exports = value向外暴露一个对象
 */
let privateData = 'private_data';
module.exports = {
    publicData:'public_data',
  publicFn(){
      console.log('obj_'+privateData);
  }
};
  • js/src/moduleFun.js
/**
 * 函数向模块内传递的形参有require、module、exports。
 * 使用module.exports = value向外暴露一个函数
 */
let privateData = 'private_data';
module.exports = function(){
  console.log('fun_'+privateData) ;
};
  • js/src/index.js
// 安装开发依赖broserify
npm install browserify -g
// 使用browserify编译打包index.js入口文件
browserify js/src/index.js -o js/dist/bundle.js
let moduleAttr = require('./moduleAttr');
let moduleObj = require('./moduleObj');
let moduleFun = require('./moduleFun');

console.log(moduleAttr.publicData);
console.log(moduleAttr.privateData);
moduleAttr.publicFn();

console.log('------------------------');
console.log(moduleObj.publicData);
console.log(moduleObj.privateData);
moduleObj.publicFn();

console.log('------------------------');
moduleFun();
  • index.html
<!--引入编译打包后的js文件-->
<script type="text/javascript" src="js/dist/bundle.js"></script>
  • 运行结果
    在这里插入图片描述

AMD

浏览器端
  • 专门用于浏览器端,模块的加载是异步的。
特点
  • 少量配置代码。
  • 模块异步加载。
  • 模块按需加载。
代码示例
  • 目录结构
    在这里插入图片描述
  • 工具库:js/libs/require.js
  • 入口/配置文件:js/main.js
(function () {
    //配置
    require.config({
        //基本路径
        baseUrl: 'js/',
        //映射: 模块标识名: 路径
        paths: {
            //自定义模块
            'module1': 'src/module1',
            'module2': 'src/module2',

            //库模块
            'jquery': 'libs/jquery-1.10.1'
        }
        //配置不兼容AMD的模块
    });

    //引入模块使用
    require(['module2'], function (module2) {
        module2.module2Fn();
    })
})();
  • 第三方模块:js/libs/jquery.js(jQuery的实现支持AMD规范)

  • 自定义无依赖模块:module1

/*
 定义没有依赖的模块
 */
define(function () {
    let module1_data = 'module1_data';

    function module1Fn() {
        return module1_data
    }

    return {module1Fn}
});

  • 自定义有依赖模块:module2
/*
 定义有依赖的模块
 */
define(['module1', 'jquery'], function (module1, $) {
    let module2_data = 'module2_data';

    function module2Fn() {
        $('body').css('background', 'red');
        console.log(module1.module1Fn() + '--' + module2_data);
    }
    return {module2Fn}
});
  • index.html
<!--引入require.js并指定js主文件的入口-->
<script type="text/javascript"  src="js/libs/require.js" data-main="js/main.js"></script>
  • 运行结果
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6LOjWNrT-1583763282355)(C:\Users\ASUS\Desktop\md笔记\尚硅谷前端\5规范集成\模块化\assets\1583763088368.png)]

CMD

ES6

浏览器端
  • ES6->ES5:使用Babel将ES6转译为ES5代码(但包含CommonJS语法)。
  • ES5->Bundle:使用Browserify将转译后的ES5代码编译打包成js。
代码示例
  • 目录结构
    在这里插入图片描述
  • js/src/module1.js
/**
 * 分别暴露
 */
let privateData = 'module1_private_data';

export let publicData = 'module1_public_data';
export function module1Fn1(){
    console.log(privateData);
}
  • js/src/module2.js
/**
 * 统一暴露
 */
 
let privateData = 'module2_private_data';

let publicData = 'module2_public_data';
function module2Fn1(){
    console.log(privateData);
}
export {publicData,module2Fn1}
  • js/src/module3.js
/**
 * 默认暴露
 */
let privateData = 'module3_private_data';

let publicData = 'module3_public_data';
function module3Fn1(){
    console.log(privateData);
}

// 可暴露一个函数/对象/值
export default{
    publicData,
    module3Fn1
}
  • js/src/index.js
// 常规暴露使用解构赋值引入
import {publicData1,module1Fn1} from './module1';
import {publicData2,module2Fn1} from './module2';
// 默认暴露使用对象接收
import module3 from './module3';
// 引入第三方库
import $ from 'jquery';

console.log(publicData1);
console.log(publicData2);
console.log(module3.publicData);
module1Fn1();
module2Fn1();
module3.module3Fn1();

$("body").css("background","red");
  • js/build文件夹
npm install babel-cli -g 
npm install babel-preset-es2015 --save-dev
// 已配置好.babelrc,并确认已开发依赖babel-preset-es2015
babel js/src -d js/build
  • .babelrc(json):babel-cli运行所读取的配置文件
{
    "presets": ["es2015"]
}
  • package.josn
{
  "name": "moduleEs6Test",
  "version": "1.0.0",
  "devDependencies": {
    "babel-preset-es2015": "^6.24.1"
  },
  "dependencies": {
    "jquery": "^1.12.4"
  }
}
  • js/dist文件夹
npm install babel-cli browserify -g
// 指定入口文件和打包后的文件名。
browserify js/build/index.js -o js/dist/bundle.js
  • index.html
<script type='text/javascript' src='./js/dist/bundle.js'></script>
  • 运行结果
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值