成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

淺析webpack源碼之Compiler.js模塊(八)

PumpkinDylan / 800人閱讀

摘要:小尾巴最終返回了屬性掛載把引入的函數(shù)模塊全部暴露出來下面暴露了一些插件再通俗一點的解釋比如當(dāng)你你能調(diào)用文件下的方法這個和上面的不同在于上面的是掛在函數(shù)對象上的正題要想理解必須要理解再寫一遍地址我們先簡單的理解它為一個通過注冊插件是插件的事

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ù)模塊全部暴露出來
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")}
)

再通俗一點的解釋:

比如當(dāng)你api.AutomaticPrefetchPlugin你能
調(diào)用AutomaticPrefetchPlugin文件下的方法

這個和上面的不同在于上面的是掛在webpack函數(shù)對象上的

Compiler.js正題

要想理解Compiler.js
必須要理解tapable
再寫一遍 git地址

我們先簡單的理解它為一個通過tap 注冊插件
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用法一個模子里刻出來的,我們仔細(xì)的研究run函數(shù)

compiler.js是webpack 的核心

run(callback) {
   //如果正在running,返回報錯處理
    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時間
    const startTime = Date.now();
    //設(shè)置running標(biāo)志,防止多次running
    this.running = true;
    
    //正在編譯
    const onCompiled = (err, compilation) => {
        //如果報錯,編譯結(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對象掛載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 => {
            // 類似同上, 如果報錯,編譯結(jié)束
            if (err) return finalCallback(err);
            // 如果需要額外的編譯,上次的沒編譯完成嗎           
               
                                           
                       
                 

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/101228.html

相關(guān)文章

  • 淺析webpack源碼Tapable粗解(五)

    摘要:打開是個構(gòu)造函數(shù),定義了一些靜態(tài)屬性和方法我們先看在插件下地址上面寫的解釋就跟沒寫一樣在文件下我們看到輸出的一些對象方法每一個對應(yīng)一個模塊而在下引入的下面,我們先研究引入的對象的英文單詞解釋,除了最常用的點擊手勢之外,還有一個意思是水龍頭進 打開compile class Compiler extends Tapable { constructor(context) { ...

    Arno 評論0 收藏0
  • FE.SRC-webpack原理梳理

    摘要:執(zhí)行完成后會返回如下圖的結(jié)果,根據(jù)返回數(shù)據(jù)把源碼和存儲在的屬性上的回調(diào)函數(shù)中調(diào)用類生成,并根據(jù)生成依賴后回調(diào)方法返回類。 webpack設(shè)計模式 一切資源皆Module Module(模塊)是webpack的中的關(guān)鍵實體。Webpack 會從配置的 Entry 開始遞歸找出所有依賴的模塊. 通過Loaders(模塊轉(zhuǎn)換器),用于把模塊原內(nèi)容按照需求轉(zhuǎn)換成新模塊內(nèi)容. 事件驅(qū)動架構(gòu) we...

    cfanr 評論0 收藏0
  • 淺析webpack源碼convert-argv模塊(二)

    摘要:接下來我看看一下函數(shù)我們先按照分支走為讀取是里的對象,饒了這大的一個圈子,那么接下來一起來看一看對你的輸入配置做了怎么樣的處理吧 打開webpeck-cli下的convert-argv.js文件 // 定義options為空數(shù)組 const options = []; // webpack -d 檢查 -d指令 if (argv.d) { //... } ...

    lemon 評論0 收藏0
  • 淺析webpack源碼processOptions處理Options以及入口函數(shù)(三)

    摘要:我們打開根據(jù)上次所返回的這個因為有了上次的基礎(chǔ),比較容易讀了大體邏輯是這樣的先定義一個空對象同上次的一個邏輯,還是一個目前的方式只有一個滿足如果滿足的會執(zhí)行一系列函數(shù)這個函數(shù)直接結(jié)果是的影響是打比如如果滿足的話當(dāng)你的時候就會在頁面上出 我們打開bin/cli.js根據(jù)上次所返回的Options processOptions(options)這個因為有了上次的基礎(chǔ),比較容易讀了,大體邏輯...

    doodlewind 評論0 收藏0
  • 淺析webpack源碼WebpackOptionsApply 模塊(七)

    摘要:還做了處理,是之所以能根據(jù)變化自己更新的核心,好凌亂,我們先從那個坑跳出來進入這個大坑進入這個頁面看到前面一大堆的模塊引入,已經(jīng)給跪了,但是馬馬虎虎的完成也比放棄好前面一大堆的引入,主要是下和文件夾下的模塊父類就只是定義了接口主要核心在方法 NodeEnvironmentPlugin還做了watch處理,NodeWatchFileSystem是webpack之所以能根據(jù)變化自己更新的核...

    AaronYuan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<