原来rollup这么简单之插件篇 (3)

我们通过transform操作来简单看下,之前对ast进行transform的时候,调用了transform钩子:

graph.pluginDriver .hookReduceArg0<any, string>( 'transform', [curSource, id], // source.code 和 模块id transformReducer, // 第四个参数是一个函数,用来声明某些钩子上下文中需要的方法 (pluginContext, plugin) => { // 这一大堆是插件利用的,通过this.xxx调用 curPlugin = plugin; if (curPlugin.cacheKey) customTransformCache = true; else trackedPluginCache = getTrackedPluginCache(pluginContext.cache); return { ...pluginContext, cache: trackedPluginCache ? trackedPluginCache.cache : pluginContext.cache, warn(warning: RollupWarning | string, pos?: number | { column: number; line: number }) { if (typeof warning === 'string') warning = { message: warning } as RollupWarning; if (pos) augmentCodeLocation(warning, pos, curSource, id); warning.id = id; warning.hook = 'transform'; pluginContext.warn(warning); }, error(err: RollupError | string, pos?: number | { column: number; line: number }): never { if (typeof err === 'string') err = { message: err }; if (pos) augmentCodeLocation(err, pos, curSource, id); err.id = id; err.hook = 'transform'; return pluginContext.error(err); }, emitAsset(name: string, source?: string | Buffer) { const emittedFile = { type: 'asset' as const, name, source }; emittedFiles.push({ ...emittedFile }); return graph.pluginDriver.emitFile(emittedFile); }, emitChunk(id, options) { const emittedFile = { type: 'chunk' as const, id, name: options && options.name }; emittedFiles.push({ ...emittedFile }); return graph.pluginDriver.emitFile(emittedFile); }, emitFile(emittedFile: EmittedFile) { emittedFiles.push(emittedFile); return graph.pluginDriver.emitFile(emittedFile); }, addWatchFile(id: string) { transformDependencies.push(id); pluginContext.addWatchFile(id); }, setAssetSource(assetReferenceId, source) { pluginContext.setAssetSource(assetReferenceId, source); if (!customTransformCache && !setAssetSourceErr) { try { return this.error({ code: 'INVALID_SETASSETSOURCE', message: `setAssetSource cannot be called in transform for caching reasons. Use emitFile with a source, or call setAssetSource in another hook.` }); } catch (err) { setAssetSourceErr = err; } } }, getCombinedSourcemap() { const combinedMap = collapseSourcemap( graph, id, originalCode, originalSourcemap, sourcemapChain ); if (!combinedMap) { const magicString = new MagicString(originalCode); return magicString.generateMap({ includeContent: true, hires: true, source: id }); } if (originalSourcemap !== combinedMap) { originalSourcemap = combinedMap; sourcemapChain.length = 0; } return new SourceMap({ ...combinedMap, file: null as any, sourcesContent: combinedMap.sourcesContent! }); } }; } )

runHook中有一句判断,就是对上下文环境的使用:

function runHook<T>( hookName: string, args: any[], pluginIndex: number, permitValues: boolean, hookContext?: ReplaceContext | null ) { // ... const plugin = this.plugins[pluginIndex]; // 获取默认的上下文环境 let context = this.pluginContexts[pluginIndex]; // 如果提供了,就替换 if (hookContext) { context = hookContext(context, plugin); } // ... }

至于rollup是什么时机调用插件提供的钩子函数的,这里就不啰嗦了,代码中分布很清晰,一看便知.

还有 rollup 为了方便咱们变化插件,还提供了一个工具集,可以非常方便的进行模块的操作以及判断,有兴趣的自行查看。

总结

rollup系列到此也就告一段落了,从开始阅读时的一脸懵逼,到读到依赖收集、各工具类的十脸懵逼,到现在的轻车熟路,真是一段难忘的经历~

学习大佬们的操作并取其精华,去其糟粕就像打怪升级一样,你品,你细品。哈哈

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

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