webpack进阶篇(二十二):Scope Hoisting使用和原理分析

简介: webpack进阶篇(二十二):Scope Hoisting使用和原理分析

说明

玩转webpack课程学习笔记。



现象:构建后的代码存在大量闭包代码

20200706013211926.png


会导致什么问题

  • ⼤量作用域包裹代码,导致体积增大(模块越多越明显)
  • 运行代码时创建的函数作⽤域变多,内存开销变大




模块转换分析

20200706013232704.png



结论:

  • 被 webpack 转换后的模块会带上一层包裹
  • import 会被转换成 __webpack_require

进⼀步分析 webpack 的模块机制


20200706013252977.png


分析:

  • 打包出来的是⼀个 IIFE (匿名闭包)
  • modules 是⼀个数组,每⼀项是⼀个模块初始化函数
  • __webpack_require ⽤来加载模块,返回 module.exports
  • 通过 WEBPACK_REQUIRE_METHOD(0) 启动程序



scope hoisting 原理


原理:将所有模块的代码按照引用顺序放在⼀个函数作用域里,然后适当的重命名⼀些变量以防止变量名冲突。


对比: 通过 scope hoisting 可以减少函数声明代码和内存开销


20200706013325745.png


scope hoisting 使用


webpack mode 为 production 默认开启


必须是 ES6 语法(静态分析),CJS 不⽀持(动态)

module.exports = {
  entry: {
    app: './src/app.js',
    search: './src/search.js'
  },
  output: {
    filename: '[name][chunkhash:8].js',
    path: __dirname + '/dist'
  },
  plugins: [
    // webpack3需要添加这个
    new webpack.optimize.ModuleConcatenationPlugin()
  ]
};



例子


1、先将mode设置成none,在打包看看index.js

/******/ (function(modules) { // webpackBootstrap
/******/  // install a JSONP callback for chunk loading
/******/  function webpackJsonpCallback(data) {
/******/    var chunkIds = data[0];
/******/    var moreModules = data[1];
/******/    var executeModules = data[2];
/******/
/******/    // add "moreModules" to the modules object,
/******/    // then flag all "chunkIds" as loaded and fire callback
/******/    var moduleId, chunkId, i = 0, resolves = [];
/******/    for(;i < chunkIds.length; i++) {
/******/      chunkId = chunkIds[i];
/******/      if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/        resolves.push(installedChunks[chunkId][0]);
/******/      }
/******/      installedChunks[chunkId] = 0;
/******/    }
/******/    for(moduleId in moreModules) {
/******/      if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
/******/        modules[moduleId] = moreModules[moduleId];
/******/      }
/******/    }
/******/    if(parentJsonpFunction) parentJsonpFunction(data);
/******/
/******/    while(resolves.length) {
/******/      resolves.shift()();
/******/    }
/******/
/******/    // add entry modules from loaded chunk to deferred list
/******/    deferredModules.push.apply(deferredModules, executeModules || []);
/******/
/******/    // run deferred modules when all chunks ready
/******/    return checkDeferredModules();
/******/  };
/******/  function checkDeferredModules() {
/******/    var result;
/******/    for(var i = 0; i < deferredModules.length; i++) {
/******/      var deferredModule = deferredModules[i];
/******/      var fulfilled = true;
/******/      for(var j = 1; j < deferredModule.length; j++) {
/******/        var depId = deferredModule[j];
/******/        if(installedChunks[depId] !== 0) fulfilled = false;
/******/      }
/******/      if(fulfilled) {
/******/        deferredModules.splice(i--, 1);
/******/        result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
/******/      }
/******/    }
/******/
/******/    return result;
/******/  }
/******/
/******/  // The module cache
/******/  var installedModules = {};
/******/
/******/  // object to store loaded and loading chunks
/******/  // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/  // Promise = chunk loading, 0 = chunk loaded
/******/  var installedChunks = {
/******/    0: 0
/******/  };
/******/
/******/  var deferredModules = [];
/******/
/******/  // The require function
/******/  function __webpack_require__(moduleId) {
/******/
/******/    // Check if module is in cache
/******/    if(installedModules[moduleId]) {
/******/      return installedModules[moduleId].exports;
/******/    }
/******/    // Create a new module (and put it into the cache)
/******/    var module = installedModules[moduleId] = {
/******/      i: moduleId,
/******/      l: false,
/******/      exports: {}
/******/    };
/******/
/******/    // Execute the module function
/******/    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/    // Flag the module as loaded
/******/    module.l = true;
/******/
/******/    // Return the exports of the module
/******/    return module.exports;
/******/  }
/******/
/******/
/******/  // expose the modules object (__webpack_modules__)
/******/  __webpack_require__.m = modules;
/******/
/******/  // expose the module cache
/******/  __webpack_require__.c = installedModules;
/******/
/******/  // define getter function for harmony exports
/******/  __webpack_require__.d = function(exports, name, getter) {
/******/    if(!__webpack_require__.o(exports, name)) {
/******/      Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/    }
/******/  };
/******/
/******/  // define __esModule on exports
/******/  __webpack_require__.r = function(exports) {
/******/    if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/      Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/    }
/******/    Object.defineProperty(exports, '__esModule', { value: true });
/******/  };
/******/
/******/  // create a fake namespace object
/******/  // mode & 1: value is a module id, require it
/******/  // mode & 2: merge all properties of value into the ns
/******/  // mode & 4: return value when already ns object
/******/  // mode & 8|1: behave like require
/******/  __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;
/******/  };
/******/
/******/  // getDefaultExport function for compatibility with non-harmony modules
/******/  __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;
/******/  };
/******/
/******/  // Object.prototype.hasOwnProperty.call
/******/  __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/  // __webpack_public_path__
/******/  __webpack_require__.p = "";
/******/
/******/  var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
/******/  var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
/******/  jsonpArray.push = webpackJsonpCallback;
/******/  jsonpArray = jsonpArray.slice();
/******/  for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
/******/  var parentJsonpFunction = oldJsonpFunction;
/******/
/******/
/******/  // add entry module to deferred list
/******/  deferredModules.push([0,2]);
/******/  // run deferred modules when ready
/******/  return checkDeferredModules();
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _helloWebpack__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var _common_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
document.write(Object(_helloWebpack__WEBPACK_IMPORTED_MODULE_0__["helloWebpck"])());
/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "helloWebpck", function() { return helloWebpck; });
function helloWebpck() {
  return 'Hello Webpack!';
}
/***/ })
/******/ ]);



