获取到标准化之后的output配合和插件驱动器后,到了内置的generate方法了,该方法接受三个参数,其中第二个参数标识是否写入,也就是说该方法同时用于generate和下一篇write中。
首先获取用户定义的资源名,没有的话取默认值
const assetFileNames = outputOptions.assetFileNames || 'assets/[name]-[hash][extname]';获取chunks的目录交集,也就是公共的根目录
const inputBase = commondir(getAbsoluteEntryModulePaths(chunks));getAbsoluteEntryModulePaths获取所有绝对路径的chunks id,commondir参考的node-commondir模块,原理是先获取第一个文件的路径,进行split转成数组(设为a),然后遍历剩余所有文件id,进行比对,找到不相等的那个索引,然后重新赋值给a,进行下一次循环,直到结束,就得到了公共的目录。
function commondir(files: string[]) { if (files.length === 0) return 'http://www.likecs.com/'; if (files.length === 1) return path.dirname(files[0]); const commonSegments = files.slice(1).reduce((commonSegments, file) => { const pathSegements = file.split(/\/+|\\+/); let i; for ( i = 0; commonSegments[i] === pathSegements[i] && i < Math.min(commonSegments.length, pathSegements.length); i++ ); return commonSegments.slice(0, i); }, files[0].split(/\/+|\\+/)); // Windows correctly handles paths with forward-slashes return commonSegments.length > 1 ? commonSegments.join('http://www.likecs.com/') : 'http://www.likecs.com/'; }创建一个包含所有chunks和assets信息的对象
const outputBundleWithPlaceholders: OutputBundleWithPlaceholders = Object.create(null);调用插件驱动器上的setOutputBundle将output设置到上面创建的outputBundleWithPlaceholders上。
outputPluginDriver.setOutputBundle(outputBundleWithPlaceholders, assetFileNames);setOutputBundle在FileEmitter类上实现,在插件驱动器类(PluginDriver)上实例化,并将公共方法赋给插件驱动器。
reserveFileNameInBundle方法为outputBundleWithPlaceholders上挂载文件chunks。
finalizeAsset方法只处理资源,将资源格式化后,添加到outputBundleWithPlaceholders上。格式为: