Sourcemapping TypeScript в Карме
Я пытаюсь настроить процесс сборки для 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>
Однако сама Карма регистрирует ошибки только с номерами строк, сопоставленными с источником (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 from 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 ответ
Выяснить это было довольно утомительно. Здесь возникает пара проблем:
webpack-internal://
исходные карты были добавлены в качестве обходного пути к неназванной ошибке Chrome с исходными картами типа eval. Похоже, что другие браузеры, такие как средство запуска Karma (и также Firefox), все еще не могут интерпретировать исходные карты типа eval и поэтому возвращаются кwebpack-internal://
, Для того, чтобы получить надлежащую поддержку исходных карт в этих браузерах, вам нужно использовать классические исходные карты, такие какdevtool: inline-source-map
, Это также устраняетwebpack-internal://
исходные карты в целом.- При транспортировке
.ts
файлы с karma-webpack без исходных карт генерируются до сих пор. Это потому, что karma-webpack по умолчанию выводит файлы с их исходным именем. А такжеdevtool: inline-source-map
устанавливает фильтр для построения только исходных карт.css
а также.js
выходные файлы. Это можно спасти, настроив SourceMapDevToolPlugin явно и предоставивtest
регулярное выражение, которое включает в себя.ts
файлы. - Как только вы замените
devtool
установка поSourceMapDevtoolPlugin
толькоwebpack://
исходные карты генерируются, но они все еще неправильны вdevelopment
Режим. Это потому, что в этом режимеdevtool: eval
автоматически добавляется в конфиг. Чтобы отключить это поведение, вы должны явно установитьdevtool: false
, - Для того, чтобы Карма загружала встроенные исходные карты, вам необходимо применить https://github.com/demerzel3/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'
}
});
};