前端工程化——模块化概述

模块化概述——「模块化」只是思想

最主流的代码整合方式,安装功能不同划分不同模块。

  • 模块化演变过程
  • 模块化规范
  • 常用的模块化打包工具
  • 基于模块化工具构建现代WEB应用
  • 打包工具的优化技巧

模块化的演进过程

Stage 1 - 文件划分方式

完全依靠约定

├── index.html
├── module-01.js
└── module-02.js
  • 通过scriptsrc属性引入模块
  • 污染全局作用域,容易产生命名冲突
  • 模块成员可以随意修改
  • 无法管理模块依赖关系

Stage 2 - 命名空间方式

依靠约定,模块暴露全局对象, 所有成员都暴露在该对象下面,解决了污染全局作用域问题

var moduleA = {
    name: 'module-a'
    method1: function() {
        console.log(this.name + 'method1')
    }
    method2: function() {
        console.log(this.name + 'method2')
    }
}
  • 通过scriptsrc属性引入模块
  • 模块成员可以随意修改
  • 无法管理模块依赖关系

Stage 3 - IIFE

立即执行函数方式,为模块提供私有空间。实现了私有成员的概念。通过自执行函数传参的方式可以实现简单的模块化依赖处理

;
(function() {
    var name = 'module-a'

    function method1() {
        console.log(name + 'method1')
    }

    function method2() {
        console.log(name + 'method2')
    }
    window.moduleA = {
        method1: method1,
        method2: method2
    }
})(jQuery)
  • 通过scriptsrc属性引入模块
  • 无法管理模块依赖关系

模块化规范的出现

模块化标准+模块化加载器

  • 解决通过scriptsrc属性引入模块不受控制
  • 解决无法管理模块依赖关系

CommonJs规范

以同步的模式加载模块,在node环境中不会存在问题,但是在浏览器环境会导致效率低下

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

AMD规范 + Require.js

异步模式加载模块

  • 使用相对复杂
  • 模块js文件请求频繁
  • 基本三方模块都支持amd规范
define 定义模块
// 参数1 模块名字
// 参数2 声明依赖项
// 参数3 callback函数 函数形参中接收定义依赖项 
// 返回函数值为导出模块
define('module1', ['jquery', './module2'], function($, module2) {
    return {
        start: function() {
            $('body').animate({
                margin: '200px'
            })
            module2()
        }
    }
})
require 加载模块
require(['./module2'], function(module1) {
    module1.start()
})

模块化标准规范——模块化的最佳实践

  • node

    遵循CommonJs规范

  • web环境

    遵循ES modules规范

ES modules

基本特性

  • 自动采用严格模式,忽略 ‘use strict’
  • 每个module 都运行在私用作用域当中
  • 通过CORS方式请求外部JavaScript模块,不支持文件访问
  • 标签会延迟加载执行脚本

导入导出

直接导出
export const foo = 'es modules'
export function hello() {
    console.log('hello')
}
export class Person {}
文件末尾导出
const foo = 'es modules'

function hello() {
    console.log('hello')
}
class Person {}
export {
    foo,
    hello,
    Person
}
别名导出
const foo = 'es modules'
export {
    foo as myFoo
}
导出默认成员
const foo = 'es modules'
export default foo
常规引入
import {
    foo,
    hello,
    Person
} from './module.js'
console.log(foo)
console.log(hello)
console.log(Person)
别名处理
import {
    foo as myFoo
} from './module.js'
console.log(myFoo)
引入默认成员
import foo from './module.js'

导入导出注意事项

  • 末尾导出非对象字面量导出, 而是固定的语法
  • 导出的为引用关系不是复制一个新的对象
  • 模块引入是并不是对象解构,而是固定的语法
  • 模块引入的模块是只读的存在不能被修改

导入用法(原生)

  • 不能省略文件后缀名
  • 不能省略index

后续通过打包工具打包模块时可以省略

  • 不能省略 ./ 相对路径,否则视为三方依赖包
  • 可以使用项目的绝对路径
  • 可以使用网络资源
导出一个模块里的所有方法
import * as mod from './module.js'
console.log(mod)
  • import 只能存在最顶层不能嵌套函数或if语句
  • import 的 from 后面不能是变量
动态导入
import('./module.js').then(module => {
    console.log(module)
})
默认成员与命名成员同时导入
import name, {
    age
} from './module.js'
导出导入成员
// 常用于index 文件,做导出零散文件使用
export {
    foo,
    bar
}from './module.js'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵忠洋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值