美文网首页
CommonJS规范

CommonJS规范

作者: 刘彪lastbee | 来源:发表于2019-09-26 14:18 被阅读0次

    研究了一下CommonJS规范,用webpack打包之后,得到源码进行分析,只要分析webpack_require与打包的过程。webpack打包的命令(webpack --devtool none --mode development --target node ./src/index.js --output-path='./CommonJS'

    • webpack的用法自行百度,我只展示打包后的代码(把注释删掉了)
    源码
    // core.js
    console.log('core js')
    exports.name = 'Jack'
    exports.old = '18'
    exports.play = function() {
      console.log('play game')
    }
    
    module.exports = function() {
      console.log('module')
    }
    
    // index.js
    const Core = require('./core.js')
    console.log(Core.name)
    console.log(Core.old)
    console.log(Core.paly)
    console.log(Core)
    
    (function (modules) {
      var installedModules = {};
      function __webpack_require__(moduleId) {
        if (installedModules[moduleId]) {
          return installedModules[moduleId].exports;
        }
        var module = installedModules[moduleId] = {
          i: moduleId,
          l: false,
          exports: {}
        };
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
        module.l = true;
        return module.exports;
      }
      __webpack_require__.m = modules;
      __webpack_require__.c = installedModules;
    
      __webpack_require__.d = function (exports, name, getter) {
        if (!__webpack_require__.o(exports, name)) {
          Object.defineProperty(exports, name, { enumerable: true, get: getter });
        }
      };
      __webpack_require__.r = function (exports) {
        if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
          Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
        }
        Object.defineProperty(exports, '__esModule', { value: true });
      };
      __webpack_require__.t = function (value, mode) {
        if (mode & 1) value = __webpack_require__(value);
        if (mode & 8) return value;
        if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
        var ns = Object.create(null);
        __webpack_require__.r(ns);
        Object.defineProperty(ns, 'default', { enumerable: true, value: value });
        if (mode & 2 && typeof value != 'string') for (var key in value) __webpack_require__.d(ns, key, function (key) { return value[key]; }.bind(null, key));
        return ns;
      };
      __webpack_require__.n = function (module) {
        var getter = module && module.__esModule ?
          function getDefault() { return module['default']; } :
          function getModuleExports() { return module; };
        __webpack_require__.d(getter, 'a', getter);
        return getter;
      };
      __webpack_require__.o = function (object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
      __webpack_require__.p = "";
      return __webpack_require__(__webpack_require__.s = "./src/index.js");
    })({
    
      "./src/core.js": (function (module, exports) {
    
        console.log('core js')
    
        exports.name = 'Jack'
        exports.old = '18'
        exports.play = function () {
          console.log('play game')
        }
    
        module.exports = function () {
          console.log('module')
        }
    
      }),
      "./src/index.js": (function (module, exports, __webpack_require__) {
        const Core = __webpack_require__(/*! ./core.js */ "./src/core.js")
        console.log(Core.name)
        console.log(Core.old)
        console.log(Core.paly)
        console.log(Core)
      })
    });
    

    分析一下结构

    1、 './src/core.js'与'./src/index.js'是两个脚本路径,每个参数指向一个函数,每个模块相当于一个作用域,js使用函数创建作用域。
    2、打包之后就是个自执行函数,参数就是每个模块的对应的函数

    (function (modules) {})({模块1, 模块2,...})
    

    3、installedModules 储存每个模块初始化,判断是否已经初始化,在调用入口文件
    4、可以看出来./src/core.jsmodule.exports是被重新赋值,而./src/core.js内部的module.exports内被保留在函数内部

    var module = installedModules[moduleId] = {
      i: moduleId,
      l: false,
      exports: {} // 重新赋值
    };
    return module.exports// 返回结果
    
    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    

    关于webpack打包的原理 AST preset-env loader plugins entry output等有兴趣可以了解一下,我只是简单介绍CommonJS规范引入nodeJS是怎么引用的,以及exports的作用域

    相关文章

      网友评论

          本文标题:CommonJS规范

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