如何让 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).