【webpack篇】原理

【webpack篇】原理

以前每件事都差很少,直到如今才發現差不少。

如今才發現理清一件事的原委是多麼快樂的一件事,咱們共同勉勵。javascript

懶得扯淡,直接正題css

不基於例子的講原理都是扯淡,知乎同樣的舉例都是賣弄html

要說如今的模塊打包確定用的最多的就是webpack,下面由淺入深的講一下它的原理,在這裏舉例打包js和css模塊。java

ps: 基於webpack 4node

打包構建解析

示例環境依賴及部分代碼

依賴

  • "clean-webpack-plugin": "^0.1.18",
  • "css-loader": "^0.28.10",
  • "html-webpack-plugin": "^3.0.4",
  • "style-loader": "^0.20.2",
  • "webpack": "^4.0.1",
  • "webpack-cli": "^2.0.10"

webpack.config.js

const path = require('path');
const webpack = require('webpack');
//用於插入html模板
const HtmlWebpackPlugin = require('html-webpack-plugin');
//清除輸出目錄,省得每次手動刪除
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    mode: 'development',
    entry: {
        index: path.join(__dirname, 'index.js'),
    },
    output: {
        path: path.join(__dirname, '/dist'),
        filename: 'js/[name].[chunkhash:4].js'
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
        })
    ],
    module: {
        rules: [{
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        }]
    }
};

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webpack-learn</title>
</head>
<body>
    <div class="wrapper">webpack-learn</div>
</body>
</html>

index.css

.wrapper {
    font-size: 20px;
    color: #f00;
}

js 文件

// index.js
const test = require('./src/js/test');
require('./src/css/index.css');
console.log(test);
// test.js
const str = 'test is loaded';
module.exports = str;

頁面結構以下:webpack

clipboard.png

運行

$ webpack

打包結果分析

查看 dist/js/index.[chunkhash:4].js 文件,發現文件有點大,不知道從何處看起,那麼咱們把入口js文件進行剝繭抽絲,清空,看一下,最簡單的打包後的文件。web

/******/ (function(modules) { // webpackBootstrap
/******/     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__.r = function(exports) {
/******/         Object.defineProperty(exports, '__esModule', { value: true });
/******/     };
/******/     __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 = "./index.js");
/******/ })
/******/ ({
/***/ "./index.js":
/***/ (function(module, exports) {
eval("//# sourceURL=webpack:///./index.js?");
/***/ })
/******/ });

發覺其打包產出是一個FFII,參數爲由模塊名和模塊文件處理成的函數組成的對象,由此,咱們能夠猜想 webpack在打包時作了模塊文件到函數的轉換。咱們再把入口文件內容恢復,再看一下打包結果的FFII參數。數組

clipboard.png

除了 src/js/test.jssrc/css/index.css 模塊之外還有 node_modules 裏面的 css-loaderstyle-loader。由此,咱們能夠猜想 webpack在打包時作了模塊依賴的解析和深度遍歷模塊的依賴bash

相關文章
相關標籤/搜索