webpack模块化编程进化史及规范

首先我们要知道webpack是什么?

webpack是一个现代JavaScript应用程序的静态模块打包工具。当webpack处理应用程序时,它会在内部构建一个依赖图,此依赖图会映射项目所圃的每个模块,并生成一个或多个bundle包! webpack本身是基于node.js开发的!(比如说:有多个js文件,我们需要构建这些js文件的依赖关系,读取这些js文件中的代码,最后合并在一起 放在一个新的js文件中,最后压缩)

我们为什么要学习webpack?(webpack的好处)

  • 代码转换: TypeScript编译成JavaScript、LESS/SCSS编译成CSS、ES6/7编译为ES5、虚拟DOM编译为真实的DOM等等.。
  • 文件优化:压缩JS、CSS、HTML代码,压缩合并图片,图片BASE64等
  • 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码等
  • 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
  • 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器
  • 代码校验: Eslint代码规范校验和检测、单元测试等
  • 自动发布:自动构建出线上发布代码并传输给发布系统
  • .........

webpack的模块化编程历史

  • 单例设计模式

  • AMD「require.js」

  • CommonJS

  • CMD「sea.js」

  • ES6Module

单例设计模式:最早期的模块开发管理方案

首先要知道单例设计模式

单例模式的好处:

@1:它是被闭包 包起来的 可以防止全局变量的污染。它保证了各个模块之间方法/属性的私有化

@2:可以把闭包中某些属性和方法 暴露出去 供别的模块使用,可以实现模块间方法的调用

假设说有两个模块 :A模块和B模块  A 模块中有一个方法求和,B模块中有一个方法求平均数

单例设计模式A模块js代码:

let AModule=(function(){
    let name="A";
    const sum=function sum(...args){
        if(args.length===0)return 0;
        if(args.length===1)return args[0];
        return args.reduce((result,item)=>{
            return result+item;
        },0)
    };
    return {
        name,
        sum
    }
})();

单例设计模式B模块js代码:

let BModule = (function () {
    let name = 'B';
    const average = function average(...args) {
        args.sort((a, b) => a - b);
        args.pop();
        args.shift();
        if (args.length === 0) return 0;
        let total = AModule.sum(...args);
        return (total / args.length).toFixed(2);
    };
    return {
        name,
        average
    };
})();

我们可以发现一个特点  B模块一定依赖于A 模块  他们之间存在依赖关系

我们需要把所有的模块合并在一起 必须先导入A 模块,因为B模块依赖于A模块

创建一个入口文件:main.js,在入口文件中拿到所有的模块拿来用

console.log(AModule.sum(10, 20, 30, 40, 50));
console.log(BModule.average(10, 20, 30, 40, 50));

在单例设计模式中的HTML 引入的js顺序是这样的

    <script src="A.js"></script>
    <script src="B.js"></script>
    <script src="main.js"></script>

但是存在一个弊端  js文件过多 我们需要自己构建依赖关系,梳理起来比较困难 ,比较恶心。所以诞生了新的开发管理规范

AMD[require.js]//导入框架:

相对于单例设计模式来说,在单例模式的基础上加入模块之间的依赖关系的处理。这种模式叫做AMD模式

先在HTML中导入require.min.js文件  我们使用AMD需要用到require插件。main.js 作为入口文件

    <script src="require.min.js"></script>
    <script src="main.js"></script>

我们先要拿require进行全局配置。在main.js中

require.config({
    //全局配置
    baseUrl: 'lib',//所有的模块都去lib文件夹找
});
require(['A', 'B'], function (AModule, BModule) {
    console.log(AModule.sum(10, 20, 30, 40, 50));
    console.log(BModule.average(10, 20, 30, 40, 50));
});

A模块js代码:使用   define  定义模块

define(function () {
    const sum = function sum(...args) {
        if (args.length === 0) return 0;
        if (args.length === 1) return args[0];
        return args.reduce((result, item) => {
            return result + item;
        }, 0);
    };
    
    return {
        sum
    };
});

B模块js代码:

define(['A'], function (AModule) {  //数组中存放 所有依赖的模块  正常情况下应该是'lib/A.js'但是已经指定了公共的文件夹(lib)所以写成A  .js可以忽略不写
    const average = function average(...args) {
        args.sort((a, b) => a - b);
        args.pop();
        args.shift();
        if (args.length === 0) return 0;
        let total = AModule.sum(...args);
        return (total / args.length).toFixed(2);
    };
    return {
        average
    };
});

