Просунута конфігурація Webpack

Дата оновлення перекладу 2022-12-14

Просунута конфігурація Webpack

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

Наприклад, уявіть, що вам потрібно автоматично розвʼязати нове розширення. Щоб зробити це, змініть конфігурацію після її вилучення з Encore:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 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