源代码转换
如果插件转换了源代码,就应该自动生成 source map,除非插件提供了明确的 sourceMap: false 选项。Rolldown 只关心 mappings 属性,其他内容都会自动处理。magic-string 提供了一种简单的方法,可为添加或删除代码片段等基础转换生成此类映射。
如果生成 source map 没有意义,请返回一个空的 source map:
js
return {
code: transformedCode,
map: { mappings: '' },
};如果转换没有移动代码,可以返回 null 来保留现有 source map:
js
return {
code: transformedCode,
map: null,
};转换代码块
可以使用 renderChunk 转换代码块。如果返回所应用转换的 sourcemap,Rolldown 会将该映射与之前的转换组合起来,并根据选项重新构建 x_google_ignoreList 字段:
js
import MagicString from 'magic-string';
export default function myPlugin() {
return {
name: 'example',
renderChunk(code) {
const s = new MagicString(code);
s.prepend('/* banner */\n');
return { code: s.toString(), map: s.generateMap({ hires: 'boundary' }) };
},
};
}我们不建议在 generateBundle 中进行转换。它在哈希计算之后运行,因此输出文件名保留的是未转换代码的哈希;同时它在 .map 资源构建之后运行,因此编辑 chunk.map 不会改变该文件。不过,如果必须在那里转换,请组合映射并自行写入资源:
js
import remapping from '@jridgewell/remapping';
import MagicString from 'magic-string';
export default function myPlugin() {
return {
name: 'example',
generateBundle(options, bundle) {
for (const chunk of Object.values(bundle)) {
if (chunk.type !== 'chunk') continue;
const s = new MagicString(chunk.code);
// ……你的转换逻辑……
if (!s.hasChanged()) continue;
// 低分辨率映射在组合时可能退化为空,因此请保留边界处的映射。
const step = s.generateMap({ source: chunk.fileName, hires: 'boundary' });
chunk.code = s.toString();
if (chunk.map) {
// 组合 source map
chunk.map = remapping([step, chunk.map], () => null);
// 输出文件来自此资源,而不是来自 `chunk.map`。
const asset = bundle[`${chunk.fileName}.map`];
if (asset) asset.source = chunk.map.toString();
}
}
},
};
}