总结JavaScript不同模块化规范的差别

164 阅读2分钟

本篇文章主要介绍CommonJs,AMD,CMD,ES Modules的基本使用与区别

  1. CommonJs

    也就是Nodejs上使用的模块化规范,模块加载是同步加载,服务端能够直接运行,浏览器端要运行需要打包工具打包以后才能运行(比如browserify)

    基本语法:

    暴露模块:

    module.exports = value;
    exports.xxx = value;
    

    引入模块:

    require(xxx)
    
  2. AMD

    专门针对浏览器端的,模块加载是异步的,依赖于Require.js

    基本语法:

    暴露模块

    //定义没有依赖的模块
    define(function(){
    	return 模块
    })
    
    //定义有依赖的模块
    define['module1', 'module2'], function(m1, m2){
      function() showMsg(){
        console.log("我是模块", m1.xxx)
      }
      return {showMsg};
    }
    

    引入模块

    main.js

    (function(){
      //引入之前记得配置js文件的路径
      requirejs.config({
        baseUrl: 'js/module',//公共路径,也就是下面paths中的路径前面都得加上js/
        paths: {
          module1: 'module1',
          module2: 'module2'
        }
      })
    
      require(['module1', 'module2'], function(m1, m2){
        //使用m1, m2
        m1.xxx;
        m2.yyy;
      })
    })();
    

    index.html中

    //date-main是你自己的文件,src是你下载下来的require.js的文件
    <script data-main="js/main.js" src="js/require.js"></script>
    
  3. CMD

    专门用于浏览器端,模块的加载是异步的

    模块使用时才会加载

    暴露模块

    define(function(require, exports, module){
      exports.xxx = value
    	module.exports = value
    })
    
    //定义有依赖的模块
    define(function(require, exports, module){
      //引入依赖模块(同步)
      var module2 = require('./module2')
      //引入依赖模块(异步)
      require.asycn('./module3', function (m3) {
    
      })
      //暴露模块
      exports.xxx = value
    })
    
    

    引入模块

    define(function (require) {
      var m1 = require('./module1')
      var m4 = require('./module4')
      m1.show()
      m4.show()
    })
    
  4. ES Modules

    依赖的模块需要编译打包处理(先使用Babel,将ES6编译为ES5,再使用browserify编译js,最终才能在浏览器上运行)

    学习过Vue的朋友应该很熟悉这种规范,因为Vue中使用的就是这种规范

    基本语法

    暴露模块:

    • 常规暴露

      • 分别暴露
      export function foo(){//export,不是exports
        ....
      } 
      export function bar(){//export,不是exports
        ....
      }
      
      • 统一暴露
      function foo(){
        ...
      }
      function bar(){
        ...
      }
      export { foo, bar }
      
    • 默认暴露

      export default () => {
        ...
      };
      

    引入模块:

    import { foo, bar } from '路径';//引入常规暴露的模块
    import obj from '路径';//引入默认暴露的模块
      
    foo();
    bar();
    obj();