zoukankan      html  css  js  c++  java
  • 基于JS模块化现状谈谈选择ES6模块的原因

    这篇文章,我们将了解为什么JS社区有必要选择ES6模块。

    现状

    要明白这种重要性,首先我们需要描述一下JS的实际情况。过去5年,JavaScript 发展得非常迅猛,大多数开发人员几乎没意识到当前已经有 5 种方式,可以为 JavaScript 脚本和应用创建模块了!

    • 原始的 IIFE () : 这是最古老,也是比较简单的创建 JS 模块的方法了。以下是用 IIFE 实现的简单模块化示例:
       const myModule = (function (...deps){
           // JavaScript chunk
           return {hello : () => console.log(‘hello from myModule’)};
        })(dependencies);

    相信大家对这段代码都不陌生,它只是把变量和方法都封装在本身作用域内的一种普通模式。其存在的缺点就是没有帮我们处理依赖。

    • requirejsAMD (异步模块依赖) : Require.js 很受欢迎,它可以给模块注入依赖,还允许动态地加载 JS 块。
      <pre>define(‘myModule’, [‘dep1’, ‘dep2’], function (dep1, dep2){
            // JavaScript chunk, with a potential deferred loading
            return {hello: () => console.log(‘hello from myModule’)};
        });
        // anywhere else
        require([‘myModule’], function (myModule) {
            myModule.hello() // display ‘hello form myModule’
        });

    效率高,可惜有点冗长,而且不能在 Node.js 本地运行。

    • CommonJs : Node.js 平台的默认格式. 通常用法类似这样:
      // file1.js
        modules.export = {
            hello : () => console.log(‘hello from myModule’)
        }
    
        // file2;
        const myModule = require('./file1.js');
        myModule.hello();

    nodejs

    感觉这种方式更酷吧,不仅可以定义变量的作用域,还可以定义模块之间的依赖。可惜这是专为 Node 设计的,不支持在浏览器运行,也不能异步加载模块。但是,它可以在前端app使用,借助 Browserify 或者其他工具来转换,就可以让它在浏览器运行了。

    • UMD (通用模块依赖) : 到这里,我们发现还没有一种既可以同时兼容浏览器和 Node 服务器的解决方案。AMD 适合浏览器,CommonJS 适合 Node.

    UMD 就来尝试解决这个问题了。它通过把 AMD 和 CommonJS 结合起来,使之在各种需求下都是可集成的,代码大概如下:

     (function (global, factory) {
            typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
            typeof define === 'function' && define.amd ? define(factory) :
        (factory());
        }(this, function () {
            // JavaScript chunk
            return {
               hello : () => console.log(‘hello from myModule’)
            }
        });

    该模式根据内容来判断选择 AMD 还是 CommonJS. 这种模式对于打包 多环境 的库,如 lodash 或者 moment.js 是十分适合的。

    因此,为何要加一个新模块类型 ?

    首先,这些解决方案没有一个是由TC39团队定义的标准。ECMA6 现在已经被大量的开发者所使用,那为何不选择该版本JS定义的标准(ES6模块)呢?

    这个标准提供了一个更加灵活有力的解决方式。我推荐你看这篇文章, 了解 ES6模块的全部属性,因为这篇文章,我把重点放在了ES6模块这个性质上。它能够更加精确地定义模块间哪些需要被 exposed/imported。一起看看下面的代码:

    // file1.js
    const f1 = ()=> console.log(‘f1’);
    const f2 = ()=> console.log(‘f2’);
    const f3 = ()=> console.log(‘f3’);
    export {f1, f2, f3};
    
    // file2.js
    import {f1, f2} from “./file1”;
    f1(); // display ‘f1’
    f2(); // display ‘f2’

    从这里可以看出,只需要静态地声明我们想要 import 的内容就可以。与其它模式不同,像 CommonJS 我们可以动态加载需要的文件。如果我们在 CommonJS 里面使用这个例子,就会有点不同:

    // file1.js
    const f1 = ()=> console.log(‘f1’);
    const f2 = ()=> console.log(‘f2’);
    const f3 = ()=> console.log(‘f3’);
    modules.exports = {f1,f2,f3};
    
    // file2.js
    const file1 = require(‘./file1’);
    file1.f1(); // display ‘f1’
    file1.f2(); // display ‘f2’
    file1[process.ENV.funcName]();

    很明显,最后一行无法呈现成真正的代码,但它表明了一些值超出了可控范围,无法在静态分析中被预知。这里,我们实质上是可以调用 f3,因为用 CommonJs (AMD、IIFE 或者 UMD) 我们都是无法限制 import 的内容。

    tree-shacking

    所以?了解代码的静态分析是使用什么是不是也很重要呢?

    答案是肯定的!

    因为有了这个控制,开发者工具可以检测到一些 bug。 如果你使用 WebPack 2 或者 Rollup.js 将会更有趣,结合 Tree Shaking, 你编译的文件将会更小。Tree Shaking 的功能就是把不用用到的代码移除掉。

    这就是 tree shaking 的一个例子 :

    原文件
    //-------------
    // main.js
    import {cube} from './maths.js';
    console.log( cube( 5 ) ); // 125
    
    //-------------
    // maths.js
    export function square ( x ) {
       return x * x;
    }
    
    // This function gets included
    export function cube ( x ) {
       return x * x * x;
    }
    输出文件
    function cube ( x ) {
       return x * x * x;
    }
    
    console.log( cube( 5 ) ); // 125

    Mathieu Breton CTO chez JS-Republic

    原文链接https://www.zcfy.cc/article/1010

  • 相关阅读:
    LeetCode OJ 107. Binary Tree Level Order Traversal II
    LeetCode OJ 116. Populating Next Right Pointers in Each Node
    LeetCode OJ 108. Convert Sorted Array to Binary Search Tree
    LeetCode OJ 105. Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode OJ 98. Validate Binary Search Tree
    老程序员解Bug的通用套路
    转载 四年努力,梦归阿里,和大家聊聊成长感悟
    转载面试感悟----一名3年工作经验的程序员应该具备的技能
    Web Service和Servlet的区别
    关于spring xml文件中的xmlns,xsi:schemaLocation
  • 原文地址:https://www.cnblogs.com/GeniusZ/p/12539679.html
Copyright © 2011-2022 走看看