安装

安装本地webpack
webpack、webpack-cli

npm install webpack webpack-cli -D

webpack可以进行0配置

如果只是安装了webpack,不做任何配置,默认会去找node-modules->bin->webpack文件进行打包编译。webpack文件里有对webpack-cli的依赖描述,一般这两个需要一起安装。

输出后的结果(js模块)

运行:

npx webpack

可以生成打包后的js文件,这些文件默认是进行压缩和优化的,原因是mode配置的是production

Code Runner 插件可以在VsCode里实施运行代码)

手动配置webpack

默认配置文件:webpack.config.js

通过create-react-app创建的项目,用npm run eject生成的webpack文件config->webpack.config.js

把原有的webpack.config.js文件删除,在项目根目录下创建一个新的webpack.config.js文件,尝试手动写一个webpack配置。

1、编译单个JS文件

1.新建了一个aaa.js

console.log("first js maomao")

里面只写了一行代码。

2.配置webpack.config.js

//webpack 是用nodejs写的,是node语法

let path = require('path')//node提供的 相对路径 转 绝对路径 的插件

console.log(path.resolve(__dirname, "src"))
module.exports = {
  mode:"development",//模式,两种模式,产线模式"production"、开发模式"development"。产线模式会把编译文件进行压缩优化,代码变成一行。
  entry: "./src/aaa.js",//入口,相对路径
  output: {
    filename: "bundle.js",//打包后的文件名
    path: path.resolve(__dirname, "dist"),//打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
  }
}

该配置的作用是把./src/aaa.js文件编译成./dist/bundle.js

3.运行

npx webpack

需要先安装:webpack、webpack-cli

4.查看编译结果bundle.js

(function () { // webpackBootstrap
  var __webpack_modules__ = ({
    "./src/aaa.js"://key,模块的路径
      (function () {//value,执行函数
        eval("console.log(\"first js maomao\")\n\n//# sourceURL=webpack://mm_webpack/./src/aaa.js?");
      })
  });
  var __webpack_exports__ = {};
  __webpack_modules__["./src/aaa.js"]();
})();

删除无用注释之后,最后编译出的文件就是这个。

文件大致含义是:

定义了一个模块变量__webpack_modules__,里面包含被打包的文件路径和对应的执行函数,执行行数会找到被打包的文件绝对路径进行执行。

然后调用__webpack_modules__["./src/aaa.js"]();执行这个执行函数。

最后一行就是执行最外层的function方法。

这是单个文件,下面看看多文件(模块)引用的打包情况

2、编译多个JS文件

前面两步与编译当个文件一致。

1.新增一个bbb.js文件

console.log("bbb js maomao")

只有一行代码。

aaa.js代码:

import './bbb.js'
console.log("first js maomao")

aaa.js文件引用了bbb.js文件。

2.配置webpack.config.js

编译单个JS文件配置。

3.运行

npx webpack

需要先安装:webpack、webpack-cli

4.查看编译结果bundle.js

(function () { // webpackBootstrap
  var __webpack_modules__ = ({
    "./src/aaa.js":
      (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
        "use strict";
        eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _bbb_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bbb.js */ \"./src/bbb.js\");\n/* harmony import */ var _bbb_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_bbb_js__WEBPACK_IMPORTED_MODULE_0__);\n\nconsole.log(\"first js maomao\")\n\n//# sourceURL=webpack://mm_webpack/./src/aaa.js?");
      }),
    "./src/bbb.js":
      (function () {
        eval("console.log(\"bbb js maomao\")\n\n//# sourceURL=webpack://mm_webpack/./src/bbb.js?");
      })
  });
  /************************************************************************/
  // 定义了一个缓存
  var __webpack_module_cache__ = {};
  // 实现了require方法,该方法会被浏览器执行
  function __webpack_require__(moduleId) {
    //检查是否在缓存
    var cachedModule = __webpack_module_cache__[moduleId];
    if (cachedModule !== undefined) {
      //检查在缓存就直接返回
      return cachedModule.exports;
    }
    //如果不在缓存,新建一个
    var module = __webpack_module_cache__[moduleId] = {
      //定义一个初始值
      exports: {}
    };

    //执行模块加载方法
    //该方法对应的执行方法里又会执行引用的‘bbb.js’文件对应的加载方法
    //依此类推,最后会寻找并加载所有文件
    __webpack_modules__[moduleId](module, module.exports, __webpack_require__);

    // 返回执行结果
    return module.exports;
  }

  /************************************************************************/
  /* webpack/runtime/compat get default export */
  !function () {
    // getDefaultExport function for compatibility with non-harmony modules
    __webpack_require__.n = function (module) {
      var getter = module && module.__esModule ?
        function () { return module['default']; } :
        function () { return module; };
      __webpack_require__.d(getter, { a: getter });
      return getter;
    };
  }();

  /* webpack/runtime/define property getters */
  !function () {
    // define getter functions for harmony exports
    __webpack_require__.d = function (exports, definition) {
      for (var key in definition) {
        if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
          Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
        }
      }
    };
  }();

  /* webpack/runtime/hasOwnProperty shorthand */
  !function () {
    __webpack_require__.o = function (obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
  }();

  /* webpack/runtime/make namespace object */
  !function () {
    // 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 });
    };
  }();

  //最终 执行加载入口文件并返回结果,即为加载所有文件
  var __webpack_exports__ = __webpack_require__("./src/aaa.js");//入口模块
})();

文件大致含义是:

定义了一个模块变量__webpack_modules__,里面包含所有被打包的文件路径和对应的执行函数,执行行数会找到被打包的文件绝对路径进行执行。

其中aaa.js对应的执行函数里面会包含执行bbb.js对应的函数。

另外,在__webpack_require__里会缓存编译加载的结果,如果第二次执行时如果缓存有,就直接从缓存中取编译数据。

然后调用__webpack_modules__["./src/aaa.js"]();执行入口执行函数。

最后一行就是执行最外层的function方法。

3、总结:

  • 单个文件的编译,执行方法是加载自己本身;
  • 多个文件编译,执行方法里会包含所有引入的文件的编译执行,如此递归遍历,可以加载完所有文件。

4、手动指定webpack文件

npx webpack --config webpack.config.my.js

--config可以手动指定webpack配置文件

5、脚本运行webpack文件

1.package.json文件中配置:

  "scripts": {
    "build": "webpack --config webpack.config.my.js",
  },

2.运行

npm run build

or:

package.json配置成:

  "scripts": {
    "build": "webpack",
  },

运行时传参数:

npm run build -- --config webpack.config.my.js

中间的--代表其后的值作为参数传递,如果没有--npm run build后面的值不会被认为是参数。