高级 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');
// ... all Encore config here
// fetch the config, then modify it!
const config = Encore.getWebpackConfig();
// add an extension
config.resolve.extensions.push('json');
// export the final config
module.exports = config;
但请注意不要意外覆盖 Encore 的任何配置
1 2 3 4 5 6 7 8
// webpack.config.js
// ...
// GOOD - this modifies the config.resolve.extensions array
config.resolve.extensions.push('json');
// BAD - this replaces any extensions added by Encore
// config.resolve.extensions = ['json'];
配置监听选项和轮询
Encore 提供了 configureWatchOptions()
方法,用于在运行 encore dev --watch
或 encore dev-server
时配置 监听选项
1 2 3 4 5
Encore.configureWatchOptions(function(watchOptions) {
// enable polling and check for changes every 250ms
// polling is useful when running Encore inside a Virtual Machine
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
// define the first configuration
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())
;
// build the first configuration
const firstConfig = Encore.getWebpackConfig();
// Set a unique name for the config (needed later!)
firstConfig.name = 'firstConfig';
// reset Encore to build the second config
Encore.reset();
// define the second configuration
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())
;
// build the second configuration
const secondConfig = Encore.getWebpackConfig();
// Set a unique name for the config (needed later!)
secondConfig.name = 'secondConfig';
// export the final configuration as an array of multiple configurations
module.exports = [firstConfig, secondConfig];
运行 Encore 时,两个配置将并行构建。如果您希望单独构建配置,请传递 --config-name
选项
1
$ 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
{# Using the entrypoints.json file located in ./public/first_build #}
{{ encore_entry_script_tags('app', null, 'firstConfig') }}
{{ encore_entry_link_tags('global', null, 'firstConfig') }}
{# Using the entrypoints.json file located in ./public/second_build #}
{{ encore_entry_script_tags('mobile', null, 'secondConfig') }}
{{ encore_entry_link_tags('mobile', null, 'secondConfig') }}
避免渲染多个模板时丢失 CSS
当您在同一请求中渲染两个或多个模板时(例如,两封电子邮件),您应该在 EntrypointLookupInterface
接口上调用 reset()
方法。为此,注入 EntrypointLookupInterface
接口
1 2 3 4 5 6 7
public function __construct(EntrypointLookupInterface $entryPointLookup) {}
public function send() {
$this->twig->render($emailOne);
$this->entryPointLookup->reset();
$this->render($emailTwo);
}
如果您正在使用多个 Webpack 配置(例如,一个用于管理员,一个用于电子邮件),您将需要注入正确的 EntrypointLookupInterface
服务。使用以下命令查找正确的服务
1 2 3 4 5 6 7 8 9
$ php bin/console console debug:container entrypoint_lookup
# You will see a result similar to this:
Select one of the following services to display its information:
[0] webpack_encore.entrypoint_lookup_collection
[1] webpack_encore.entrypoint_lookup.cache_warmer
[2] webpack_encore.entrypoint_lookup[_default]
[3] webpack_encore.entrypoint_lookup[admin]
[4] webpack_encore.entrypoint_lookup[email]
在此示例中,与 email
配置相关的配置是名为 webpack_encore.entrypoint_lookup[email]
的配置。
要将此服务注入到您的类中,请使用 bind
选项
1 2 3 4 5
# config/services.yaml
services:
_defaults
bind:
Symfony\WebpackEncoreBundle\Asset\EntrypointLookupInterface $entryPointLookupEmail: '@webpack_encore.entrypoint_lookup[email]'
现在您可以将您的服务注入到您的类中
1 2 3 4 5 6 7
public function __construct(EntrypointLookupInterface $entryPointLookupEmail) {}
public function send() {
$this->twig->render($emailOne);
$this->entryPointLookupEmail->reset();
$this->render($emailTwo);
}
生成不使用命令行界面的 Webpack 配置对象
通常,您会通过从命令行界面调用 Encore 来使用 webpack.config.js
文件。但有时,某些不使用 Encore 的工具(例如,测试运行器,如 Karma)可能需要访问生成的 Webpack 配置。
问题是,如果您尝试在不使用 encore
命令的情况下生成该 Webpack 配置对象,您将遇到以下错误
1
Error: Encore.setOutputPath() cannot 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');
// Set the runtime environment
Encore.configureRuntimeEnvironment('dev');
// Retrieve the Webpack configuration object
const webpackConfig = require('./webpack.config');
如果需要,您还可以将通常从命令行界面使用的所有选项传递给该方法
1 2 3 4 5 6
Encore.configureRuntimeEnvironment('dev-server', {
// Same options you would use with the
// CLI utility, with their name in camelCase.
https: true,
keepPublicPath: true,
});
完全控制加载器规则
configureLoaderRule()
方法提供了一种干净的方式来配置 Webpack 加载器规则(module.rules
,请参阅 配置)。
这是一个底层方法。您的所有修改将在加载器规则推送到 Webpack 之前应用。这意味着您可以覆盖 Encore 提供的默认配置,这可能会破坏某些东西。使用时请小心。
一个用途可能是配置 eslint-loader
以也对 Vue 文件进行 lint 检查。以下代码是等效的
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Manually
const webpackConfig = Encore.getWebpackConfig();
const eslintLoader = webpackConfig.module.rules.find(rule => rule.loader === 'eslint-loader');
eslintLoader.test = /\.(jsx?|vue)$/;
return webpackConfig;
// Using 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
配置导入或请求模块时的别名
Webpack resolve.alias 选项允许创建别名,以简化某些模块的 import
或 require
(例如,通过别名常用 src/
文件夹)。在 Webpack Encore 中,您可以通过 addAliases()
方法使用此选项
1 2 3 4
Encore.addAliases({
Utilities: path.resolve(__dirname, 'src/utilities/'),
Templates: path.resolve(__dirname, 'src/templates/')
})
使用上述配置,您现在可以更简洁地导入某些模块
1 2
-import Utility from '../../utilities/utility';
+import Utility from 'Utilities/utility';
从输出捆绑包中排除某些依赖项
Webpack externals 选项允许阻止捆绑某些导入的包,而是在运行时检索这些外部依赖项。此功能对于 JavaScript 库开发人员最有用,因此您可能不需要它。
在 Webpack Encore 中,您可以通过 addExternals()
方法使用此选项
1 2 3 4 5 6 7
// this won't include jQuery and React in the output bundles generated
// by Webpack Encore. You'll need to load those dependencies yourself
// (e.g with a `<script>` tag) to make the application or website work.
Encore.addExternals({
jquery: 'jQuery',
react: 'react'
})