2、在mode设置为none下,添加配置

module.exports = {
  mode: 'none',
  plugins: [
    // webpack3需要添加这个
    new webpack.optimize.ModuleConcatenationPlugin()
  ]
};
/******/ (function(modules) { // webpackBootstrap
/******/  // install a JSONP callback for chunk loading
/******/  function webpackJsonpCallback(data) {
/******/    var chunkIds = data[0];
/******/    var moreModules = data[1];
/******/    var executeModules = data[2];
/******/
/******/    // add "moreModules" to the modules object,
/******/    // then flag all "chunkIds" as loaded and fire callback
/******/    var moduleId, chunkId, i = 0, resolves = [];
/******/    for(;i < chunkIds.length; i++) {
/******/      chunkId = chunkIds[i];
/******/      if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/        resolves.push(installedChunks[chunkId][0]);
/******/      }
/******/      installedChunks[chunkId] = 0;
/******/    }
/******/    for(moduleId in moreModules) {
/******/      if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
/******/        modules[moduleId] = moreModules[moduleId];
/******/      }
/******/    }
/******/    if(parentJsonpFunction) parentJsonpFunction(data);
/******/
/******/    while(resolves.length) {
/******/      resolves.shift()();
/******/    }
/******/
/******/    // add entry modules from loaded chunk to deferred list
/******/    deferredModules.push.apply(deferredModules, executeModules || []);
/******/
/******/    // run deferred modules when all chunks ready
/******/    return checkDeferredModules();
/******/  };
/******/  function checkDeferredModules() {
/******/    var result;
/******/    for(var i = 0; i < deferredModules.length; i++) {
/******/      var deferredModule = deferredModules[i];
/******/      var fulfilled = true;
/******/      for(var j = 1; j < deferredModule.length; j++) {
/******/        var depId = deferredModule[j];
/******/        if(installedChunks[depId] !== 0) fulfilled = false;
/******/      }
/******/      if(fulfilled) {
/******/        deferredModules.splice(i--, 1);
/******/        result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
/******/      }
/******/    }
/******/
/******/    return result;
/******/  }
/******/
/******/  // The module cache
/******/  var installedModules = {};
/******/
/******/  // object to store loaded and loading chunks
/******/  // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/  // Promise = chunk loading, 0 = chunk loaded
/******/  var installedChunks = {
/******/    2: 0
/******/  };
/******/
/******/  var deferredModules = [];
/******/
/******/  // The require function
/******/  function __webpack_require__(moduleId) {
/******/
/******/    // Check if module is in cache
/******/    if(installedModules[moduleId]) {
/******/      return installedModules[moduleId].exports;
/******/    }
/******/    // Create a new module (and put it into the cache)
/******/    var module = installedModules[moduleId] = {
/******/      i: moduleId,
/******/      l: false,
/******/      exports: {}
/******/    };
/******/
/******/    // Execute the module function
/******/    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/    // Flag the module as loaded
/******/    module.l = true;
/******/
/******/    // Return the exports of the module
/******/    return module.exports;
/******/  }
/******/
/******/
/******/  // expose the modules object (__webpack_modules__)
/******/  __webpack_require__.m = modules;
/******/
/******/  // expose the module cache
/******/  __webpack_require__.c = installedModules;
/******/
/******/  // define getter function for harmony exports
/******/  __webpack_require__.d = function(exports, name, getter) {
/******/    if(!__webpack_require__.o(exports, name)) {
/******/      Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/    }
/******/  };
/******/
/******/  // define __esModule on exports
/******/  __webpack_require__.r = function(exports) {
/******/    if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/      Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/    }
/******/    Object.defineProperty(exports, '__esModule', { value: true });
/******/  };
/******/
/******/  // create a fake namespace object
/******/  // mode & 1: value is a module id, require it
/******/  // mode & 2: merge all properties of value into the ns
/******/  // mode & 4: return value when already ns object
/******/  // mode & 8|1: behave like require
/******/  __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;
/******/  };
/******/
/******/  // getDefaultExport function for compatibility with non-harmony modules
/******/  __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;
/******/  };
/******/
/******/  // Object.prototype.hasOwnProperty.call
/******/  __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/  // __webpack_public_path__
/******/  __webpack_require__.p = "";
/******/
/******/  var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
/******/  var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
/******/  jsonpArray.push = webpackJsonpCallback;
/******/  jsonpArray = jsonpArray.slice();
/******/  for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
/******/  var parentJsonpFunction = oldJsonpFunction;
/******/
/******/
/******/  // add entry module to deferred list
/******/  deferredModules.push([14,0]);
/******/  // run deferred modules when ready
/******/  return checkDeferredModules();
/******/ })
/************************************************************************/
/******/ ({
/***/ 14:
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./src/index/helloWebpack.js
function helloWebpck() {
  return 'Hello Webpack!';
}
// EXTERNAL MODULE: ./common/index.js
var common = __webpack_require__(0);
// CONCATENATED MODULE: ./src/index/index.js
document.write(helloWebpck());
/***/ })
/******/ });




