认识前端模块化

常见模块化规范有CommonJS,AMD,CMD,ES6模块化CommonJS核心思想是通过require方法来同步加载依赖的其他模块,通过module.exports导出需要暴露的接口,通过require引入模块,同步执行。AMD规范主要是为了解决针对浏览器环境的模块化问题,最具代表性的实现是requireJS.

模块化

模块化是指把一复杂的系统分解到多个模块中

CommonJS

CommonJS 是一种使用广泛的javascript模块化规范,核心思想是通过require方法来同步加载依赖的其他模块,通过module.exports导出需要暴露的接口,通过require引入模块,同步执行 主要用在node中

  • 用法

    1
    2
    3
    4
    5
    // 采用CommonJS来进行导入导出
    // 用require方法导入
    const moduleA = require('./b.js');
    // 用module.exports导出
    module.exports = someFunc;
  • 原理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let fs = require('fs');
    let path = reqiure('path');
    let b = req('./b.js');
    function req(mod){
    let filename = path.join(__dirname,mod);
    let content = fs.readFileSync(filename, 'utf-8');
    let fn = new Function('exports', 'require', 'module', '__dirname', '__filename', content + '\n return module.exports;')
    let module = {
    exports: {}
    }
    return fn(module.exports, req, module, __dirname, __filename)
    }

AMD

AMD 也是一种Javascript 模块化规范, 与CommonJS 最大的不同在于它采用异步的方式去加载依赖的模块. AMD规范主要是为了解决针对浏览器环境的模块化问题,最具代表性的实现是requireJS.
AMD的优点

  • 可在不转换代码的情况下直接在浏览器中运行
  • 可加载多个依赖
  • 代码可运行在浏览器环境和Node.js 环境下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 定义一个模块
    define('a', [], function(){
    return 'a';
    })
    define('b', ['a'], function(a){
    return a + 'b';
    })
    // 导入和使用
    require(['b'], function(b){
    console.log(b)
    })

CMD

一个文件最为一个模块,使用define来定义模块,modules.exports对外导出模块, 使用require来加载一个模块,代表是SeaJS, 尽可能懒执行

1
2
3
4
5
6
7
8
9
// 通过 define 来定义模块
define(function(require, exports, module){
// 通过 require 引入模块
var $ = require('jquery')
// 通过 exports 对外提供接口
exports.doSomething = ...
// 通过 module.exports 提供整个接口
module.exports = ...
})

ES6模块化(ES Module)

ES6 模块化是ECMA提出的javascript模块化规范,它在语言的层面上实现了模块化.浏览器厂商和Node.js都宣布要原生支持该规范,它将逐渐取代CommonJSAMD规范,成为浏览器和服务器通用的模块化解决方案.
ES6模块目前还无法直接运行在javascript环境下,必须通过工具转换成ES5后才能正产运行

1
2
3
4
// 使用export导出
export const name = 'asd'
// 使用import导入
import {name} = from 'xxx.js'

ConmmonJS与ES6 Module的区别

  • ConmmonJS的require的模块路径可以根据if判断条件动态指定加载那个文件。ES6 Module导入和导出的路径不支持表达式,导入导出的语句必须位于顶层作用域,不能放在if等判断语句中
  • 在导入模块时CommonJS获取的是一份值拷贝,对导出的值修改,不会影响源文件的值。而ES6 Module则是值的动态映射,对导出的值进行修改,会影响源文件的值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    /* ES6 Module */
    // add-content.js
    var count = 0
    const add = function () {
    count += 1
    }
    export { count, add }
    // index.js
    import { count, add } from './add-content.js'
    console.log(count)
    add()
    console.log(count)
    count += 1 // 直接修改会报错
    // connot set property count of #<Object> which has only e getter
    /* ConmmonJS */
    // add-content.js
    var count = 0
    module.exports = {
    count: count,
    add: function () {
    count += 1
    }}
    }
    // index.js
    var count = require('./add-content.js').count
    var add = require('./add-content.js').add
    console.log(count) // 0
    add()
    console.log(count) // 0
    count += 1
    console.log(count) // 1

自动化构建

把源代码转换成在线上可执行的 Javascript、CSS、HTML代码。包括如下内容

  • 代码转换: Ecmascript6 变异成 Ecmascript5, less编译成css等
  • 文件优化: 压缩Javascript、CSS、HTML代码,图片压缩与合并。
  • 代码分割: 提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
  • 模块合并:使用构建工具将多个模块与文件合并成一个文件。
  • 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。
  • 代码校验:检验代码是否符合规范,以及单元测试是否通过。
  • 自动发布:更新完代码后,自动打包代码并发布到服务器上。

前端工程化

前端工程化 是指将前端开发的流程规范化,标准化,包括开发流程,技术选型,代码规范,构建发布等

-------------本文结束感谢您的阅读-------------
0%