You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webpack打包后如何保留并获取原始源文件名称?

如何在打包后仍获取原始源文件名创建追踪对象

下面提供几种可靠的方案,解决Webpack打包后__filename指向打包文件的问题,让你可以安全复用追踪代码:

方案1:Webpack DefinePlugin 编译时注入原始文件名

直接通过Webpack的内置插件,在编译阶段为每个模块注入原始文件名,运行时直接使用即可:

  1. 修改Webpack配置文件,添加DefinePlugin:
const webpack = require('webpack');
const path = require('path');

module.exports = {
  // 其他配置项(入口、输出等)
  plugins: [
    new webpack.DefinePlugin({
      // 注入仅保留文件名的原始路径,也可根据需求改为完整路径
      __ORIGINAL_FILENAME__: JSON.stringify(path.basename(__resourcePath))
    })
  ]
};
  1. 在你的TS/JS源文件中直接使用:
const TRACER = new Tracker(__ORIGINAL_FILENAME__);

__resourcePath是Webpack编译时提供的当前模块的原始文件路径,通过path.basename可以只提取文件名,避免路径过长。

方案2:Babel插件注入自定义标识

如果项目使用Babel编译,可以写一个极简的Babel插件,自动为每个文件注入原始文件名:

  1. 编写Babel插件(比如inject-original-filename.js):
const path = require('path');

module.exports = function({ types: t }) {
  return {
    visitor: {
      Program(path, state) {
        // 获取当前文件的原始路径,提取文件名
        const fileName = path.basename(state.file.opts.filename);
        // 在文件顶部插入常量定义
        path.unshiftContainer('body', t.variableDeclaration('const', [
          t.variableDeclarator(
            t.identifier('__ORIGINAL_FILENAME__'),
            t.stringLiteral(fileName)
          )
        ]));
      }
    }
  };
};
  1. 在Babel配置(比如.babelrc或babel.config.js)中引入该插件:
{
  "plugins": ["./inject-original-filename.js"]
}
  1. 源文件中直接使用:
const TRACER = new Tracker(__ORIGINAL_FILENAME__);

这个方案不依赖Webpack,Rollup等其他打包工具也能兼容。

方案3:Source Map 运行时解析(调试场景专用)

如果无法修改构建配置,可通过Source Map反向解析原始文件名,但该方案运行时开销大,仅适合调试:

const { SourceMapConsumer } = require('source-map');
const path = require('path');

async function getOriginalFilename() {
  try {
    // 通过抛出错误获取栈信息
    throw new Error();
  } catch (e) {
    const stackLine = e.stack?.split('\n')[2];
    if (!stackLine) return __filename;

    // 提取栈中的行号、列号和打包文件路径
    const match = stackLine.match(/at .+ \((.+):(\d+):(\d+)\)/);
    if (!match) return __filename;

    const [, bundlePath, line, column] = match;
    // 加载对应的Source Map文件(需确保打包时生成了source map)
    const sourceMapUrl = `${bundlePath}.map`;
    const response = await fetch(sourceMapUrl);
    const sourceMapData = await response.json();

    // 解析原始文件路径
    const consumer = await new SourceMapConsumer(sourceMapData);
    const originalPos = consumer.originalPositionFor({
      line: parseInt(line, 10),
      column: parseInt(column, 10)
    });
    consumer.destroy();
    
    return originalPos.source ? path.basename(originalPos.source) : __filename;
  }
}

// 注意:这里需要异步调用
const TRACER = new Tracker(await getOriginalFilename());

方案选择建议

优先选择方案1或方案2,这两种都是构建时注入,运行时无额外开销,且能保证文件名的准确性,完全满足你复制粘贴代码不失效的需求。方案3仅作为无法修改构建配置时的应急方案。

内容的提问来源于stack exchange,提问作者Grogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 10:50:15