如何让 Rollup 的内联源地图工作?
How to get Rollup's inline sourcemaps to work?
我正在做一件相当奇怪的事情,我在每个请求上直接编译 Javascript(暂时请假装这是一件合理的事情;不用说,它是仅供内部开发使用)。
不幸的是,尽管我尝试了几种配置,但我无法使源映射工作。
我的快递路线是这样的:
app.get(`/js/${f.script}`, async (req, res) => {
try {
const bundle = await rollup.rollup({
input: `./examples/src/${f.script}`,
external: ['React', 'ReactDOM'],
treeshake: false,
plugins: [
resolvePlugin({ jsnext: true, extensions: ['.js', '.jsx'] }),
commonjsPlugin({ include: 'node_modules/**' }),
babelPlugin({
babelrc: false,
presets: [
[
'env',
{ modules: false, targets: { browsers: ['last 2 versions'] } },
],
'react',
],
plugins: ['external-helpers', 'transform-class-properties'],
exclude: 'node_modules/**',
}),
],
});
const { code, map } = await bundle.generate({
format: 'iife',
sourcemap: 'inline',
intro: `var process = {
env : {
NODE_ENV : 'development',
}
}`,
});
res.set('Content-Type', 'text/javascript');
res.send(
`${code}\n//@ sourceMappingURL=data:application/json;charset=utf-8,${map}`,
);
// eslint-disable-next-line no-console
console.log(`Served ${f.script}`);
} catch (e) {
// eslint-disable-next-line no-console
console.log('oh bad no no', e);
res.sendStatus(500);
}
});
这给我一个脚本,后面是:
//@ sourceMappingURL=data:application/json;charset=utf-8,{"version":3,"file":...
它很长,但在我相对未经训练的眼睛看来,它就像一个源地图。浏览器完全忽略它。
我已经通过仅使用其他位的 sourcemap: 'inline'
和 none 进行了尝试,它没有在末尾附加任何源映射。我现在已经多次手动 'tacking on' 生成的源映射到脚本的末尾,但是 Chrome 无法识别它。是这里有简单的语法错误,还是我整个方法都错了?
你就快完成了——你是对的,你需要在使用 bundle.generate
时手动附加评论(如果你改用 bundle.write
,它会自动为你完成,但事实并非如此这里没有意义)。
很可能是 JSON 导致数据 URI 无效,因此需要将其呈现为 base64。 map
对象附带了一个方法,可以让您轻松地做到这一点:
res.send(
`${code}\n//# sourceMappingURL=${map.toUrl()}`,
);
toUrl
的实现可见here。
请注意,我使用的是 //#
而不是 //@
— 两者都有效,但 //#
正式是 'preferred'(//@
是遗留的神器,据spec).
我正在做一件相当奇怪的事情,我在每个请求上直接编译 Javascript(暂时请假装这是一件合理的事情;不用说,它是仅供内部开发使用)。
不幸的是,尽管我尝试了几种配置,但我无法使源映射工作。
我的快递路线是这样的:
app.get(`/js/${f.script}`, async (req, res) => {
try {
const bundle = await rollup.rollup({
input: `./examples/src/${f.script}`,
external: ['React', 'ReactDOM'],
treeshake: false,
plugins: [
resolvePlugin({ jsnext: true, extensions: ['.js', '.jsx'] }),
commonjsPlugin({ include: 'node_modules/**' }),
babelPlugin({
babelrc: false,
presets: [
[
'env',
{ modules: false, targets: { browsers: ['last 2 versions'] } },
],
'react',
],
plugins: ['external-helpers', 'transform-class-properties'],
exclude: 'node_modules/**',
}),
],
});
const { code, map } = await bundle.generate({
format: 'iife',
sourcemap: 'inline',
intro: `var process = {
env : {
NODE_ENV : 'development',
}
}`,
});
res.set('Content-Type', 'text/javascript');
res.send(
`${code}\n//@ sourceMappingURL=data:application/json;charset=utf-8,${map}`,
);
// eslint-disable-next-line no-console
console.log(`Served ${f.script}`);
} catch (e) {
// eslint-disable-next-line no-console
console.log('oh bad no no', e);
res.sendStatus(500);
}
});
这给我一个脚本,后面是:
//@ sourceMappingURL=data:application/json;charset=utf-8,{"version":3,"file":...
它很长,但在我相对未经训练的眼睛看来,它就像一个源地图。浏览器完全忽略它。
我已经通过仅使用其他位的 sourcemap: 'inline'
和 none 进行了尝试,它没有在末尾附加任何源映射。我现在已经多次手动 'tacking on' 生成的源映射到脚本的末尾,但是 Chrome 无法识别它。是这里有简单的语法错误,还是我整个方法都错了?
你就快完成了——你是对的,你需要在使用 bundle.generate
时手动附加评论(如果你改用 bundle.write
,它会自动为你完成,但事实并非如此这里没有意义)。
很可能是 JSON 导致数据 URI 无效,因此需要将其呈现为 base64。 map
对象附带了一个方法,可以让您轻松地做到这一点:
res.send(
`${code}\n//# sourceMappingURL=${map.toUrl()}`,
);
toUrl
的实现可见here。
请注意,我使用的是 //#
而不是 //@
— 两者都有效,但 //#
正式是 'preferred'(//@
是遗留的神器,据spec).