摘要:小尾巴最終返回了屬性掛載把引入的函數(shù)模塊全部暴露出來(lái)下面暴露了一些插件再通俗一點(diǎn)的解釋比如當(dāng)你你能調(diào)用文件下的方法這個(gè)和上面的不同在于上面的是掛在函數(shù)對(duì)象上的正題要想理解必須要理解再寫一遍地址我們先簡(jiǎn)單的理解它為一個(gè)通過(guò)注冊(cè)插件是插件的事
webpack.js小尾巴
const webpack = (options, callback) => { //... if (callback) { if (typeof callback !== "function") { throw new Error("Invalid argument: callback"); } if ( options.watch === true || (Array.isArray(options) && options.some(o => o.watch)) ) { const watchOptions = Array.isArray(options) ? options.map(o => o.watchOptions || {}) : options.watchOptions || {}; return compiler.watch(watchOptions, callback); } compiler.run(callback); } return compiler; }
最終返回了compiler
exports.version = version; // ...屬性掛載,把引入的函數(shù)模塊全部暴露出來(lái) webpack.WebpackOptionsDefaulter = WebpackOptionsDefaulter; webpack.WebpackOptionsApply = WebpackOptionsApply; webpack.Compiler = Compiler; webpack.MultiCompiler = MultiCompiler; webpack.NodeEnvironmentPlugin = NodeEnvironmentPlugin; // @ts-ignore Global @this directive is not supported webpack.validate = validateSchema.bind(this, webpackOptionsSchema); webpack.validateSchema = validateSchema; webpack.WebpackOptionsValidationError = WebpackOptionsValidationError;
下面暴露了一些插件
const exportPlugins = (obj, mappings) => { for (const name of Object.keys(mappings)) { Object.defineProperty(obj, name, { configurable: false, enumerable: true, get: mappings[name] }); } }; exportPlugins(exports, { AutomaticPrefetchPlugin: () => require("./AutomaticPrefetchPlugin"), BannerPlugin: () => require("./BannerPlugin"), CachePlugin: () => require("./CachePlugin")} )
再通俗一點(diǎn)的解釋:
比如當(dāng)你api.AutomaticPrefetchPlugin你能
調(diào)用AutomaticPrefetchPlugin文件下的方法
這個(gè)和上面的不同在于上面的是掛在webpack函數(shù)對(duì)象上的
要想理解Compiler.js
必須要理解tapable
再寫一遍 git地址
我們先簡(jiǎn)單的理解它為一個(gè)通過(guò)tap 注冊(cè)插件
call是run插件的事件流,里面還有一些異步的操作
Compiler整理如下
class Compiler extends Tapable { constructor(context) { super(); this.hooks = { //羅列一些出現(xiàn)頻率比較高的 shouldEmit: new SyncBailHook(["compilation"]), done: new AsyncSeriesHook(["stats"]), beforeRun: new AsyncSeriesHook(["compiler"]), run: new AsyncSeriesHook(["compiler"]), emit: new AsyncSeriesHook(["compilation"]), afterEmit: new AsyncSeriesHook(["compilation"]), thisCompilation: new SyncHook(["compilation", "params"]), compilation: new SyncHook(["compilation", "params"]), beforeCompile: new AsyncSeriesHook(["params"]), compile: new SyncHook(["params"]), make: new AsyncParallelHook(["compilation"]), afterCompile: new AsyncSeriesHook(["compilation"]), watchRun: new AsyncSeriesHook(["compiler"]), //... } // 添加事件流 this._pluginCompat.tap("Compiler", options => { switch (options.name) { case "additional-pass": case "before-run": case "run": case "emit": case "after-emit": case "before-compile": case "make": case "after-compile": case "watch-run": options.async = true; break; } }); } watch(){ //... } run(callback) { //... } // 清除輸入文件系統(tǒng) purgeInputFileSystem() { if (this.inputFileSystem && this.inputFileSystem.purge) { this.inputFileSystem.purge(); } } emitAssets(compilation, callback) { //... } createChildCompiler( compilation, compilerName, compilerIndex, outputOptions, plugins ) { //... } //... compile(callback){ //... } }
和tapable用法一個(gè)模子里刻出來(lái)的,我們仔細(xì)的研究run函數(shù)
compiler.js是webpack 的核心
run(callback) { //如果正在running,返回報(bào)錯(cuò)處理 if (this.running) return callback(new ConcurrentCompilationError()); //running調(diào)用finalCallback const finalCallback = (err, stats) => { this.running = false; if (callback !== undefined) return callback(err, stats); }; //記錄初始化running時(shí)間 const startTime = Date.now(); //設(shè)置running標(biāo)志,防止多次running this.running = true; //正在編譯 const onCompiled = (err, compilation) => { //如果報(bào)錯(cuò),編譯結(jié)束 if (err) return finalCallback(err); //如果沒有編譯完成 if (this.hooks.shouldEmit.call(compilation) === false) { // Stats模塊有1400行, // compiler.js是webpack 的核心,new Stats(compilation)是compiler.js的核心 const stats = new Stats(compilation); // stats對(duì)象掛載startTime,endTime stats.startTime = startTime; stats.endTime = Date.now(); // 異步調(diào)用完成事件流,running結(jié)束 this.hooks.done.callAsync(stats, err => { if (err) return finalCallback(err); return finalCallback(null, stats); }); return; } // 調(diào)用emitAsset方法,emitAsset主要負(fù)責(zé)寫入文件輸出文件,不影響我們先看編譯 this.emitAssets(compilation, err => { // 類似同上, 如果報(bào)錯(cuò),編譯結(jié)束 if (err) return finalCallback(err); // 如果需要額外的編譯,上次的沒編譯完成嗎
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/101228.html
摘要:打開是個(gè)構(gòu)造函數(shù),定義了一些靜態(tài)屬性和方法我們先看在插件下地址上面寫的解釋就跟沒寫一樣在文件下我們看到輸出的一些對(duì)象方法每一個(gè)對(duì)應(yīng)一個(gè)模塊而在下引入的下面,我們先研究引入的對(duì)象的英文單詞解釋,除了最常用的點(diǎn)擊手勢(shì)之外,還有一個(gè)意思是水龍頭進(jìn) 打開compile class Compiler extends Tapable { constructor(context) { ...
摘要:執(zhí)行完成后會(huì)返回如下圖的結(jié)果,根據(jù)返回?cái)?shù)據(jù)把源碼和存儲(chǔ)在的屬性上的回調(diào)函數(shù)中調(diào)用類生成,并根據(jù)生成依賴后回調(diào)方法返回類。 webpack設(shè)計(jì)模式 一切資源皆Module Module(模塊)是webpack的中的關(guān)鍵實(shí)體。Webpack 會(huì)從配置的 Entry 開始遞歸找出所有依賴的模塊. 通過(guò)Loaders(模塊轉(zhuǎn)換器),用于把模塊原內(nèi)容按照需求轉(zhuǎn)換成新模塊內(nèi)容. 事件驅(qū)動(dòng)架構(gòu) we...
摘要:接下來(lái)我看看一下函數(shù)我們先按照分支走為讀取是里的對(duì)象,饒了這大的一個(gè)圈子,那么接下來(lái)一起來(lái)看一看對(duì)你的輸入配置做了怎么樣的處理吧 打開webpeck-cli下的convert-argv.js文件 // 定義options為空數(shù)組 const options = []; // webpack -d 檢查 -d指令 if (argv.d) { //... } ...
摘要:我們打開根據(jù)上次所返回的這個(gè)因?yàn)橛辛松洗蔚幕A(chǔ),比較容易讀了大體邏輯是這樣的先定義一個(gè)空對(duì)象同上次的一個(gè)邏輯,還是一個(gè)目前的方式只有一個(gè)滿足如果滿足的會(huì)執(zhí)行一系列函數(shù)這個(gè)函數(shù)直接結(jié)果是的影響是打比如如果滿足的話當(dāng)你的時(shí)候就會(huì)在頁(yè)面上出 我們打開bin/cli.js根據(jù)上次所返回的Options processOptions(options)這個(gè)因?yàn)橛辛松洗蔚幕A(chǔ),比較容易讀了,大體邏輯...
摘要:還做了處理,是之所以能根據(jù)變化自己更新的核心,好凌亂,我們先從那個(gè)坑跳出來(lái)進(jìn)入這個(gè)大坑進(jìn)入這個(gè)頁(yè)面看到前面一大堆的模塊引入,已經(jīng)給跪了,但是馬馬虎虎的完成也比放棄好前面一大堆的引入,主要是下和文件夾下的模塊父類就只是定義了接口主要核心在方法 NodeEnvironmentPlugin還做了watch處理,NodeWatchFileSystem是webpack之所以能根據(jù)變化自己更新的核...
閱讀 2568·2021-11-11 11:01
閱讀 3472·2021-10-11 10:57
閱讀 2821·2021-09-30 09:46
閱讀 3636·2021-07-26 23:38
閱讀 1726·2019-08-29 12:22
閱讀 782·2019-08-29 11:28
閱讀 2491·2019-08-26 14:04
閱讀 3213·2019-08-23 18:34