美文网首页Front End
[FE] webpack v4.20.2 源码解析(二):加载资

[FE] webpack v4.20.2 源码解析(二):加载资

作者: 何幻 | 来源:发表于2018-10-17 12:25 被阅读2次

    总览

    1. webpack命令行工具的源码位置

    (1)使用which命令查看CLI的本地地址

    $ which webpack
    ~/.nvm/versions/node/v8.12.0/bin/webpack
    

    (2)原身
    事实上,这个位置的webpack只是一个软链接(symbolic link)。

    $ l ~/.nvm/versions/node/v8.12.0/bin/
    webpack -> ../lib/node_modules/webpack/bin/webpack.js
    

    我们看到,webpack CLI的原身在

    ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack/bin/webpack.js
    

    2. webpack/bin/webpack.js(v4.20.2)

    上一节我们知道了,webpack命令的原身在这里,

    ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack/bin/webpack.js
    

    我们打开这个文件,直接阅读源码。

    2.1 CLI检查

    我们看到webpack.js 第84行,对CLI工具进行了检查,

    if (installedClis.length === 0) {
    

    如果没有安装webpack-cliwebpack-command,就会报错。

    2.2 加载CLI

    webpack.js 第149-158行
    会加载命令行工具。

    require(path.resolve(
        path.dirname(pkgPath),
        pkg.bin[installedClis[0].binName]
    ));
    

    2.3 文件地址

    我们使用上文第4节的办法,借用debug模块,写入日志。
    得到的文件加载地址如下,

    debug-webpack webpack webpack.js cliPath: ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack-cli/bin/cli.js +0ms
    

    即,webpack命令行工具,最终会加载这个文件,

    ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack-cli/bin/cli.js
    

    源码可以点这里,cli.js(webpack-cli v3.1.2)。


    3. webpack-cli/bin/cli.js 源码分析(v3.1.2)

    3.1 加载webpack模块

    cli.js 第436行,会加载webpack模块。
    而该模块实际的本地路径为,

    ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack
    

    我们查看该模块的package.json中的main字段,

    "main": "lib/webpack.js"
    

    得知实际加载的是webpack/lib/webpack.js文件。

    3.2 调用webpack,返回一个compiler对象

    cli.js 第441行
    会调用webpack,返回一个compiler对象。

    compiler = webpack(options);
    

    3.3 调用compiler.run

    cli.js 第533行
    会调用compiler.run,执行实际的webpack逻辑。

    } else compiler.run(compilerCallback);
    

    我们修改一下这行代码,加上log,
    (别忘了,按照第一篇中的办法,安装debug模块。下面使用的是,调用后返回的log函数)

    else {
        log('start: compiler.run');
        compiler.run(compilerCallback);
    }
    

    结果如下,

    debug-webpack webpack webpack.js cliPath: ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack-cli/bin/cli.js +0ms
    debug-webpack webpack-cli cli.js start: compiler.run +0ms
    

    4. webpack源码分析(v4.20.2)

    4.1 webpack/lib/Compiler.js

    按照第3.1节的分析,我们知道webpack-cli/bin/cli.js,加载了以下webpack模块,

    ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack
    

    然后调用了webpack()返回值compilerrun方法。
    我们查看webpack/lib/webpack.js 第39行

    compiler = new Compiler(options.context);
    

    得知compiler.run方法在webpack/lib/Compiler.js文件中。

    4.2 run 方法

    搜索以后发现,run方法在webpack/lib/Compiler.js 第198行

    run(callback) {
        ...
    }
    

    然后run 方法在第268行调用了this.compile

    this.compile(onCompiled);
    

    4.3 compile方法

    compile方法是Compiler的实例方法,在第527行

    compile(callback) {
        ...
    }
    

    然后在第536行,调用了this.hooks.make.callAsync

    this.hooks.make.callAsync(compilation, err => {
        ...
    });
    

    关于hooks的解析,我们放在下一篇,
    这里我们需要知道的是,
    this.hooks.make.callAsync调用的是某个插件中实现的hooks.make.tapAsync方法,

    compiler.hooks.make.tapAsync(
        "SingleEntryPlugin",
        (compilation, callback) => {
            const { entry, name, context } = this;
    
            const dep = SingleEntryPlugin.createDependency(entry, name);
            compilation.addEntry(context, dep, name, callback);
        }
    );
    

    通过全文搜索,我们可以看到,它的位置在这里,webpack/lib/SingleEntryPlugin.js 第40行

    其中compiler.hooks.make.tapAsync的第一个参数,SingleEntryPlugin,只是一个名字。
    具体的实现是它的第二个参数,

    (compilation, callback) => {
        ...
    }
    

    于是我们发现这里实际调用了compilation.addEntry
    写入日志,

    debug-webpack webpack webpack.js cliPath: ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack-cli/bin/cli.js +0ms
    debug-webpack webpack-cli cli.js start: compiler.run +0ms
    debug-webpack webpack Compiler.js start: this.hooks.make.callAsync +0ms
    debug-webpack webpack SingleEntryPlugin.js in: compiler.hooks.make.tapAsync +0ms
    debug-webpack webpack SingleEntryPlugin.js start: compilation.addEntry +0ms
    ...
    debug-webpack webpack Compiler.js end: this.hooks.make.callAsync +397ms
    

    我们在每个函数的调用之前,加入了start: xxx
    然后在函数内第一行加入了in: xxx
    再函数的回调函数中,加入了end: xxx

    (1)Compiler.js compile方法内部

    log('start: this.hooks.make.callAsync');
    this.hooks.make.callAsync(compilation, err => {
        log('end: this.hooks.make.callAsync');
    

    (2)SingleEntryPlugin.js apply方法内部

    compiler.hooks.make.tapAsync(
        "SingleEntryPlugin",
        (compilation, callback) => {
            log('in: compiler.hooks.make.tapAsync');
    

    4.4 compilation.addEntry

    compilation.addEntryCompilation对象的addEntry实例方法,
    不难发现,它位于webpack/lib/Compilation.js 第1027行

    addEntry(context, entry, name, callback) {
        ...
    }
    

    它内部调用了this._addModuleChain,然后_addModuleChain内部调用了moduleFactory.create
    moduleFactory.create会返回一个module对象,源码位于第943行

    我们在addEntrymoduleFactory.create前后写入log,

    debug-webpack webpack webpack.js cliPath: ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack-cli/bin/cli.js +0ms
    debug-webpack webpack-cli cli.js start: compiler.run +0ms
    debug-webpack webpack Compiler.js start: this.hooks.make.callAsync +0ms
    debug-webpack webpack SingleEntryPlugin.js in: compiler.hooks.make.tapAsync +0ms
    debug-webpack webpack SingleEntryPlugin.js start: compilation.addEntry +0ms
    debug-webpack webpack Compilation.js in: addEntry +0ms
    debug-webpack webpack Compilation.js start: this._addModuleChain +1ms
    debug-webpack webpack Compilation.js in: _addModuleChain +0ms
    debug-webpack webpack Compilation.js start: moduleFactory.create +0ms
    debug-webpack webpack Compilation.js end: moduleFactory.create +35ms
    debug-webpack webpack Compilation.js module.resource: ~/Test/debug-webpack/src/index.js +0ms
    debug-webpack webpack Compilation.js module.loaders: [{"options":{"presets":["@babel/preset-env"]},"ident":"ref--4","loader":"~/Test/debug-webpack/node_modules/_babel-loader@8.0.4@babel-loader/lib/index.js"}] +0ms
    ...
    debug-webpack webpack Compilation.js end: this._addModuleChain +0ms
    debug-webpack webpack Compiler.js end: this.hooks.make.callAsync +254ms
    

    我们看到,moduleFactory.create完成后得到的module对象中,
    包含了待webpack载入的资源地址resource和载入它所用的loaders

    即webpack即将使用以下loaders,

    [{"options":{"presets":["@babel/preset-env"]},"ident":"ref--4","loader":"~/Test/debug-webpack/node_modules/_babel-loader@8.0.4@babel-loader/lib/index.js"}]
    

    载入这个文件,

    ~/Test/debug-webpack/src/index.js
    

    这正是我们debug-webpack工程中的源文件src/index.js

    4.5 this.buildModule(module...

    得到了module对象之后,webpack使用了this.buildModule方法,
    来调用module对象自身的build方法,modulebuild方法,又调用了runLoaders方法。

    debug-webpack webpack webpack.js cliPath: ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack-cli/bin/cli.js +0ms
    debug-webpack webpack-cli cli.js start: compiler.run +0ms
    debug-webpack webpack Compiler.js start: this.hooks.make.callAsync +0ms
    debug-webpack webpack SingleEntryPlugin.js in: compiler.hooks.make.tapAsync +0ms
    debug-webpack webpack SingleEntryPlugin.js start: compilation.addEntry +0ms
    debug-webpack webpack Compilation.js in: addEntry +0ms
    debug-webpack webpack Compilation.js start: this._addModuleChain +1ms
    debug-webpack webpack Compilation.js in: _addModuleChain +0ms
    debug-webpack webpack Compilation.js start: moduleFactory.create +0ms
    debug-webpack webpack Compilation.js end: moduleFactory.create +35ms
    debug-webpack webpack Compilation.js module.resource: ~/Test/debug-webpack/src/index.js +0ms
    debug-webpack webpack Compilation.js module.loaders: [{"options":{"presets":["@babel/preset-env"]},"ident":"ref--4","loader":"~/Test/debug-webpack/node_modules/_babel-loader@8.0.4@babel-loader/lib/index.js"}] +0ms
    debug-webpack webpack Compilation.js start: this.buildModule +1ms
    debug-webpack webpack Compilation.js in: buildModule +0ms
    debug-webpack webpack Compilation.js start: module.build +0ms
    debug-webpack webpack NormalModule.js in: build +0ms
    debug-webpack webpack NormalModule.js start: this.doBuild +0ms
    debug-webpack webpack NormalModule.js in: doBuild +1ms
    debug-webpack webpack NormalModule.js start: runLoaders +0ms    <---- 进入loader-runner模块
    ...
    debug-webpack webpack NormalModule.js end: runLoaders +208ms
    debug-webpack webpack NormalModule.js end: this.doBuild +1ms
    debug-webpack webpack Compilation.js end: module.build +215ms
    debug-webpack webpack Compilation.js end: this.buildModule +1ms
    debug-webpack webpack Compilation.js end: this._addModuleChain +0ms
    debug-webpack webpack Compiler.js end: this.hooks.make.callAsync +254ms
    

    其中module相关的代码,在webpack/lib/NormalModule.js这个文件中。

    runLoaders方法却不在webpack代码库中,它是一个外部依赖,github: loader-runner


    5. loader-runner源码分析(v2.3.1)

    loader-runner由于涉及到了两个递归函数,iteratePitchingLoadersiterateNormalLoaders
    因此显得比较繁琐。

    这里之所以用递归实现,是因为loader-runner不仅可以加载单独的一个文件,
    还可以加载它依赖的文件,因此是一个递归加载过程。
    (限于篇幅,这里就不介绍递归加载过程了,加载有依赖的文件的日志,见下一篇)。

    5.1 入口文件路径

    由于loader-runner是在文件webpack/lib/NormalModule.js中首次加载的,
    因此,loader-runner模块的本地路径在这里,

    ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack/node_modules/loader-runner
    

    通过查看它的package.json文件中的main字段,

    "main": "lib/LoaderRunner.js",
    

    我们知道实际加载的文件是loader-runner/lib/LoaderRunner.js

    5.2 runLoaders

    在文件LoaderRunner.js 第242行

    exports.runLoaders = function runLoaders(options, callback) {
        ...
    }
    

    我们看到了runLoaders函数实现。

    (1)loadLoader函数
    runLoaders执行过程会分为两个环节,先载入loader,
    然后再使用loader加载文件。

    因此,runLoaders函数中,首先调用了iteratePitchingLoaders
    iteratePitchingLoaders调用了loader-runner/lib/loadLoader.js文件中导出的loadLoader函数。

    loadLoader(currentLoaderObject, function(err) {
        ...
    }
    

    loadLoader函数中,在第13行使用了require,载入了loader,

    var module = require(loader.path);
    

    (2)iteratePitchingLoaders递归
    loadLoader执行完了之后,又会递归的调用iteratePitchingLoaders,位于第173行

    if(!fn) return iteratePitchingLoaders(options, loaderContext, callback);
    

    然后又会递归调用一次,第165行

    if(currentLoaderObject.pitchExecuted) {
        loaderContext.loaderIndex++;
        return iteratePitchingLoaders(options, loaderContext, callback);
    }
    

    最终,在iteratePitchingLoaders函数中,调用了processResource,位于第158行

    return processResource(options, loaderContext, callback);
    

    (3)processResource函数
    processResource函数在第202行调用了iterateNormalLoaders

    iterateNormalLoaders(options, loaderContext, [buffer], callback);
    

    iterateNormalLoaders第229行 调用了runSyncOrAsync

    runSyncOrAsync(fn, loaderContext, args, function(err) {
        ...
    }
    

    (4)runSyncOrAsync函数
    该函数执行runLoaders的后半部分逻辑,即使用loader载入用户的源码文件。
    我们看到,它在第118行调用了LOADER_EXECUTION函数,来完成操作。

    var result = (function LOADER_EXECUTION() {
        return fn.apply(context, args);
    }());
    

    webpack loader实际上是一个导出的一个函数,这里的fn就是那个loader函数。

    注:
    LOADER_EXECUTION实际上是一个异步函数,
    fn中会通过调用this.async()得到一个callback函数,见babel-loader/src/index.js 第44行

    const callback = this.async();
    

    而这个this就是fn.apply(context, args)中的context
    它的async方法位于,loader-runner/lib/LoaderRunner.js 第95行

    context.async = function async() {
        ...
        return innerCallback;
    }
    

    因此,end: LOADER_EXECUTION日志需要写到这个函数返回的callback中,
    即,loader-runner/lib/LoaderRunner.js 第103行 innerCallback函数里。

    var innerCallback = context.callback = function() {
        log('end: LOADER_EXECUTION');
        ...
    }
    

    (5)iterateNormalLoaders递归
    值得注意的是iterateNormalLoaders也是一个递归函数,
    runSyncOrAsync执行完之后,会在第233行递归调用iterateNormalLoaders

    iterateNormalLoaders(options, loaderContext, args, callback);
    

    然后,进入iterateNormalLoaders函数后,又会在第218行再次递归调用iterateNormalLoaders

    return iterateNormalLoaders(options, loaderContext, args, callback);
    

    最终loader-runner调用了babel-loader完成了用户源码的转换操作。

    5.3 日志

    debug-webpack webpack NormalModule.js start: runLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: runLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: iteratePitchingLoaders +1ms
    debug-webpack loader-runner LoaderRunner.js in: iteratePitchingLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: loadLoader +0ms
    debug-webpack loader-runner loadLoader.js in: loadLoader +0ms
    debug-webpack loader-runner loadLoader.js loader.path: ~/Test/debug-webpack/node_modules/_babel-loader@8.0.4@babel-loader/lib/index.js +0ms
    debug-webpack loader-runner LoaderRunner.js end: loadLoader +61ms         <---- 1. 完成加载loader
    debug-webpack loader-runner LoaderRunner.js start: 1. iteratePitchingLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iteratePitchingLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: 2. iteratePitchingLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iteratePitchingLoaders +1ms
    debug-webpack loader-runner LoaderRunner.js start: processResource +0ms
    debug-webpack loader-runner LoaderRunner.js in: processResource +0ms
    debug-webpack loader-runner LoaderRunner.js start: iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: runSyncOrAsync +1ms
    debug-webpack loader-runner LoaderRunner.js in: runSyncOrAsync +0ms
    debug-webpack loader-runner LoaderRunner.js start: LOADER_EXECUTION +0ms
    ...
    debug-webpack loader-runner LoaderRunner.js in: async +0ms
    debug-webpack loader-runner LoaderRunner.js in: innerCallback +264ms
    debug-webpack loader-runner LoaderRunner.js end: LOADER_EXECUTION +0ms    <---- 2. 完成用loader载入文件
    debug-webpack loader-runner LoaderRunner.js end: runSyncOrAsync +0ms
    debug-webpack loader-runner LoaderRunner.js start: 1. iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: 2. iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js end: iteratePitchingLoaders +0ms
    debug-webpack webpack NormalModule.js end: runLoaders +328ms
    

    6. babel源码分析

    6.1 babel-loader(v8.0.4)

    在上一节的日志中,我们看到载入的loader文件地址为,

    ~/Test/debug-webpack/node_modules/_babel-loader@8.0.4@babel-loader/lib/index.js
    

    位于debug-webpack工程目录的node_modules文件夹中。

    注意由于node_modules中的babel-loader不包含src目录,是编译后的结果,
    我们可以从github仓库中找到源码,babel-loader/src/index.js
    这里我们需要在编译后的结果中进行debug。

    我们看到,在babel-loader/lib/index.js 第198行,loader调用了transform函数,

    result = await transform(source, options);
    

    transform函数是由babel-loader/lib/transform.js导出的,
    其中调用了@babel/core模块导出对象的transform方法。

    6.2 @babel/core(v7.1.2)

    导入的模块位于,

    ~/Test/debug-webpack/node_modules/_@babel_core@7.1.2@@babel/core/
    

    通过查看模块的package.jsonmain字段,

    "main": "lib/index.js",
    

    我们得知实际加载的文件是,

    ~/Test/debug-webpack/node_modules/_@babel_core@7.1.2@@babel/core/lib/index.js
    

    babel内部的transform过程,这里暂且略过。

    6.3 日志

    debug-webpack loader-runner LoaderRunner.js start: LOADER_EXECUTION +0ms
    debug-webpack loader-runner LoaderRunner.js in: async +0ms
    debug-webpack babel-loader index.js in: loader +0ms
    debug-webpack babel-loader index.js this.resourcePath: ~/Test/debug-webpack/src/index.js +0ms
    debug-webpack babel-loader index.js start: transform +185ms
    debug-webpack babel-loader index.js source: alert(); +0ms
    debug-webpack babel-loader index.js end: transform +77ms
    debug-webpack babel-loader index.js result: {"ast":null,"code":"alert();","map":null,"metadata":{},"sourceType":"module"} +0ms
    debug-webpack loader-runner LoaderRunner.js in: innerCallback +264ms
    debug-webpack loader-runner LoaderRunner.js end: LOADER_EXECUTION +0ms
    

    7. 回顾

    整个webpack打包过程,总过涉及了这几层调用,
    (1)webpack-cli
    (2)webpack
    (3)loader-runner
    (4)babel-loader

    webpack-cli调用webpack完成打包工作,
    webpack,调用loader-runner,加载loader,然后用loader加载用户代码,
    当前我们的例子中,用到了babel-loader,因此,加载用户代码时调用了babel-loader。

    debug-webpack webpack webpack.js cliPath: ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack-cli/bin/cli.js +0ms
    
    debug-webpack webpack-cli cli.js start: compiler.run +0ms
    
    debug-webpack webpack Compiler.js start: this.hooks.make.callAsync +0ms
    debug-webpack webpack SingleEntryPlugin.js in: compiler.hooks.make.tapAsync +0ms
    debug-webpack webpack SingleEntryPlugin.js start: compilation.addEntry +1ms
    debug-webpack webpack Compilation.js in: addEntry +0ms
    debug-webpack webpack Compilation.js start: this._addModuleChain +0ms
    debug-webpack webpack Compilation.js in: _addModuleChain +0ms
    debug-webpack webpack Compilation.js start: moduleFactory.create +0ms
    debug-webpack webpack Compilation.js end: moduleFactory.create +65ms
    debug-webpack webpack Compilation.js module.resource: ~/Test/debug-webpack/src/index.js +0ms
    debug-webpack webpack Compilation.js module.loaders: [{"options":{"presets":["@babel/preset-env"]},"ident":"ref--4","loader":"~/Test/debug-webpack/node_modules/_babel-loader@8.0.4@babel-loader/lib/index.js"}] +0ms
    debug-webpack webpack Compilation.js start: this.buildModule +1ms
    debug-webpack webpack Compilation.js in: buildModule +0ms
    debug-webpack webpack Compilation.js start: module.build +0ms
    debug-webpack webpack NormalModule.js in: build +0ms
    debug-webpack webpack NormalModule.js start: this.doBuild +0ms
    debug-webpack webpack NormalModule.js in: doBuild +1ms
    debug-webpack webpack NormalModule.js start: runLoaders +0ms
    
    debug-webpack loader-runner LoaderRunner.js in: runLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: iteratePitchingLoaders +1ms
    debug-webpack loader-runner LoaderRunner.js in: iteratePitchingLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: loadLoader +0ms
    debug-webpack loader-runner loadLoader.js in: loadLoader +0ms
    debug-webpack loader-runner loadLoader.js loader.path: ~/Test/debug-webpack/node_modules/_babel-loader@8.0.4@babel-loader/lib/index.js +0ms
    debug-webpack loader-runner LoaderRunner.js end: loadLoader +61ms
    debug-webpack loader-runner LoaderRunner.js start: 1. iteratePitchingLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iteratePitchingLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: 2. iteratePitchingLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iteratePitchingLoaders +1ms
    debug-webpack loader-runner LoaderRunner.js start: processResource +0ms
    debug-webpack loader-runner LoaderRunner.js in: processResource +0ms
    debug-webpack loader-runner LoaderRunner.js start: iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: runSyncOrAsync +1ms
    debug-webpack loader-runner LoaderRunner.js in: runSyncOrAsync +0ms
    debug-webpack loader-runner LoaderRunner.js start: LOADER_EXECUTION +0ms
    debug-webpack loader-runner LoaderRunner.js in: async +0ms
    
    debug-webpack babel-loader index.js in: loader +0ms
    debug-webpack babel-loader index.js this.resourcePath: ~/Test/debug-webpack/src/index.js +0ms
    debug-webpack babel-loader index.js start: transform +185ms
    debug-webpack babel-loader index.js source: alert(); +0ms
    debug-webpack babel-loader index.js end: transform +77ms
    debug-webpack babel-loader index.js result: {"ast":null,"code":"alert();","map":null,"metadata":{},"sourceType":"module"} +0ms
    
    debug-webpack loader-runner LoaderRunner.js in: innerCallback +264ms
    debug-webpack loader-runner LoaderRunner.js end: LOADER_EXECUTION +0ms
    debug-webpack loader-runner LoaderRunner.js end: runSyncOrAsync +0ms
    debug-webpack loader-runner LoaderRunner.js start: 1. iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js start: 2. iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js in: iterateNormalLoaders +0ms
    debug-webpack loader-runner LoaderRunner.js end: iteratePitchingLoaders +0ms
    
    debug-webpack webpack NormalModule.js end: runLoaders +328ms
    debug-webpack webpack NormalModule.js end: this.doBuild +0ms
    debug-webpack webpack Compilation.js end: module.build +339ms
    debug-webpack webpack Compilation.js end: this.buildModule +0ms
    debug-webpack webpack Compilation.js end: this._addModuleChain +1ms
    debug-webpack webpack Compiler.js end: this.hooks.make.callAsync +407ms
    

    参考

    github: nvm
    github: debug
    github: webpack
    github: webpack-cli
    github: loader-runner
    github: babel-loader
    github: @babel/core

    相关文章

      网友评论

        本文标题:[FE] webpack v4.20.2 源码解析(二):加载资

        本文链接:https://www.haomeiwen.com/subject/rimlzftx.html