Karma изначально поддерживает работу с различными препроцессорами, которые позволяют трансформировать исходный код перед его выполнением в тестовой среде. Препроцессоры нужны для компиляции файлов из форматов, отличных от чистого JavaScript, таких как TypeScript, CoffeeScript, или для внедрения дополнительных шагов обработки, например, обфускации, транспиляции через Babel или генерации исходного кода. Karma работает с препроцессорами через механизм плагинов, что позволяет создавать собственные обработчики файлов.
Препроцессор в Karma — это функция, которая получает исходный код
файла и возвращает его обработанную версию через callback или промис. Он
регистрируется в конфигурации с помощью объекта
preprocessors и связки с ключом-паттерном, указывающим на
файлы, которые нужно обработать.
module.exports = function(config) {
config.set({
preprocessors: {
'**/*.js': ['myCustomPreprocessor']
},
plugins: [
'karma-*',
require('./karma-my-preprocessor')
]
});
};
Препроцессор представляет собой модуль, экспортирующий фабричную
функцию. Фабрика принимает объект logger и возвращает
функцию, обрабатывающую исходные файлы. Функция препроцессора должна
соответствовать интерфейсу (content, file, done), где:
content — исходный текст файла,file — объект с информацией о файле
(originalPath, path, content и
метод error()),done — callback для передачи результата препроцессинга
или ошибки.Пример минимального собственного препроцессора:
var createPreprocessor = function(logger) {
var log = logger.create('preprocessor:myCustomPreprocessor');
return function(content, file, done) {
log.debug('Обрабатывается файл: ' + file.originalPath);
// Простейшая замена текста в файле
var transformed = content.replace(/console\.log/g, 'customLogger.log');
done(transformed);
};
};
createPreprocessor.$inject = ['logger'];
module.exports = {
'preprocessor:myCustomPreprocessor': ['factory', createPreprocessor]
};
После написания модуля его необходимо зарегистрировать в конфигурации
Karma. Это делается через параметр plugins и указание
препроцессора в объекте preprocessors. Karma автоматически
подхватывает плагин и применяет его к указанным файлам.
Пример расширенной конфигурации:
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
files: [
'src/**/*.js',
'test/**/*.spec.js'
],
preprocessors: {
'src/**/*.js': ['myCustomPreprocessor'],
'test/**/*.spec.js': ['myCustomPreprocessor']
},
plugins: [
'karma-jasmine',
'karma-chrome-launcher',
require('./karma-my-preprocessor')
]
});
};
Препроцессор может выполнять асинхронные операции, например, загрузку
внешних данных, компиляцию TypeScript или чтение файлов. Для этого
done можно вызывать после завершения промиса или
асинхронного вызова.
return function(content, file, done) {
someAsyncTransformation(content)
.then(transformed => done(transformed))
.catch(err => done(file.error(err)));
};
Логирование является ключевым инструментом для разработки
собственного препроцессора. Karma предоставляет объект
logger, который поддерживает уровни debug,
info, warn и error. Использование
log.debug позволяет отслеживать порядок обработки файлов и
внутренние состояния без засорения консоли во время обычного запуска
тестов.
Препроцессор получает полные пути файлов, что позволяет строить
зависимости и определять структуру проекта. Объект file
содержит метод originalPath, который указывает исходное
расположение файла до любых изменений пути. Это особенно полезно при
генерации исходного кода в отдельную директорию или внедрении source
maps.
Для препроцессоров, которые изменяют код, критично сохранять
соответствие исходного и скомпилированного кода через source maps. Karma
не генерирует их автоматически, но позволяет передавать объект
sourceMap вместе с результатом:
done({
code: transformedCode,
map: sourceMapObject
});
Это обеспечивает корректную навигацию в инструментах разработчика и правильное отображение ошибок тестов.
Karma поддерживает последовательное применение нескольких препроцессоров к одному файлу. Порядок обработки определяется порядком массива в конфигурации. Это позволяет комбинировать, например, компиляцию TypeScript с минификацией или внедрением mock-функций для тестирования.
preprocessors: {
'src/**/*.ts': ['typescript', 'myCustomPreprocessor']
}
debug помогает отследить
внутренние изменения кода.file.error() или reject промиса.Создание собственного препроцессора в Karma позволяет гибко адаптировать тестовую среду под особенности проекта, внедрять специфические трансформации и поддерживать современные стандарты JavaScript и TypeScript без потери производительности тестирования.