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());
/***/ })
/******/ });




目录
打赏
0
0
0
0
21
分享
相关文章
Webpack Bundle Analyzer:深入分析与优化你的包
Webpack Bundle Analyzer是一款可视化工具,帮助分析Webpack构建结果,找出占用空间较大的模块以便优化。首先需安装Webpack和Webpack Bundle Analyzer,接着在`webpack.config.js`中配置插件。运行Webpack后,会在`dist`目录生成`report.html`,展示交互式图表分析包大小分布。为优化可采用代码分割、Tree Shaking、压缩插件、加载器优化、模块懒加载、代码预热、提取公共库、使用CDN、图片优化、利用缓存、避免重复模块、使用Source Maps、优化字体和图标、避免全局样式污染以及优化HTML输出等策略。
162 3
Webpack 中 HMR 插件的工作原理
【10月更文挑战第23天】可以进一步深入探讨 HMR 工作原理的具体细节、不同场景下的应用案例,以及与其他相关技术的结合应用等方面的内容。通过全面、系统地了解 HMR 插件的工作原理,能够更好地利用这一功能,为项目的成功开发提供有力保障。同时,要不断关注技术的发展动态,以便及时掌握最新的 HMR 技术和最佳实践。
Webpack 动态加载的原理
【10月更文挑战第23天】Webpack 动态加载通过巧妙的机制和策略,实现了模块的按需加载和高效运行,提升了应用程序的性能和用户体验。同时,它也为前端开发提供了更大的灵活性和可扩展性,适应了不断变化的业务需求和技术发展。
webpack 原理
【10月更文挑战第23天】Webpack 原理是一个复杂但又非常重要的体系。它通过模块解析、依赖管理、加载器和插件的协作,实现了对各种模块的高效打包和处理,为现代前端项目的开发和部署提供了强大的支持。同时,通过代码分割、按需加载、热模块替换等功能,提升了应用程序的性能和用户体验。随着前端技术的不断发展,Webpack 也在不断演进和完善,以适应不断变化的需求和挑战。
|
4月前
webpack——通过webpack-bundle-analyzer分析项目包占比情况
webpack——通过webpack-bundle-analyzer分析项目包占比情况
41 2
webpack——通过webpack-bundle-analyzer分析项目包占比情况
手写一个简易bundler打包工具带你了解Webpack原理
该文章通过手写一个简易的打包工具bundler,帮助读者理解Webpack的工作原理,包括模块解析、依赖关系构建、转换源代码以及生成最终输出文件的整个流程。
Webpack 模块解析:打包原理、构造形式、扣代码补参数和全局导出
Webpack 模块解析:打包原理、构造形式、扣代码补参数和全局导出
204 1
webpack热更新原理
Webpack的Hot Module Replacement(HMR)提升开发效率,无需刷新页面即可更新模块。开启HMR需在配置中设`devServer.hot: true`。Webpack构建时插入HMR Runtime,通过WebSocket监听并处理文件变化。当模块改变,Webpack发送更新到浏览器,HMR Runtime找到对应模块进行热替换,保持应用状态。开发者可利用`module.hot` API处理热替换逻辑。
深入理解 Webpack 热更新原理:提升开发效率的关键
深入理解 Webpack 热更新原理:提升开发效率的关键
AI助理

阿里云 AI 助理已上线!

快来体验一下吧。