進擊webpack 4 (基礎篇一)

主題

本文爲webpack的基礎部分, 旨在如何從0搭建一個工程環境,並簡單介紹打包之後生成什麼代碼, 並且介紹webpack的常用的各種loader,plugin的配置 跟解決了什麼問題 本篇爲第一篇

項目初始化

安裝webpack

yarn init -y

個人比較喜歡用yarn初始化項目 完成後

yarn add webpack webpack-cli -D

再在目錄裏新建一個src 文件用於放我們的源代碼,src創建一個index.js作爲本次的入口文件 index.js 隨便輸入點什麼

clipboard.png
在當前目錄下直接運行

npx webpack 

clipboard.png

警告我們需要配置一個mode指明是生產環境還是開發環境

打包成功 並且在目錄下生成一個dist文件

npx 會去找node_modules/.bin/webpack.cmd 文件

clipboard.png

這個文件就做了一個判斷 判斷當前目錄下有沒有node.exe 有就執行當前目錄下的webpack.js 沒有用node執行上一級的webpack.js
webpack.js 會去找webpack-cli.js
在webpack-cli的文件目錄下可以找到config-yargs.js 配置文件 其中一段代碼寫明瞭要求什麼配置文件

.options({
            config: {
                type: "string",
                describe: "Path to the config file",
                group: CONFIG_GROUP,
                defaultDescription: "webpack.config.js or webpackfile.js",
                requiresArg: true
            },

這裏講明webpack默認配置文件需取名webpack.config.js 或者webpackfile.js ,
所以說,我們如果需要用自定義的名字去配置, 需要在命令行裏自行添加config 指定webpack用哪個配置去打包
如:

npx webpack --config [webpack-config的path]
  

打包之後的文件

在項目根目錄下新建文件webpack.config.js 並且導出去

const path = require('path')
module.exports = {
    mode:'development',  // 指定生產還是開發
    entry:'./src/index.js', // 入口文件
    output:{
        filename:'bundle.js', // 打包後的文件名
        path:path.resolve(__dirname,'./dist')  // 這裏需指定一個絕對路徑 我們需要node的path模塊去解析路徑
    }
}

再執行npx webpack

clipboard.png

看看這個bundle.js 長什麼樣子

clipboard.png

暫時不管__webpack_require__上的屬性 簡寫下就是

clipboard.png

一個自執行函數傳入一個obj 並且在裏面自己定義了一個require方法 返回require的執行結果

obj的key是打包文件的path路徑, value是一個函數 , 方法體是用eval執行index.js內部的代碼。

重點就是require做了什麼

clipboard.png

moduleId 就是__webpack_require__.s = './src/index.js'

定義了一個緩存 {'./src/index.js':...} 如果存在,也就是打包過了, 則直接返回,如果沒有則創建一個對象

{
    i:moduleId,  // 模塊的標識
    l:false, // 表示是否打包過
    exports:{}
}

並且引用給module,
然後用modules[moduleId].call 執行 modules 就是最外部傳入的那個自執行函數的參數obj{'path':代碼塊}

這段代碼就是說 執行這個obj的代碼塊,上下文指向module.exports, 傳入module,module.exports,跟require函數做參數

(function(module, exports) {  // module對應傳入的module(installedModules[moduleId]) ,exports對應module.exports
      eval("console.log('webpack')\n\n//# sourceURL=webpack:///./src/index.js?");
  })  

這段代碼執行了就是輸出了'webpack'

modules[moduleId].call做的事就是執行傳入模塊moduleId對應的代碼而已

注: 如果此時index.js 內部有import 之類導入其他的模塊 其他的模塊也會解析成obj的key跟value格式 他會遞歸去用require解析

比如在index.js 裏 import a from './a.js' 他的value是這樣的

function(module, exports, require) {

"use strict";
eval("require.r(exports); 
    var a = require(\"./src/a.js\");   // a是require執行後返回的module.exports
    var a_default = require.n(a);  // 返回的是獲取模塊的函數
    console.log('webpack')");
 }

clipboard.png

require.r 就是在exports上定義了個屬性作爲標識

clipboard.png

require.n就是執行了require.d 並且返回了一個獲取模塊的方法,

clipboard.png

require.d 就是在此函數上添加了 'a', 當訪問getter.a 的時候執行getter

最後:
這樣層層遞歸 一層層打包 最終生成module.exports 返回

module.l 改變true 表示當前這個module已經打包完成 最後返回module.exports

下一節預告:webpack.config.js的配置

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章