美文网首页
16.前端模块化

16.前端模块化

作者: 原来哥哥是万家灯火 | 来源:发表于2020-07-03 12:59 被阅读0次
模块化

就是把代码分成一块一块的,每个块即使有相同的变量名也不会冲突(没有全局污染),每个块还可以对外暴露变量,提供给其他模块使用。
其意义就是避免产生一堆全局变量,还能使逻辑结构更加清晰。

实现原理:

把每个模块的代码都放在一个函数中执行,这样就避免了全局污染
把每个模块需要暴露的变量,统一挂载到一个全局变量。加载变量时,就从这个全局变量去取值。

举个例子:
在没有模块化这个概念时,我们的代码是这样,所有的代码都写在一个脚本里面。

<script>
    var desc = '这里提供了几个函数';
    console.log(desc); 

    function add(a, b) {
        return a + b
    }

    console.log(add(1, 2))
</script>

当代码量太大时,非常不好维护,另外还有性能问题。那么改进一下:

<script>
    var desc = '这里提供了一些函数';
    console.log(desc); 

    function add(a, b) {
        return a + b
    }
</script>

<script>
    console.log(add(1, 2))
</script>

这时候,函数的提供和调用逻辑分开了,其实就可以算是模块化了,可维护性这个问题是解决了。
但是还有个问题依然没有解决:全局污染。
代码里所有的变量,都是在全局上下文上声明的,在整个程序运行期间,都不会被回收。比如变量desc 、add。不仅造成内存泄漏、而且容易命名冲突。

那么再改进一下:

<script>
    // 同一挂载模块变量的全局变量 
    var modules = { };
    modules.require = function (moduleId) {
        return modules[moduleId].exports;
    }
</script>

<script>
    (function() {
        var module = { id: 'module1', exports: {} };
        modules.module1 = module;

        (function(exports, require, module) {

            var desc = '这里提供了几个函数';
            console.log(desc);
            function add(a, b) {
                return a + b
            }
            module.exports = {add: add}

        })(module.exports, modules.require, module )

    })()
</script>

<script>
    (function() {
        var module = { id: 'module2', exports: {} };
        modules.module2 = module;

        (function(exports, require, module) {

            var add = require('module1').add;
            console.log(add(1, 2))

        })(module.exports, modules.require, module )

    })()
</script>

这就已经实现模块化了,只不过是否真的要这样手动引入很多个script,还可以再优化。比如在node中可以使用node的 IO 能力,结合 eval 函数去加载模块并执行代码。在浏览器中可以执行一个入口文件,然后通过动态添加 script 标签去加载模块并执行代码。

CommonJS规范

一个文件就是一个模块,加载时会执行这个文件,且加载同步化的。执行文件时,会自动用上运行时。这个运行时就是一个自执行的匿名函数,并会传递一些参数进来。如下,可以打印出运行时传递的参数。

// test.js
console.log(arguments)

使用exports或者module.exports导出变量
使用require()导入变量,已经被reuiqre()加载过的模块,其导出结果会被缓存。

AMD\CMD规范

都是异步加载模块,且AMD本身就是async module define的简写。分别是RequireJS、SeaJs(淘宝)在推广过程中对模块定义的规范化产出。

  • 全局函数 difine,用于定义一个模块
  • 全局函数 require,用于加载一个模块

指定了入口文件后,被应用到的模块会被加载,加载完成之后,执行回调函数。至于如何判断是否加载并执行完毕,用的是script的load事件。下面这句话是我在 requirejs 源码中找到的注释。

IE9 has a subtle issue in its addEventListener and script onload firings that do not match the behavior of all other browsers with addEventListener support, which fire the onload event for a script right after the script execution.

翻译一下:IE9 的 addEventListener 和 script 标签的 load 的触发有个不明显的问题,其他浏览器会在脚本执行后才触发 load事件,这点上 IE9 和他们不同。
这表明,其他浏览器下,可以监听script标签的load事件。requirejs源码中也确实是这么做的。

UMD规范

umd规范,是一种糅合,判断当前环境支持哪种模块化,是amd还是commonjs,或是都不支持(如浏览器又未使用amd),然后根据具体情况来实现模块化。其原理如下:

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node, CommonJS-like
        module.exports = factory(require('jquery'));
    } else {
        // Browser globals (root is window)
        root.returnExports = factory(root.jQuery);
    }
}(this, function ($) {
    //    methods
    function myFunc(){};

    //    exposed public method
    return myFunc;
}));
ES6

导入变量

命名导入
import { sth } from 'module.js';
import { sth as something } from 'module.js';
命名空间导入
import * as sth from 'module.js';
默认导入
import sth from 'module.js';
空导入(仅仅执行模块代码,但是不输入任何值)
import 'module.js';

导出变量

命名导出
export { sth } from 'module.js';
export { sth as something } from 'module.js';
默认导出
export default sth from 'module.js';

动态导入
import()函数

相关文章

  • 16.前端模块化

    模块化 就是把代码分成一块一块的,每个块即使有相同的变量名也不会冲突(没有全局污染),每个块还可以对外暴露变量,提...

  • 前端模块化(requirejs)

    前端模块化 什么是前端模块化 将代码依据不同功能,或者职责进行模块的划分,就称为前端模块化 模块化的好处 结构更轻...

  • webpack基础笔记

    webpack基础 1.前端工程化 实际的前端开发: 模块化:(js的模块化,css的模块化,资源的模块化) 组件...

  • 关于前端模块化开发

    关于前端模块化开发 1 前端中有哪些模块化开发的规范以及实现方案 2 模块化的开发的好处 3 CommonJS

  • 前端模块化

    什么是前端模块化? 前端为什么需要模块化? CommonJS、AMD、ES6、CMD区别是什么? 一、什么是模块化...

  • 认识Webpack

    要了解Webpack,首先要知道前端模块化开发的概念 前端模块化 模块化的目的是使代码可以重用,模块化在任何开发中...

  • 前端自动化构建工具,前端工程化,前端模块化,前端组件化

    前端自动化构建,前端工程化,模块化,组件化, 1:前端自动构建工具webpack等,是为了前端的规范化,模块化,提...

  • AMD_CMD_RequireJS

    为什么要使用模块化? 前端模块化开发的价值 参考 最主要的目的: 解决命名冲突 依赖管理 在前端工程潮流下,模块化...

  • 春哥教你前端模块化

    前端模块化 (Require.js) 为什么要用 前端模块化 早期,所有Javascript代码都写在一个文件里面...

  • 【转】JavaScript模块化 --- Commonjs、AM

    随着前端js代码复杂度的提高,JavaScript模块化这个概念便被提出来,前端社区也不断地实现前端模块化,直到e...

网友评论

      本文标题:16.前端模块化

      本文链接:https://www.haomeiwen.com/subject/jyksqktx.html