目录
相关文章
|
7月前
|
JavaScript 前端开发 API
webpack核心原理-2
webpack核心原理-2
39 0
|
2天前
|
API 开发工具 开发者
webpack热更新原理
Webpack的Hot Module Replacement(HMR)提升开发效率,无需刷新页面即可更新模块。开启HMR需在配置中设`devServer.hot: true`。Webpack构建时插入HMR Runtime,通过WebSocket监听并处理文件变化。当模块改变,Webpack发送更新到浏览器,HMR Runtime找到对应模块进行热替换,保持应用状态。开发者可利用`module.hot` API处理热替换逻辑。
|
3月前
|
缓存 前端开发 算法
Webpack 进阶:深入理解其工作原理与优化策略
Webpack 进阶:深入理解其工作原理与优化策略
51 2
|
5月前
|
自然语言处理 JavaScript 前端开发
webpack 的热更新是如何做到的?原理是什么?
webpack 的热更新是如何做到的?原理是什么?
39 0
|
5月前
|
缓存 前端开发 API
《Webpack5 核心原理与应用实践》学习笔记-> webpack插件开发基础
《Webpack5 核心原理与应用实践》学习笔记-> webpack插件开发基础
68 0
|
5月前
|
前端开发 JavaScript 测试技术
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader运行与调试
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader运行与调试
37 0
|
5月前
|
存储 缓存 JavaScript
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader开发技巧
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader开发技巧
44 1
|
5月前
|
缓存 监控 JavaScript
《Webpack5 核心原理与应用实践》学习笔记-> webpack极致性能优化
《Webpack5 核心原理与应用实践》学习笔记-> webpack极致性能优化
32 1
|
5月前
|
前端开发 JavaScript
《Webpack5 核心原理与应用实践》学习笔记-> webpack代码压缩
《Webpack5 核心原理与应用实践》学习笔记-> webpack代码压缩
48 0
|
5月前
|
监控 IDE 开发工具
《Webpack5 核心原理与应用实践》学习笔记-> webpack性能优化技巧
《Webpack5 核心原理与应用实践》学习笔记-> webpack性能优化技巧
68 0