如何让Webpack在生成源代码映射时使用已有的源代码映射?

4

我有 JavaScript 代码和从 TypeScript 代码生成的源地图(使用 tsc)。

然后,我进行了第二个编译步骤,使用 webpack 捆绑代码。

我已在 webpack.config.js 中启用了源地图:

module.exports = {
  devtool: "source-map"
}

生成的源映射并不完全正确。
Webpack没有考虑从TypeScript代码生成的现有源映射。
这会导致映射到JavaScript代码而不是TypeScript代码。
如何让Webpack源映射包含现有的映射?
编辑:
重命名我的问题,并在谷歌上搜索后,我找到了一个答案。
您可以使用Webpack的预加载程序source-map-loader: https://webpack.js.org/loaders/source-map-loader/ 但是,在安装source-map-loader并将webpack.config.js更新为以下内容后,仍然没有使用现有的源映射:
module.exports = {
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.js$/,
        use: ["source-map-loader"],
        enforce: "pre"
      }
    ]
  }
}

我的猜测是,因为我的现有源映射文件指向的文件位于webpack.config.js中的entry目录之外,所以它们被忽略了…?

是的,你的问题标题肯定需要改变:如何让Webpack在生成源映射时使用已经存在的源映射?- 你当前的配置正在按照你所要求的方式进行。Webpack没有映射TypeScript,现有的映射也不会反映捆绑包中的内容,而是反映转换后的JavaScript中的内容。不确定是否有实现你目标的方法。 - Randy Casburn
我已经更新了问题。如果没有解决方案,那将是令人失望的。 - David Callanan
好的,我认为我们需要从两个方面考虑这个问题:1)原始源映射(SM)指向什么?是从转译后的JavaScript反射出来的TypeScript。如果转译后的JavaScript文件被删除或更改,则SM会中断。因此,简单地包含原始SM是行不通的。2)webpack工作流程:将TS转译,放置到引用行号的捆绑包中,根据_转译JS在捆绑包中的位置_编写SM。这是无法在捆绑包创建之外完成的工作流程的一部分。 - Randy Casburn
  1. 我希望有一种方法可以剪枝到映射。所以,如果捆绑包中的A映射到js中的B,而js中的B映射到ts中的C,那么A可以直接映射到C。
  2. 我希望TypeScript能够在webpack内进行转译,但我有代码共享服务器、客户端和其他构建。例如,我的react native客户端正在使用不同的内置捆绑程序。
  3. 也许有不同的打包工具可以做到这一点。
- David Callanan
1个回答

1
如果你在Webpack中将TypeScript转译,就会得到它的源代码映射。
devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: ([
          {
            loader: 'awesome-typescript-loader',
            options: { configFileName: 'tsconfig.json' }
          },

你需要在webpack中使用devTool: 'source-map',并在tsconfig.json中设置"sourceMap": true。
devtool: 'cheap-module-eval-source-map'提供了更快的构建速度来生成开发环境下的源映射。但是它会将源映射放在内联中,因此不适用于生产环境。
那么重要的问题是,为什么要将步骤与webpack分开?
如果你在angular中使用AOT编译(使用@anguler/compiler中的ngc命令),并在aot文件夹中生成.map文件,则希望重复使用map文件。我可以告诉你,我测试过以下解决方案可行。
然后这样做就可以了:
  {
    test: /\.js$/,
    use: ["source-map-loader"],
    enforce: "pre"
  },

在 tsconfig 中需要设置 sourceMap: true,并且如果使用 minimizer,则同样需要设置。

    optimization: {
        minimizer: [
          new TerserPlugin({
cache: true,
        parallel: true,
        sourceMap: true, // Must be set to true if using source-maps in production
        terserOptions: {
          // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
        }

我在开发中有一个tsconfig.json文件

用于ngc命令的tsconfig_ao1.json文件

我有一个tsconfig_ao2.json文件,用于使用aot文件夹编译main.ts,并且我在webpack之外使用ngc,因为在webpack内无法使用@ngtools/webpack,存在问题。

如果你在做其他事情,你需要理解source-map-load只会在它测试匹配的文件具有源映射,并且如果这些文件不是从entry加载的树的一部分,则不会加载源映射。必须从main.ts导入到正在进行源映射的文件。


1
我正按照您所说的做…… 我有 builddistsrc 文件夹。TypeScript 从 src 获取输入,并在 dist 文件夹中生成输出和源映射。Webpack 的入口是 dist 文件夹,并输出到 build 文件夹。它不能工作,是因为原始的 TypeScript 代码在 src 文件夹中,但是 webpack 入口是 dist 文件夹,因此在生成源映射时忽略了原始的 TypeScript 代码(因为 TypeScript 的源映射指向了 webpack 入口之外的文件)?如果是这种情况,您知道该如何解决吗? - David Callanan
符号链接有时可能会引起问题,例如如果您的dist是指向一个映射的符号链接。一个条目不是文件夹,一个条目是程序的根文件(就像C中的main())。而且这个文件必须导入到你生成的js文件的相对路径(ts生成的输出)。我用构建和aot分开的文件夹使它工作了。你必须简化你的webpack配置。例如,如果你有一个排除规则,它可能会排除一些文件。Webpack需要练习。我怀疑你的typescript编译器很奇怪。也许要改变它。 - Thierry Vilmart
加载器(loaders)例如source-map-loaders只在模块上运行。要有一个模块,您需要导入它。因此,请尝试创建一个新的入口点文件,该文件导入dist/main.ts。然后您将拥有一个模块。并将webpack入口点更改为该新文件。它能工作吗?可以拥有不同的部分并共享代码。也许重新构造dist/main以使其具有导出。请注意在各种import x和import * as x和import { x }之间进行区分。 - Thierry Vilmart
我有一个类似于@DavidCallanan的设置,也无法将我的库的dist文件夹中的源映射集成到使用它的项目的总体源映射中。我现在已经放弃了,但如果我找到解决方法,我会在这里更新。 - Venryx
你应该尝试去论坛上询问,附上在线代码示例。我不能在这里做广告。但是一个好的论坛以S开头,以T结尾,有9个字母。 - Thierry Vilmart
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接