首页 技术 正文
技术 2022年11月21日
0 收藏 414 点赞 4,940 浏览 9273 个字

一:什么是Scope Hoisting? 它有什么作用?
Scope Hoisting 它可以让webpack打包出来的代码文件更小,运行更快,它可以被称作为 “作用域提升”。是在webpack3中提出来的,当然现在webpack4也是支持的。

在介绍之前,我们还是来和之前一样,看看我们项目整个目录架构如下:

### 目录结构如下:
demo1 # 工程名
| |--- dist # 打包后生成的目录文件
| |--- node_modules # 所有的依赖包
| |--- app
| | |---index
| | | |-- views # 存放所有vue页面文件
| | | | |-- home.vue
| | | | |-- index.vue
| | | | |-- xxx.vue
| | | |-- components # 存放vue公用的组件
| | | |-- js # 存放js文件的
| | | |-- app.js # vue入口配置文件
| | | |-- router.js # 路由配置文件
| |--- views
| | |-- index.html # html文件
| |--- webpack.config.js # webpack配置文件
| |--- .gitignore
| |--- README.md
| |--- package.json
| |--- .babelrc # babel转码文件

首先我们在 app/index/js 下新建 index.js 代码如下:

export default 'xxxx';

然后在我们的入口文件 app/index/app.js 代码如下:

import index from './js/index';
console.log(index);

然后运行 npm run build 打包后,bundle.js 代码如下:

/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // 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 = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./app/index/app.js");
/******/ })
/************************************************************************/
/******/ ({/***/ "./app/index/app.js":
/*!**************************!*\
!*** ./app/index/app.js ***!
\**************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _js_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./js/index */ "./app/index/js/index.js");console.log(_js_index__WEBPACK_IMPORTED_MODULE_0__["default"]);/***/ }),/***/ "./app/index/js/index.js":
/*!*******************************!*\
!*** ./app/index/js/index.js ***!
\*******************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {"use strict";
__webpack_require__.r(__webpack_exports__);/* harmony default export */ __webpack_exports__["default"] = ('xxxx');/***/ })/******/ });
//# sourceMappingURL=bundle.js.map

如上代码我们没有使用 Scope Hoisting 功能,输出如上那么多代码,下面我们来看看引入 Scope Hoisting 功能,打包后的代码;

要使用 Scope Hoisting 功能,首先我们需要 的是我们JS文件都使用ES6的语法来编写的,否则它是不会生效的。还是上面的代码不变。

使用 Scope Hoisting(编写的代码需要支持ES6规范)

Scope Hoisting 是webpack内置的功能,只要配置一个插件即可,如下在webpack.config.js 代码如下配置:

module.exports = {
plugins: [
// 开启 Scope Hoisting 功能
new webpack.optimize.ModuleConcatenationPlugin()
]
}

然后执行npm run build 打包后的bundle.js 代码如下:

/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // 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 = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./app/index/app.js");
/******/ })
/************************************************************************/
/******/ ({/***/ "./app/index/app.js":
/*!**************************************!*\
!*** ./app/index/app.js + 1 modules ***!
\**************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {"use strict";// CONCATENATED MODULE: ./app/index/js/index.js/* harmony default export */ var js = ('xxxx');
// CONCATENATED MODULE: ./app/index/app.jsconsole.log(js);/***/ })/******/ });
//# sourceMappingURL=bundle.js.map

如上代码可以看到,开启 Scope Hoisting后,函数声明由两个变成了一个,app/index/js/index.js 代码直接被注入到 app.js里面去了,如上代码 var js = (‘xxx’);

因此 启用 Scope Hoisting的优点如下:
1. 代码体积会变小,因为函数声明语句会产生大量代码,但是第二个没有函数声明。
2. 代码在运行时因为创建的函数作用域减少了,所以内存开销就变小了。

具体的可以看官网(https://webpack.js.org/plugins/module-concatenation-plugin/)

但是对于有很多第三方库并没有使用ES6模块语法的代码,webpack它会降级处理这些非ES6编写的代码,不使用 Scope Hoisting 优化。

因此在webpack中还需要加上如下代码配置:

module.exports = {
resolve: {
// 针对 Npm 中的第三方模块优先采用 jsnext:main 中指向的 ES6 模块化语法的文件
mainFields: ['jsnext:main', 'browser', 'main']
},
};

我们可以在启动webpack时候带上 –display-optimization-bailout 参数,在输出日志中就会包含类似如下的日志:如下图

深入浅出的webpack4构建工具—Scope Hoisting(十六)

其中的 ModuleConcatenation bailout 告诉了你哪个文件因为什么原因导致了降级处理。

因此在webpack中所有的配置代码如下:

module.exports = {
resolve: {
// 针对 Npm 中的第三方模块优先采用 jsnext:main 中指向的 ES6 模块化语法的文件
mainFields: ['jsnext:main', 'browser', 'main']
},
plugins: [
// 开启 Scope Hoisting 功能
new webpack.optimize.ModuleConcatenationPlugin()
]
};
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,962
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,486
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,331
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,114
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,747
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,781