【问题标题】:Sourcemapping TypeScript in KarmaKarma 中的源映射 TypeScript
【发布时间】:2018-05-16 15:04:04
【问题描述】:

我正在尝试使用 Webpack 为 TypeScript 设置构建过程。大多数部分一切正常。但是我无法让源映射在 Karma 测试运行器中正常工作。

问题描述

假设我有一个打字稿文件test.spec.ts (1)。该文件由 TypeScript 转译为带有内联源映射 (2) 的某些 ES5 源。最后,ES5 源代码由 Webpack 4 使用 eval-source-maps (3) 捆绑,并由 Karma 测试运行程序提供给 Chrome。

通过在 Chrome 中检查 Karma Debug Runner 中的源代码,我可以看到所有三个转换阶段实际上都可用于浏览器:

  • (1) 源映射为 webpack://test.spec.ts?c161
  • (2) 源映射为webpack-internal://test.spec.ts
  • (3) 可用作localhost:9876/base/test.spec.ts

在 Chrome 控制台中,我还可以获得测试执行期间引发的所有错误的正确堆栈跟踪。正如我所料,这些包括源映射到 (1) 的行号。例如:

Error: Oh no!
    at Function.MyClass.myBadMethod (test.spec.ts?c161:9)
    at UserContext.eval (test.spec.ts?c161:21)
    at <Jasmine>

但是,Karma 本身会记录错误,其中行号仅源映射到 (2)。例如:

Error: Oh no!
    at Function.MyClass.myBadMethod (webpack-internal:///./src/test.spec.ts:8:15)
    at UserContext.eval (webpack-internal:///./src/test.spec.ts:17:17)
    at <Jasmine>

这完全没有帮助,因为 (2) 只是一些中间源,甚至从未写入磁盘。事实上,我不需要 (2) 的源映射,也不明白为什么首先包含它们。如果可能的话,我想尝试禁用它们(当然,同时为 (1) 保留正确的源映射)。

无论如何,重要的是让 Karma 使用相对于原始文件的行号报告堆栈跟踪,就像在 Chrome 控制台中所做的那样。如有必要,我也愿意为此牺牲执行速度

如果您想不出一个完整的解决方案,但对 TypeScript / TS-Loader / Webpack / Karma-Webpack / Karma 有一些见解:我也对任何有助于查明问题的论点感兴趣工具链。

最小测试配置

来自package.json 的devDependencies

"devDependencies": {
    "@types/jasmine": "~2.8.7",
    "jasmine": "~3.1.0",
    "karma": "~2.0.2",
    "karma-chrome-launcher": "~2.2.0",
    "karma-jasmine": "~1.1.2",
    "karma-webpack": "~3.0.0",
    "ts-loader": "~4.3.0",
    "typescript": "~2.8.3",
    "webpack": "~4.8.3"
}

karma.conf.js

module.exports = function(config) {
    config.set({
        frameworks: ['jasmine'],
        browsers: ['Chrome'],
        files: [
            './test.spec.ts'
        ],
        mime: {
            'text/x-typescript': ['ts']
        },
        preprocessors: {
            '**/*.ts': ['webpack']
        },
        plugins: [
            'karma-chrome-launcher',
            'karma-jasmine',
            'karma-webpack'
        ],
        webpack: {
            devtool: 'eval-source-map',
            mode: 'development',
            module: {
                rules: [
                    {
                        test: /\.ts$/,
                        loader: 'ts-loader',
                    }
                ]
            },
            resolve: {
                extensions: [ '.ts' ]
            }
        },
        webpackMiddleware: {
            logLevel: 'error'
        }
    });
};

tsconfig.json

{
    "compileOnSave": false,
    "compilerOptions": {
        "module": "es2015",
        "moduleResolution": "node",
        "sourceMap": true,
        "target": "es5",
        "types": [
        "jasmine"
        ]
    }
}

【问题讨论】:

    标签: typescript webpack karma-runner source-maps karma-webpack


    【解决方案1】:

    弄清楚这一点相当乏味。这里有几个问题:

    1. webpack-internal:// 源映射作为一种解决方法添加到具有 eval 类型源映射的未命名 Chrome bug。 似乎 Karma 启动器(以及 Firefox)等其他浏览器仍然无法解释 eval 类型的源映射,因此回退到 webpack-internal://。为了在这些浏览器中获得适当的源映射支持,您需要使用经典的源映射,例如 devtool: inline-source-map。这也完全消除了 webpack-internal:// 源映射。
    2. 当使用 karma-webpack 转译 .ts 文件时,仍然不会生成源映射。这是因为默认情况下 karma-webpack 会使用原始文件名输出文件。并且devtool: inline-source-map 设置了一个过滤器,只为.css.js 输出文件构建源映射。这可以通过显式配置 SourceMapDevToolPlugin 并提供包含 .ts 文件的 test 正则表达式来挽救。
    3. devtool 设置替换为SourceMapDevtoolPlugin 后,只会生成webpack:// 源映射,但在development 模式下这些仍然是错误的。那是因为在这种模式下 devtool: eval is added automatically 到配置。要禁用此行为,您必须显式设置 devtool: false
    4. 为了让 Karma 加载内联源映射,您需要应用 karma-sourcemap-loader

    将所有这些放在一起,问题中的配置可以固定如下:

    module.exports = function(config) {
        config.set({
            frameworks: ['jasmine'],
            browsers: ['Chrome'],
            files: [
                './test.spec.ts'
            ],
            mime: {
                'text/x-typescript': ['ts']
            },
            preprocessors: {
                '**/*.ts': ['webpack', 'sourcemap']
            },
            plugins: [
                'karma-chrome-launcher',
                'karma-jasmine',
                'karma-sourcemap-loader',
                'karma-webpack'
            ],
            webpack: {
                devtool: false,
                mode: 'development',
                module: {
                    rules: [
                        {
                            test: /\.ts$/,
                            loader: 'ts-loader',
                        }
                    ]
                },
                plugins: [
                    new webpack.SourceMapDevToolPlugin({
                        test: /\.(ts|js|css)($|\?)/i
                    })
                ],
                resolve: {
                    extensions: [ '.ts' ]
                }
            },
            webpackMiddleware: {
                logLevel: 'error'
            }
        });
    };
    

    【讨论】:

    • 我也有同样的问题。它看起来很明智。但它不起作用。在我的情况下,Karma 报告堆栈错误我看到源映射工作但堆栈格式不正确。我不需要 webpack 的消息堆栈。
    猜你喜欢
    • 2017-11-27
    • 2016-08-09
    • 1970-01-01
    • 2016-07-25
    • 2016-07-06
    • 2015-11-05
    • 2016-07-25
    • 2016-06-29
    • 2016-04-02
    相关资源
    最近更新 更多