原来rollup这么简单之 rollup.generate + rollup.write篇 (2)

获取到标准化之后的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上。格式为:

{ fileName, get isAsset(): true { graph.warnDeprecation( 'Accessing "isAsset" on files in the bundle is deprecated, please use "type === \'asset\'" instead', false ); return true; }, source, type: 'asset' }; class FileEmitter { // ... setOutputBundle = ( outputBundle: OutputBundleWithPlaceholders, assetFileNames: string ): void => { this.output = { // 打包出来的命名 assetFileNames, // 新建的空对象 => Object.create(null) bundle: outputBundle }; // filesByReferenceId是通过rollup.rollup中emitChunks的时候设置的,代表已使用的chunks // 处理文件 for (const emittedFile of this.filesByReferenceId.values()) { if (emittedFile.fileName) { // 文件名挂在到this.output上,作为key,值为: FILE_PLACEHOLDER reserveFileNameInBundle(emittedFile.fileName, this.output.bundle, this.graph); } } // 遍历set 处理资源 for (const [referenceId, consumedFile] of this.filesByReferenceId.entries()) { // 插件中定义了source的情况 if (consumedFile.type === 'asset' && consumedFile.source !== undefined) { // 给this.output上绑定资源 this.finalizeAsset(consumedFile, consumedFile.source, referenceId, this.output); } } }; // ... }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywwgw.html