1.为什么我们需要webpack
现代webapp开发自然离不开模块化的开发,现代mvvm框架,诸如angular, vue, react 让前端掀起了MVC的浪潮,所以,我们迫切的需要一个前端自动化构建的工具,用来做代码压缩,合并,打包等一系列的自动化的操作,在这之前比较流行的是grunt和gulp,自webpack初出头角之后,就收获了大量的关注。无疑,webpack将是前端自动化构建必不可少的工具。
2.正文
所以扯了这么多,webpack打包生成的一堆代码到底是啥。
首先来创建一个简单的demo
mkdir webapckTest
进而使用npm初始化
cd webpackTest
npm init
接下来等待完成就好了
接下来用npm安装一下webpack
npm install --save-dev webpack
下面分有依赖和没有依赖进行打包后生成的代码进行分析
2.1情形一:没有任何依赖的源文件 (CommonJS)
创建一个main.js ,用webpack进行打包,现在整个目录除开packge.json和node_modules就只有main.js这一个文件内容如下:
function sayHello(){
console.log('hello');
}
用webpack进行打包
webapck main.js main.bundle.js
ls一下目录,看到目录下出现了一个打包好的文件 main.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, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // 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 = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
function sayHello(){
console.log('hello');
}
/***/ })
/******/ ]);
为了能正常工作起来,webpack为我们打包的包文件,除了我们自己声明的模块(webpack 把 main.js抽象为一个模块),还有打包过程中生成的一些代码。
所以这些代码到底是啥??
先别急,慢慢来看
实际上打包过后生成的文件main.bundle.js也是一个模块,并且webpack默认为使用CommonJS模块规范(这点很重要,为什么很重要这里不深入追究,下面我们再谈)
现在我们来看一下上面打包的代码。
纵看上面打包文件生成的一大堆代码,实际上就是一个自执行函数
(function(modules) {
//...
})([function(module,exports){
function sayHello(){
console.log('hello');
}
}])
这个自执行函数接收一个参数,这个参数是一个模块数组,这个数组里存放我们打包的入口模块,以及这个模块的依赖模块,在这里我们没有依赖模块。
下面进入自执行函数的函数体一探究竟
首先声明了一个模块缓存对象,整个缓存对象是用来缓存加载进来的模块,需要注意的是,加载进来的模块和加载完毕的模块是两个概念