Sourcemapping TypeScript в Карме - PullRequest
0 голосов
/ 16 мая 2018

Я пытаюсь настроить процесс сборки для TypeScript с помощью Webpack.Все работает нормально для большинства частей.Однако я не могу заставить исходные карты работать должным образом в тестере Karma.

Описание проблемы

Допустим, у меня есть файл машинописи test.spec.ts (1).Этот файл передается TypeScript в некоторый источник ES5 со встроенными картами источников (2).Наконец, исходный код ES5 связывается с помощью Webpack 4 с помощью eval-source-maps (3) и подается в Chrome бегуном по тестам Karma.

Путем проверки источников в Karma Debug Runner в ChromeЯ вижу, что все три этапа транспаляции фактически доступны для браузера:

  • (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), конечно).

В любом случае, важно, чтобы Карма сообщала о трассировке стека с номерами строк относительноисходные файлы, как это делается в консоли Chrome.При необходимости я также готов обменять скорость выполнения на это

Если вы не можете придумать полноценное решение, но имеете некоторое представление о TypeScript / TS-Loader / Webpack / Karma-Webpack / KarmaМне также интересны любые аргументы, помогающие точно определить проблему в этой цепочке инструментов.

Минимальная конфигурация теста

devDependencies package.json

"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"
        ]
    }
}

1 Ответ

0 голосов
/ 16 июля 2018

Понять это было довольно утомительно.Здесь сошлись несколько проблем:

  1. webpack-internal:// исходные карты были добавлены в качестве обходного пути к неназванной Chrome bug с исходными картами типа eval.Похоже, что другие браузеры, такие как средство запуска Karma (а также Firefox), все еще не могут интерпретировать исходные карты типа eval и поэтому возвращаются к webpack-internal://.Чтобы получить надлежащую поддержку карты источников в этих браузерах, вам нужно использовать классические карты источников, такие как devtool: inline-source-map.Это также полностью исключает webpack-internal:// исходные карты.
  2. При переносе файлов .ts с помощью karma-webpack исходные карты по-прежнему не создаются.Это потому, что karma-webpack по умолчанию выводит файлы с их исходным именем.И devtool: inline-source-map устанавливает фильтр для построения исходных карт только для выходных файлов .css и .js.Этого можно избежать, явно настроив SourceMapDevToolPlugin и предоставив регулярное выражение test, включающее .ts файлов.
  3. После замены параметра devtool только на SourceMapDevtoolPlugin webpack:// исходные карты генерируются, но они все еще не работают в режиме development.Это потому, что в этом режиме devtool: eval автоматически добавляется в конфигурацию.Чтобы отключить это поведение, вы должны явно установить devtool: false.
  4. Чтобы Карма могла загружать встроенные исходные карты, вам необходимо применить 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'
        }
    });
};
...