当前位置: 首页 > article >正文

webpack——使用、分析打包代码

世上本无nodejs

js最初是在前端浏览器上运行的语言,js代码一旦脱离了浏览器环境,就无法被运行。直到nodejs的出现,我们在电脑上配置了node环境,就可以让js代码脱离浏览器,在node环境中运行。

浏览器不支持模块化

nodejs

nodejs可其他后端语言一样,支持模块化,享受了模块化的优点。

浏览器环境

可是浏览器并不支持nodejs的模块化语法

代码

//index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./module1.js"></script>
</head>
<body>
    <div id="btn">我是一个标题</div>
</body>
</html>
//module1.js
const module2=require('./module2')
console.log('module2',module2)
//module2.js
const a=1
console.log('module2',a)
module.exports.a=a

 目录结构

效果

Uncaught ReferenceError: require is not defined  
[Five Server] connecting...
[Five Server] connected.

webpack使用

webpack.config.js配置

//webpack.config.js
const path=require("path")
module.exports={
    mode:'development',
    entry:"./module1.js",
    output:{
        path:path.join(__dirname,"dist"),
        filename:"bundle.js"
    }
}

运行结果

webpack打包代码

例一commonJs

模块代码

//module1.js
const module2=require('./module2')
console.log('module2',module2)

 

打包代码bundle.js

//打包代码稍作修正一(功能不改变)
(() => {

  var __webpack_modules__ = ({
    "./module1.js":
    (__unused_webpack_module, __unused_webpack_exports, __webpack_require__) =>{
      eval(`
          const module2=__webpack_require__("./module2.js");
          console.log('module2',module2.a)
      `);
    },
    "./module2.js":
    (module) =>{
      eval(`
          const a=1;console.log('module2',a);
          module.exports.a=a
      `);
    }
  });

  var __webpack_module_cache__ = {};

  function __webpack_require__(moduleId) {
    var cachedModule = __webpack_module_cache__[moduleId];
    if (cachedModule !== undefined) {
      return cachedModule.exports;
    }
    var module = __webpack_module_cache__[moduleId] = {
      exports: {}
    };
    __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
    return module.exports;
  }

  var __webpack_exports__ = __webpack_require__("./module1.js");

 })();
//打包代码稍作修正二(功能不改变)
(function(){
  var cache = {};

  function require(modulePath) {
    // var cachedModule = cache[moduleId];
    // if (cachedModule !== undefined) {
    //   return cachedModule.exports;
    // }
    // var module = cache[moduleId] = {
    //   exports: {}
    // };
    module={
      exports:{}
    }
    modules[modulePath](module, module.exports, require);
    return module.exports;
  }

  var modules={
    ["./module1.js"](module, exports, require){
      eval(`
          const module2=require("./module2.js");
          console.log('module2',module2.a)
      `);
    },

    ["./module2.js"](module){
      eval(`
          const a=1;console.log('module2',a);
          module.exports.a=a
      `);
    }
  }

  var exports = require("./module1.js");
 })();

打包代码分析

①webpack实现了自己的require()函数

②webpack采用了立即执行函数

③webpac把各个模块的代码放到modules中

④各模块代码字符串形式存储,使用eval()函数执行

例二commonJs+ES6

模块代码

//module1.js
const module2=require('./module2')
console.log('module1',module2.a)
//module2.js
const module3=require('./utils/modules3')
console.log('module2',module3.a)
module.exports.a=module3.a
//module3.js
export const a=1
console.log('module3',a)

打包代码 

//打包代码稍作修正(功能不改变)
(() => { 
	var modules = ({
    "./module1.js":
    ((module, exports, require) => {
        eval(`
          const module2=require("./module2.js");
          console.log('module1',module2.a)
        `);
    }),

    "./module2.js":
    ((module, exports, require) => {
        eval(`
            const module3=require('./utils/modules3.js');
            console.log('module2',module3.a);
            module.exports.a=module3.a
        `);
    }),

    "./utils/modules3.js":
    ((module, exports, require) => {
        "use strict";
        eval(`
              require.r(exports);
              require.d(exports, {"a":() => (a)});
              const a=1;
              console.log('module3',a)
        `);
    })
  });

	var _cache = {};
	
	function require(moduleId) {		
		var cachedModule = _cache[moduleId];
		if (cachedModule !== undefined) {
			return cachedModule.exports;
		}
		var module = _cache[moduleId] = {	
			exports: {}
		};
		modules[moduleId](module, module.exports, require);
		return module.exports;
	}

	(() => {
		require.d = (exports, definition) => {
			for(var key in definition) {
				if(require.o(definition, key) && !require.o(exports, key)) {
					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
				}
			}
		};
	})();
	
	(() => {
		require.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
	})();
	
	(() => {	
		require.r = (exports) => {
			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
			}
			Object.defineProperty(exports, '__esModule', { value: true });
      console.log(exports)
      // debugger
		};
	})();

	var exports = require("./module1.js");
})()
;