注意:定义模块期间,指定需要的依赖  AModule存储A模块导出的内容

/特点:所需要的依赖,需要“前置导入”  所有的依赖都需要在数组中导入

AMD模块开发思想,解决了模块之间依赖的问题。但是存在所有依赖的模块都需要前置导入!浏览器不支持AMD思想,需要我们导入插件:require.min.js

CommonJS:[不支持浏览器端 ,Node.js默认的模块规范就是CommonJS]《常用》

CommonJS实现模块的导入和导出:main.js作为入口文件

let sum = require('./A');
console.log(sum(10, 20, 30, 40));

let B = require('./B');
console.log(B.average(10, 20, 30, 40));

注意: CommonJS模块规范

  CommonJS模块规范导出「多个」
    module.exports = {
        sum
    };
    导入
    let A = require(模块地址);
    A.sum(...);
    ---
  CommonJS模块规范导出「一个」
    module.exports = sum;
    导入
    let sum = require(模块地址);

A模块js代码:

const sum = function sum(...args) {
    if (args.length === 0) return 0;
    if (args.length === 1) return args[0];
    return args.reduce((result, item) => {
        return result + item;
    }, 0);
};
module.exports = sum;

B模块js代码:

let sum = require('./A');//... 模块地址需要是相对地址(./ OR ../ OR /),这样才是导入自己写的模块;如果不写相对地址,只写模块名字,则是导入Node内置模块或者安装的第三方模块!
const average = function average(...args) {
    args.sort((a, b) => a - b);
    args.pop();
    args.shift();
    if (args.length === 0) return 0;
    let total = sum(...args);
    return (total / args.length).toFixed(2);
};
module.exports = {
    average
};

CommonJS规范支持“按需导入”  什么时候用,什么时候导入  比AMD思想用起来更加方便

HTML部分

<script src="main.js"></script>

CMD「sea.js」

CMD 是淘宝中的“玉伯”,自己写了个 sea.js 插件,把CommonJS规范,搬到浏览器端也能用」

ES6Module:《常用

特点:不导入任何插件  也可以在浏览器端  像 CommonJS 规范一样,去管理模块化开发

ES6Module模块规范:

导出:export   导入:import

   @1: export let xxx = xxx;(导出多个)

   @2:export const xxx = function xxx(){};(导出多个)

   @3:export function xxx() { };

............

导出多个内容:[内部也是导出一个对象:把变量名作为对象的属性名,变量值作为属性值]

不支持的语法(导出对象)export {x:10};

支持的语法export default {x:10};  

导入:

import {xxx} from '地址';  //直接解构赋值

import * as AAA from '地址';  //导入所有导出的内容,并且赋值给AAA这个对象

-----------------------------------

 export default 值

 export default {...};

 export default function xxx(){};

 export default xxx;

   导出的还是个对象,对象中有一个叫做“default”的属性,属性值是导出的这个值;所以一个模块中,export default 只能出现一次;export default 导出的内容,在导入的时候,不能直接的解构赋值;

   import xxx from '地址';  //直接获取导出的default属性值

导入时候的特点:

 @1 必须放在代码最前面 “前置导入”

 @2 不能省略后缀名「但是在webpack中可以省略」

 @3 必须设定好相对路径

main.js中

import sum from './A.js';
import { average } from './B.js';
console.log(sum(10, 20, 30, 40, 50));
console.log(average(10, 20, 30, 40, 50));

HTML中 : 想要开启管理规范需要 设置 type="module" 就可以在JS文件中使用ES6Module模块规范 。但是有个前题就是页面的预览需要基于 http或者https 协议

 <script type="module" src="main.js"></script>

A模块js代码:

const sum = function sum(...args) {
    if (args.length === 0) return 0;
    if (args.length === 1) return args[0];
    return args.reduce((result, item) => {
        return result + item;
    }, 0);
};
export default sum;

B模块js代码:

import sum from './A.js';
export const average = function average(...args) {
    args.sort((a, b) => a - b);
    args.pop();
    args.shift();
    if (args.length === 0) return 0;
    let total = sum(...args);
    return (total / args.length).toFixed(2);
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值