JavaScript中使用import 和require打包后实现原理分析

 更新时间:2018年03月07日 11:04:04   投稿:mrr  
这篇文章主要介绍了JavaScript中使用import 和require打包后实现原理分析,需要的朋友可以参考下

前言:

之前使用ES6写代码,webpack打包后上线,一点问题没有,也看过打包后的代码,长的很乱,也没敢看看咋回事,加载后就是能运行!

今天通过个例子理解一下打包前,和打包后的代码!

1.创建文件夹,并在里面创建两个文件夹,app文件夹和public文件夹,app文件夹用来存放原始数据和我们将写的JavaScript模块,public文件夹用来存放之后供浏览器读取的文件(包括使用webpack打包生成的js文件以及一个 index.html 文件)。接下来我们再创建三个文件:

  • index.html --放在public文件夹中;
  • Greeter.js -- 放在app文件夹中;
  • main.js -- 放在app文件夹中;

此时项目结构如下图所示


项目结构

我们在 index.html 文件中写入最基础的html代码,它在这里目的在于引入打包后的js文件(这里我们先把之后打包后的js文件命名为 bundle.js ,之后我们还会详细讲述)。

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="utf-8">
  <title>sample Project</title>
 </head>
 <body>
  <div id='root'>
  </div>
  <script src="bundle.js"></script>
 </body>
</html>

我们在 Greeter.js 中定义一个返回包含问候信息的 html 元素的函数,并依据CommonJS规范导出这个函数为一个模块:

// Greeter.js
exports.greet= function() {
 var greet = document.createElement('div');
 greet.textContent = "Hi there and greetings!";
 return greet;
};
exports.USER_INFO = "userInfo";

main.js 文件中我们写入下述代码,用以把 Greeter模块 返回的节点插入页面。

//main.js 
 let {greeter,USER_INFO} =require('./Greeter.js');
console.log(USER_INFO);
document.querySelector("#root").appendChild(greeter());

使用webpack打包后:

(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, {
        configurable: false,
        enumerable: true,
        get: getter
      });
    }
  };
  __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 = 0);
})
(
[
(function(module, exports, __webpack_require__) {
  //main.js
  let {
    greeter,
    USER_INFO
  } = __webpack_require__(1);
  console.log(USER_INFO);
  document.querySelector("#root").appendChild(greeter());
}),
(function(module, exports) {
  // Greeter.js
  exports.greet = function() {
    var greet = document.createElement('div');
    greet.textContent = "Hi there and greetings!";
    return greet;
  };
  exports.USER_INFO = "userInfo";
})
]);

首先最为层是包裹着立即执行函数(加粗的内容),参数是一个数组,数组中每一项是对应的模块,每个模块包裹在 (function(module, exports, __webpack_require__) {//模块内容 });

立即执行函数运行执行  return __webpack_require__(__webpack_require__.s = 0);

也就是执行传入数组中的第一个模块main.js

将运行后的每个模块挂载到installedModules = {}上,当下个需要这个模块直接返回当前模块,不在运行代码块了!

接下来将require改为import看看打包后的如何实现

我们将 Greeter.js的信息改为如下 :

// Greeter.js
export default function() {
 var greet = document.createElement('div');
 greet.textContent = "Hi there and greetings!";
 return greet;
};
export const USER_INFO = "userInfo";
main.js 文件中的代码,修改后
//main.js 
import greet,{USER_INFO} from './Greeter.js';
console.log(USER_INFO);
document.querySelector("#root").appendChild(greet());

然后我们再次打包:

(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, {
        configurable: false,
        enumerable: true,
        get: getter
      });
    }
  };
  __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 = 0);
})([(function(module, __webpack_exports__, __webpack_require__) {
  "use strict";
  Object.defineProperty(__webpack_exports__, "__esModule", {
    value: true
  });
  var __WEBPACK_IMPORTED_MODULE_0__Greeter_js__ = __webpack_require__(1);
  //main.js
  console.log(__WEBPACK_IMPORTED_MODULE_0__Greeter_js__["a"]);
  document.querySelector("#root").appendChild(Object(__WEBPACK_IMPORTED_MODULE_0__Greeter_js__["b"])());
}),
(function(module, __webpack_exports__, __webpack_require__) {
  "use strict";
  __webpack_exports__["b"] = (function() {
    var greet = document.createElement('div');
    greet.textContent = "Hi there and greetings!";
    return greet;
  });;
  const USER_INFO = "userInfo";
  __webpack_exports__["a"] = USER_INFO;
})]);

总结

以上所述是小编给大家介绍的JavaScript中使用import 和require打包后实现原理分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • TypeScript中使用类型断言的几种方式分享

    TypeScript中使用类型断言的几种方式分享

    在TypeScript中,类型断言用于告诉编译器某个变量的类型,这在我们确定变量的类型比编译器更准确时非常有用,本文给大家分享了几种TypeScript中使用类型断言方式,需要的朋友可以参考下
    2023-09-09
  • CocosCreator Typescript制作俄罗斯方块游戏

    CocosCreator Typescript制作俄罗斯方块游戏

    目前关于cocos开发俄罗斯方块的文章几乎寥寥无几,因此本文将主要介绍如何通过CocosCreator Typescript制作简单的俄罗斯方块游戏,代码具有一定价值,感兴趣的同学可以学习一下
    2021-11-11
  • 详解JavaScript函数对象

    详解JavaScript函数对象

    函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块,JavaScript 中的所有事物都是对象:字符串、数值、数组、函数,下面通过本文给大家介绍JavaScript函数对象,感兴趣的朋友一起学习吧
    2015-11-11
  • 在js代码拼接dom对象到页面上去的模板总结(必看)

    在js代码拼接dom对象到页面上去的模板总结(必看)

    下面小编就为大家带来一篇在js代码拼接dom对象到页面上去的模板总结(必看)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • JavaScript中的事件与异常捕获详析

    JavaScript中的事件与异常捕获详析

    这篇文章主要给大家介绍了关于JavaScript中事件与异常捕获的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-02-02
  • JavaScript高级程序设计 阅读笔记(十九) js表格排序

    JavaScript高级程序设计 阅读笔记(十九) js表格排序

    js表格排序实现代码,需要的朋友可以参考下
    2012-08-08
  • jQuery实现为控件添加水印文字效果(附源码)

    jQuery实现为控件添加水印文字效果(附源码)

    这篇文章主要介绍了jQuery实现为控件添加水印文字效果的方法,涉及jQuery插件jquery.tinywatermark.js的使用技巧,并提供了源码供读者下载参考,需要的朋友可以参考下
    2015-12-12
  • Babel 入门教程学习笔记

    Babel 入门教程学习笔记

    Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,本篇文章主要介绍了Babel 入门教程学习笔记,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • js键盘方向键 文章翻页跳转的效果[小说站常用已支持firefox]

    js键盘方向键 文章翻页跳转的效果[小说站常用已支持firefox]

    一些小说或图片类网站,为了方便大家阅读,往往会加入利用键盘方向键进行翻页、返回上一级、返回目录、回首页等功能。
    2009-05-05
  • JavaScript 数组常见操作技巧 (二)

    JavaScript 数组常见操作技巧 (二)

    这篇文章主要介绍了JavaScript 数组常见操作技巧,上一篇文章已经给大家分享了(一),下面紧接上一篇文章分享下面技巧,需要的小伙伴可以参考一下
    2022-02-02

最新评论