Конфигурационный файл Webpack традиционно представляет собой JavaScript-модуль, экспортирующий объект или функцию. Для добавления статической типизации без перехода на TypeScript применяется JSDoc-аннотация типов, использующая декларации из пакета Webpack.
Основной механизм основан на @type и импорте типов из
webpack через import():
// webpack.config.js
/** @type {import('webpack').Configuration} */
const config = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: __dirname + '/dist',
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
},
],
},
};
module.exports = config;
Использование import('webpack').Configuration позволяет
редактору и TypeScript Language Service анализировать структуру объекта
конфигурации без преобразования файла в .ts.
Ключевой эффект такого подхода заключается в появлении автодополнения
и статической проверки корректности полей конфигурации, включая
mode, entry, output,
module, plugins, resolve.
Webpack поддерживает экспорт функции, возвращающей конфигурацию. JSDoc сохраняет типизацию и в этом случае:
/** @type {import('webpack').Configuration} */
const baseConfig = {
entry: './src/index.js',
output: {
filename: 'app.js',
path: __dirname + '/dist',
},
};
/**
* @param {import('webpack').Configuration} env
* @param {import('webpack').Configuration} argv
* @returns {import('webpack').Configuration}
*/
module.exports = (env, argv) => {
return {
...baseConfig,
mode: argv.mode || 'production',
};
};
В реальной модели Webpack параметры функции чаще типизируются через
отдельные интерфейсы окружения и аргументов CLI, однако базовая
типизация через Configuration обеспечивает структурную
совместимость.
JSDoc становится значительно более строгим при активации проверки типов в JavaScript-файлах:
// @ts-check
/** @type {import('webpack').Configuration} */
const config = {
mode: 'production',
entry: './src/index.js',
};
module.exports = config;
Директива // @ts-check включает полноценную проверку
файла как TypeScript-контекста, но без компиляции в .ts.
Это позволяет выявлять:
module.rulesdevtool, target,
statsЛокальная типизация часто применяется для сложных правил загрузчиков:
/** @type {import('webpack').RuleSetRule} */
const jsRule = {
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
};
/** @type {import('webpack').Configuration} */
module.exports = {
module: {
rules: [jsRule],
},
};
Тип RuleSetRule обеспечивает проверку структуры
загрузчиков, включая вложенные конфигурации use,
oneOf, loader, options.
Типизация output помогает избежать частых ошибок с
путями:
const path = require('path');
/** @type {import('webpack').Configuration} */
module.exports = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
Поле clean и другие современные свойства становятся
доступными только при актуальной версии типов webpack.
Webpack напрямую поддерживает конфигурацию на TypeScript при использовании Node-совместимого выполнения.
import type { Configuration } from 'webpack';
import path from 'path';
const config: Configuration = {
mode: 'development',
entry: './src/index.ts',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
export default config;
Тип Configuration обеспечивает строгую проверку всей
структуры конфигурации на этапе компиляции TypeScript.
Webpack поддерживает экспорт функции с типизированными аргументами:
import type { Configuration } from 'webpack';
type Env = {
production?: boolean;
};
type Argv = {
mode?: 'development' | 'production';
};
export default (env: Env, argv: Argv): Configuration => {
return {
mode: argv.mode ?? 'production',
entry: './src/index.ts',
output: {
filename: 'bundle.js',
path: __dirname + '/dist',
},
};
};
Такой подход позволяет разделять окружения сборки, сохраняя строгую типизацию входных параметров.
Webpack-плагины также поддерживают типизацию через
webpack.Plugin и специализированные интерфейсы:
import type { Configuration } from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
const config: Configuration = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
],
};
export default config;
TypeScript проверяет корректность конструкторов и параметров плагинов при наличии типов у конкретного пакета.
Раздел resolve часто содержит ошибки из-за сложных
структур путей и алиасов.
import type { Configuration } from 'webpack';
import path from 'path';
const config: Configuration = {
resolve: {
extensions: ['.ts', '.js'],
alias: {
'@src': path.resolve(__dirname, 'src'),
'@utils': path.resolve(__dirname, 'src/utils'),
},
},
};
export default config;
Типизация предотвращает передачу некорректных значений в
extensions и alias, обеспечивая соответствие
строковым массивам и словарным структурам.
Конфигурация devServer в Webpack требует отдельного типа
из webpack-dev-server:
import type { Configuration } from 'webpack';
import type { Configuration as DevServerConfiguration } from 'webpack-dev-server';
interface ExtendedConfiguration extends Configuration {
devServer?: DevServerConfiguration;
}
const config: ExtendedConfiguration = {
devServer: {
port: 3000,
hot: true,
open: true,
},
};
export default config;
Разделение типов необходимо из-за вынесенного пакета сервера разработки.
В проектах с частичной миграцией применяется смешанная схема: часть
конфигурации остаётся в .js, часть в .ts.
// webpack.config.js
/** @type {import('webpack').Configuration} */
const config = {
entry: './src/index.js',
};
module.exports = config;
И отдельные типизированные модули могут экспортировать вспомогательные части:
// webpack.parts.ts
import type { RuleSetRule } from 'webpack';
export const tsRule: RuleSetRule = {
test: /\.ts$/,
use: 'ts-loader',
};
Для более строгого контроля применяется tsconfig.json с
включением проверки JS:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"types": ["webpack"]
}
}
Дополнительно подключаются типы:
@types/webpack@types/nodewebpack-dev-serverЭто формирует единое типовое пространство для конфигурации.
Типизация конфигурации Webpack часто деградирует при следующих условиях:
any в кастомных функциях загрузчиковmodule.rules@ts-check в JS-конфигурацияхОсобенно часто теряется типизация в use: [], где массив
загрузчиков не описан явно и превращается в неструктурированную
конфигурацию.
Типы Webpack формируют сложную иерархию:
ConfigurationModuleOptionsRuleSetRuleResolveOptionsOptimizationOutputOptionsКаждый уровень вложенности проверяется отдельно, что позволяет выявлять ошибки не только синтаксические, но и семантические, например:
mode и devtooloptimization.splitChunksassetModuleFilenameПри росте конфигурации Webpack до десятков плагинов и правил типизация становится механизмом контроля структуры сборки. JSDoc используется как минимальный уровень проверки, TypeScript — как строгая модель описания всей сборочной системы.
Статическая типизация позволяет фиксировать контракт между частями конфигурации, разделёнными по модулям, и предотвращает расхождения между средами разработки и production-сборкой.