主題
本文爲webpack的基礎部分, 旨在如何從0搭建一個工程環境,並簡單介紹打包之後生成什麼代碼, 並且介紹webpack的常用的各種loader,plugin的配置 跟解決了什麼問題 本篇爲第一篇
項目初始化
安裝webpack
yarn init -y
個人比較喜歡用yarn初始化項目 完成後
yarn add webpack webpack-cli -D
再在目錄裏新建一個src 文件用於放我們的源代碼,src創建一個index.js作爲本次的入口文件 index.js 隨便輸入點什麼
在當前目錄下直接運行
npx webpack
警告我們需要配置一個mode指明是生產環境還是開發環境
打包成功 並且在目錄下生成一個dist文件
npx 會去找node_modules/.bin/webpack.cmd 文件
這個文件就做了一個判斷 判斷當前目錄下有沒有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
看看這個bundle.js 長什麼樣子
暫時不管__webpack_require__上的屬性 簡寫下就是
一個自執行函數傳入一個obj 並且在裏面自己定義了一個require方法 返回require的執行結果
obj的key是打包文件的path路徑, value是一個函數 , 方法體是用eval執行index.js內部的代碼。
重點就是require做了什麼
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')");
}
require.r 就是在exports上定義了個屬性作爲標識
require.n就是執行了require.d 並且返回了一個獲取模塊的方法,
require.d 就是在此函數上添加了 'a', 當訪問getter.a 的時候執行getter
最後:
這樣層層遞歸 一層層打包 最終生成module.exports 返回
module.l 改變true 表示當前這個module已經打包完成 最後返回module.exports
下一節預告:webpack.config.js的配置