打包代码分析

较例一,require函数对象上添加了d、r、o三个函数,它们的功能分析。

解开debugger的注释,控制台打印出

Module {__esModule: true, Symbol(Symbol.toStringTag): 'Module'}
    __esModule: true
    Symbol(Symbol.toStringTag): "Module"
   [[Prototype]]: Object

分析r函数功能

r函数向exports对象添加__esModule、Symbol(Symbol.toStringTag)两个属性,来标注采用了ES6模块化

注释debugger,控制台打印出

分析d。r函数功能

d。r函数向exports对象添加a属性

例三ES6

模块代码

//module1.js
import {a} from './module2'
console.log('module1',a)
export const a=1
console.log('module2',a)

打包代码

(() => {
  "use strict";
  var modules = ({

    "./module1.js":
      ((module, exports, require) => {

        eval(`require.r(exports);
              var _module2__WEBPACK_IMPORTED_MODULE_0__ = require("./module2.js");
              console.log('module1',_module2__WEBPACK_IMPORTED_MODULE_0__.a)
        `);
      }),

    "./module2.js":

      ((module, exports, require) => {

        eval(`require.r(exports);
              require.d(exports, {"a": () => (a)});
              const a=1;
              console.log('module2',a)`);

      })

  });
  
  var cache = {};

  function require(moduleId) {
    var cachedModule = cache[moduleId];
    if (cachedModule !== undefined) {
      return cachedModule.exports;
    }

    var module = cache[moduleId] = {

      exports: {}
    };


    modules[moduleId](module, module.exports, require);


    return module.exports;
  }


  (() => {

    require.d = (exports, definition) => {
      for (var key in definition) {
        if (require.o(definition, key) && !require.o(exports, key)) {
          Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
        }
      }
    };
  })();


  (() => {
    require.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
  })();


  (() => {
    require.r = (exports) => {
      if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
        Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
      }
      Object.defineProperty(exports, '__esModule', { value: true });
    };
  })();
  var exports = require("./module1.js");

})()
  ;

代码分析

和上面的打包结果差不多。


http://www.kler.cn/a/2654.html

相关文章:

  • Centos7 解决Maven scope=system依赖jar包没有打包到启动jar包中的问题(OpenCV-4.10)
  • 爬虫学习记录
  • 68.基于SpringBoot + Vue实现的前后端分离-心灵治愈交流平台系统(项目 + 论文PPT)
  • arcgis的合并、相交、融合、裁剪、联合、标识操作的区别和使用
  • 【VUE 指令学习笔记】
  • 【Logstash03】企业级日志分析系统ELK之Logstash 过滤 Filter 插件
  • python中socket智能调结用户连接数
  • 2万字带你精通MySQL索引
  • Vue:路由管理模式
  • 编写软件界面的方式
  • maven setting 配置
  • 制作简单进销存管理系统(C#)
  • 大数据专业应该怎么学习
  • python --获取内网IP地址
  • libvirt零知识学习5 —— libvirt源码编译安装(3)
  • ring_log环形日志-6M缓冲区_proc接口
  • Linux上用Samba建立共享文件夹并通过Linux测试
  • 蓝桥杯每日一真题——[蓝桥杯 2021 省 B] 杨辉三角形(二分+规律)
  • oracle查询表空间大小以及每个表所占空间的大小
  • 已解决AttributeError:module tensorflow no attribute app异常的正确解决方法,亲测有效!!!
  • HAL库 STM32 串口通信
  • 使用STM32F103ZE开发贪吃蛇游戏
  • 把python开发的web服务,打包成docker镜像的方法
  • 算法基础-回溯算法
  • 什么是Nginx
  • 【从零开始的C语言】操作符详解