Продвинутая конфигурация Webpack

Дата обновления перевода 2023-01-17

Продвинутая конфигурация Webpack

Если подытожить, Encore генерирует конфигурацию Webpack, которая используется в вашем файле webpack.config.js. Encore не поддерживаетдобавление всех опций конфигурации Webpack, так как многие вы можете с лёгкостью добавить сами.

Например, представьте, что вам нужно автоматически разрешить новое расширение. Чтобы сделать это, измените конфигурацию после её извлечения из Encore:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// webpack.config.js

const Encore = require('@symfony/webpack-encore');

// ... здесь вся конфигурация Encore

// получите конфигурацию, а потом измените её!
const config = Encore.getWebpackConfig();


// добавьте расширение
config.resolve.extensions.push('json');

// экспортируйте финальую конфигурацию
module.exports = config;

Но будьте осторожны, чтобы случайно не переопределить никакую конфигурацию из Encore:

1
2
3
4
5
6
7
8
// webpack.config.js
// ...

// ХОРОШО - изменяет массив config.resolve.extensions
config.resolve.extensions.push('json');

// ПЛОХО - заменяет любые расширения, добавленные Encore
// config.resolve.extensions = ['json'];

Конфигурация опций наблюдения и опросы

Encore предоставляет метод configureWatchOptions() для конфигурации Опций наблюдения при запуске encore dev --watch или encore dev-server:

1
2
3
4
5
Encore.configureWatchOptions(function(watchOptions) {
    // включить опросы и проверять изменения каждые 250 мс
    // опросы полезны при запуске Encore внутри виртуальной машины
    watchOptions.poll = 250;
});

Определение множества конфигураций Webpack

Webpack поддерживает передачу массива конфигураций, которые обрабатываются параллельно. Webpack Encore включает в себя объект reset(), позволяющий перезапустить состояние текущей конфигурации, чтобы построить новую:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// определить первую конфигурацию
Encore
    .setOutputPath('public/build/first_build/')
    .setPublicPath('/build/first_build')
    .addEntry('app', './assets/app.js')
    .addStyleEntry('global', './assets/styles/global.scss')
    .enableSassLoader()
    .autoProvidejQuery()
    .enableSourceMaps(!Encore.isProduction())
;

// построить первую конфигурацию
const firstConfig = Encore.getWebpackConfig();

// Установить уникальное имя для конфигурации (понадобится позже!)
firstConfig.name = 'firstConfig';

// перезапустить Encore, чтобы построить вторую конфигурацию
Encore.reset();

// определить вторую конфигурацию
Encore
    .setOutputPath('public/build/second_build/')
    .setPublicPath('/build/second_build')
    .addEntry('mobile', './assets/mobile.js')
    .addStyleEntry('mobile', './assets/styles/mobile.less')
    .enableLessLoader()
    .enableSourceMaps(!Encore.isProduction())
;

// построить вторую конфигурацию
const secondConfig = Encore.getWebpackConfig();

// Установить уникальное имя для конфигурации (понадобится позже!)
secondConfig.name = 'secondConfig';

// экспортировать финальную конфигурацию в качестве массива множества конфигураций
module.exports = [firstConfig, secondConfig];

При запуске Encore, обе конфигурации будут построены параллельно. Если вы предпочитаете строить конфигурации отдельно, передайте опцию --config-name:

1
2
3
4
5
# если вы используете менеджер пакетов Yarn
$ yarn encore dev --config-name firstConfig

# если вы используете менеджер пакетов npm
$ npm run dev -- --config-name firstConfig

Далее, определите каталоги вывода каждой компоновки:

1
2
3
4
5
6
# config/packages/webpack_encore.yaml
webpack_encore:
    output_path: '%kernel.project_dir%/public/default_build'
    builds:
        firstConfig: '%kernel.project_dir%/public/first_build'
        secondConfig: '%kernel.project_dir%/public/second_build'

Также определите манифесты ресурсов для каждой компоновки:

1
2
3
4
5
6
7
8
# config/packages/assets.yaml
framework:
    assets:
        packages:
            first_build:
                json_manifest_path: '%kernel.project_dir%/public/first_build/manifest.json'
            second_build:
                json_manifest_path: '%kernel.project_dir%/public/second_build/manifest.json'

Наконец, используйте третий необязательный параметр функций encore_entry_*_tags(), чтобы указать, какую компоновку использовать:

1
2
3
4
5
6
7
{# Использование файла entrypoints.json, расположенного в ./public/first_build #}
{{ encore_entry_script_tags('app', null, 'firstConfig') }}
{{ encore_entry_link_tags('global', null, 'firstConfig') }}

{# Использование файла entrypoints.json, расположенного в ./public/second_build #}
{{ encore_entry_script_tags('mobile', null, 'secondConfig') }}
{{ encore_entry_link_tags('mobile', null, 'secondConfig') }}

Генерирование объекта конфигурации Webpack без использования интерфейса командной строки

Обычно вы будете использовать ваш файл webpack.config.js вызывая Encore из интерфейса командной строки. Но иногда, доступ к сгенерированной конфигурации Webpack можент понадобиться инструментам, не использующим Encore (например, исполнителю тестов, вроде Karma).

Проблема в том, что если вы попробуете сгенерировать этот объект конфигурации Webpack без использования команды encore, вы столкнетесь со следующей ошибкой:

1
Error: Encore.setOutputPath() be called yet because the runtime environment doesn't appear to be configured. Make sure you're using the encore executable or call Encore.configureRuntimeEnvironment() first if you're purposely not calling Encore directly.

Причиной этого сообщения является то, что Encore необходимо знать несколько вещей перед тем, как создать объект конфигурации, и самая важная из них - каково целевое окружение.

Чтобы решить эту проблему, вы можете использовать configureRuntimeEnvironment. Этот метод должен быть вызван из файла JavaScript до требования webpack.config.js.

Например:

1
2
3
4
5
6
7
const Encore = require('@symfony/webpack-encore');

// Установить окружение выполнения
Encore.configureRuntimeEnvironment('dev');

// Извлечь объект конфигурации Webpack
const webpackConfig = require('./webpack.config');

Если необходимо, вы также можете передать этому методу все опции, которые вы обычно использовали бы из интерфейса командной строки:

1
2
3
4
5
6
Encore.configureRuntimeEnvironment('dev-server', {
    // Те же опции, которые вы бы использовали с
    // утилитой CLI, с именами в camelCase.
    https: true,
    keepPublicPath: true,
});

Полный контроль над правилами загрузчиков

Метод configureLoaderRule() предоставляет прямой путь для конфигурации правил загрузчиков Webpack (module.rules, см. Конфигурация).

Это метод нижнего уровня, Все ваши модификации будут применены прямо перед отправкой правил загрузчиков в Webpack. Это означает, что вы можете переопределеить конфигурацию по умолчанию предоставленную Encore, что может что-то сломать. Будьте осторожны при использовании.

Одним из способов применения может быть сконфигурировать eslint-loader, чтобы контролировать ещё и файлы Vue. Следующий код эквивалентен:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Вручную
const webpackConfig = Encore.getWebpackConfig();

const eslintLoader = webpackConfig.module.rules.find(rule => rule.loader === 'eslint-loader');
eslintLoader.test = /\.(jsx?|vue)$/;

return webpackConfig;

// Используя Encore.configureLoaderRule()
Encore.configureLoaderRule('eslint', loaderRule => {
    loaderRule.test = /\.(jsx?|vue)$/
});

return Encore.getWebpackConfig();
Следующие загрузчики можно сконфигурировать с помощью configureLoaderRule():
  • javascript (псевдоним js)
  • css
  • images (но вместо него используйте configureImageRule())
  • fonts (но вместо него используйте configureFontRule())
  • sass (псевдоним scss)
  • less
  • stylus
  • svelte
  • vue
  • eslint
  • typescript (псевдоним ts)
  • handlebars