opctim / vite-bundle-php72
Vite 对你的 Symfony 应用程序的集成
Requires
- php: ^7.2 || ^8.0
- symfony/asset: ^4.4 || ^5.0 || ^6.0
- symfony/config: ^4.4 || ^5.0 || ^6.0
- symfony/dependency-injection: ^4.4 || ^5.0 || ^6.0
- symfony/framework-bundle: ^4.4 || ^5.0 || ^6.0
- symfony/http-client: ^4.4 || ^5.0 || ^6.0
- symfony/http-kernel: ^4.4 || ^5.0 || ^6.0
- symfony/twig-bundle: ^4.4 || ^5.0 || ^6.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.9
- phpstan/phpstan: ^1.8
README
ViteBundle : Vite 与 Symfony 的集成
此包帮助您渲染所有必要的动态 script 和 link 标签。本质上,它提供了两个 Twig 函数来将正确的脚本加载到模板中。
安装
开始之前,请确保您没有 package.json 文件,或者如果您来自 Webpack Encore,请检查迁移文档。
使用以下命令安装该包:
composer require pentatrion/vite-bundle
npm install
# start your vite dev server
npm run dev
在任何需要包含 JavaScript 入口的模板或基础布局中添加此 Twig 函数。
{% block stylesheets %}
{{ vite_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ vite_entry_script_tags('app') }}
{% endblock %}
如果您遇到应用程序意外重新加载的问题,请阅读https/http 在开发中部分。
如果您想减少 FOUC(内容闪现),请阅读 css 文件作为入口点部分。
如果您使用 React,您必须添加此选项才能使用 FastRefresh。
{{ vite_entry_script_tags('app', { dependency: 'react' }) }}
如果您想不带社区食谱安装包,请检查手动安装。
包配置
如果您更改了 vite.config.js 文件中的某些属性,您可能需要创建一个 config/packages/pentatrion_vite.yaml 文件来推迟这些更改。这关系到 server.host、server.port、server.https 和 build.outdir(以及 base)。
默认配置
# config/packages/pentatrion_vite.yaml pentatrion_vite: # path to the web root relative to the Symfony project root directory public_dir: /public # Base public path when served in development or production base: /build/ script_attributes: # you can define your attributes that you want to apply # for all your script tags link_attributes: # you can define your attributes that you want to apply # for all your link tags # only if you have multiple vite.config files # leave keys : base, script_attributes, link_attributes empty # and fill in the following default_build: <custom-build-name-1> builds: <custom-build-name-1>: # Base public path when served in development or production base: /build1/ script_attributes: # etc link_attributes: # etc
Vite 配置
出于透明度考虑,我决定不创建配置文件 vite.config.js 的覆盖。您可以在github 仓库中查看 vite-plugin-symfony 的完整文档。
// vite.config.js import {defineConfig} from "vite"; import symfonyPlugin from "vite-plugin-symfony"; /* if you're using React */ // import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [ /* react(), // if you're using React */ symfonyPlugin(), ], build: { rollupOptions: { input: { /* relative to the root option */ app: "./assets/app.ts", /* you can also provide css files to prevent FOUC */ theme: "./assets/theme.css" }, } }, });
Twig 函数
该包提供了 2 个 Twig 函数,两者都接受一个可选的第二个参数(选项)和一个可选的第三个参数 buildName(如果您有多个构建,请参阅#多个 Vite 配置部分)。
vite_entry_script_tags
选项
- dependency: 'react' | null
- attr: Array (一个额外的属性数组)
vite_entry_script_tags('<entrypoint>', {
dependency: 'react',
attr: {
referrerpolicy: "origin"
}
})
vite_entry_link_tags
选项
- attr: Array (一个额外的属性数组)
vite_entry_link_tags('<entrypoint>', {
attr: {
media: "screen and (prefers-color-scheme: dark)"
}
})
如果您定义了多个构建
vite_entry_script_tags('<entrypoint>', {}, '<custom-build-name-1>')
Vite 资产管理
当您在 js 或 css 文件中引用资产文件时,请记住,如果您想 Vite 处理您的文件,则需要使用相对路径。
- 所有使用绝对路径定义的文件都将被 Vite 忽略,并将作为原样保留在构建文件中。您可以指定一个相对于公共文件夹的绝对路径。这种做法不推荐,因为您的资产文件将不会被版本化。
- 所有使用相对路径定义的文件都将被 Vite 处理。路径相对于引用它们的文件。通过相对路径引用的所有资产都将被 Vite 重写、版本化和捆绑。
Symfony 资产组件
每次您构建 Vite 应用程序时,您的输出文件夹(默认位置:public/build/)中都会生成两个配置文件:manifest.json(由 Vite 核心生成),entrypoints.json(由 vite-plugin-symfony 生成)。
manifest.json 文件用于获取资产文件的版本化文件名,如字体文件或图像文件。
因此,您可以使用 Symfony 的资产组件及其资产函数来利用此文件。为了能够在开发期间使用它,您将必须使用 ViteAssetVersionStrategy。
# config/packages/framework.yaml framework: assets: version_strategy: 'Pentatrion\ViteBundle\Asset\ViteAssetVersionStrategy'
您还可以通过指定您的资产文件路径(相对于根路径,出于与 vite 生成清单文件的兼容性考虑)来使用资产 twig 函数,在您的 vite.config.js 中指定。
<body> <img src="{{ asset('assets/images/avatar.jpg') }}" /> </body>
您只能使用此 asset() 函数与 JavaScript 或 CSS 文件引用的资产一起使用。如果您想使 Vite 了解其他资产,可以将资产目录导入到应用程序的入口点。例如,如果您想对所有存储在 assets/images 的图像进行版本控制,您可以在您的 app 入口点中添加以下内容。
├──assets
│ ├──images
│ │ ├──climbing.jpg
│ │ ├──violin.jpg
│ │ ├──...
│ │
│ ├──app.js
│...
// assets/app.js import.meta.glob([ './images/**' ]);
多个 Vite 配置
可以组合多个 vite 配置文件。以下是一个可能的配置模型。
package.json
{
"scripts": {
"dev": "vite -c vite.build1.config.js & vite -c vite.build2.config.js",
"build": "vite build -c vite.build1.config.js && vite build -c vite.build2.config.js"
}
}
定义 2 个 vite 配置文件 vite.build1.config.js 和 vite.build2.config.js。
// vite.build1.config.js import { defineConfig } from 'vite' import symfonyPlugin from 'vite-plugin-symfony'; export default defineConfig({ plugins: [ symfonyPlugin({ buildDirectory: 'build1' }), ], build: { rollupOptions: { input: { "welcome": "./assets/page/welcome/index.js", "theme": "./assets/theme.scss" }, }, }, server: { port: 19875 }, });
// vite.build2.config.js import { defineConfig } from 'vite' import symfonyPlugin from 'vite-plugin-symfony'; export default defineConfig({ plugins: [ symfonyPlugin({ buildDirectory: 'build2' }), ], build: { rollupOptions: { input: { "multiple": "./assets/page/multiple/build2.js", }, }, }, server: { port: 19876 }, });
在您的 config/packages/pentatrion_vite.yaml 文件中
pentatrion_vite: default_build: build1 builds: build1: base: /build1/ script_attributes: # you can define your attributes that you want to apply # for all your script tags link_attributes: # you can define your attributes that you want to apply # for all your link tags build2: base: /build2/ script_attributes: # etc link_attributes: # etc
在您的模板中
{% block stylesheets %}
{# define your build in the 3rd parameter #}
{{ vite_entry_link_tags('multiple', [], 'build2') }}
{# no 3rd parameters it will be default_build -> build1 #}
{{ vite_entry_link_tags('welcome') }}
{% endblock %}
{% block javascripts %}
{# define your build in the 3rd parameter #}
{{ vite_entry_script_tags('multiple', [], 'build2') }}
{# no 3rd parameters it will be default_build -> build1 #}
{{ vite_entry_script_tags('welcome') }}
{% endblock %}
以显示开发模式下的资产
# config/routes/dev/pentatrion_vite.yaml # remove this default config # _pentatrion_vite: # prefix: /build # resource: "@PentatrionViteBundle/Resources/config/routing.yaml" # add one route by build path _pentatrion_vite_build1: path: /build1/{path} #same as your build1 base defaults: _controller: Pentatrion\ViteBundle\Controller\ViteController::proxyBuild buildName: build1 requirements: path: ".+" _pentatrion_vite_build2: path: /build2/{path} #same as your build2 base defaults: _controller: Pentatrion\ViteBundle\Controller\ViteController::proxyBuild buildName: build2 requirements: path: ".+"
可选:如果想要使用自定义策略的资产 symfony 组件,则需要添加额外的配置...
# config/services.yaml services: pentatrion_vite.asset_strategy_build1: parent: Pentatrion\ViteBundle\Asset\ViteAssetVersionStrategy calls: - [setBuildName, ['build1']] pentatrion_vite.asset_strategy_build2: parent: Pentatrion\ViteBundle\Asset\ViteAssetVersionStrategy calls: - [setBuildName, ['build2']]
# config/packages/framework.yaml framework: assets: packages: build1: # same name as your service defined above version_strategy: 'pentatrion_vite.asset_strategy_build1' build2: version_strategy: 'pentatrion_vite.asset_strategy_build2'
然后您可以像这样使用您的资产
<img src="{{ asset('assets/images/violin.jpg', 'build1')}}" alt="">
使用提示
CSS 文件作为入口点
本节仅讨论开发中的 FOUC(无样式内容闪烁)。通常,在构建过程之后,这种现象不应发生。
默认情况下,如果您从 js 入口点导入 css 文件,vite 开发服务器将为您的 js 和 css 文件创建一个入口点(<script src="https://:5173/build/assets/app.js" type="module"></script>)。您的 css 内容将在之后加载。这导致页面内容一段时间内未进行样式化。这可能很无聊。
但是,您可以为 css/scss/... 文件提供入口点,并将其直接插入为链接标签 <link rel="stylesheet" href="https://:5173/build/assets/theme.scss">。这样,您的浏览器将等待您的 theme.scss 文件加载完毕后再渲染页面。
export default defineConfig({ // ...your config build: { rollupOptions: { input: { theme: "./assets/theme.scss" }, } }, });
注意:即使入口点是 css 文件,仍需添加 2 个 twig 函数 vite_entry_link_tags / vite_entry_script_tags,因为 ViteJs 可能需要插入其 js 代码以启用 hmr
{% block stylesheets %}
{{ vite_entry_link_tags('theme') }}
{% endblock %}
{% block javascripts %}
{{ vite_entry_script_tags('theme') }}
{% endblock %}
将在开发期间渲染
<script src="https://:5173/build/@vite/client" type="module"> <link rel="stylesheet" href="https://:5173/build/assets/theme.scss">
。
依赖项预捆绑
最初在一个 Vite 项目中,index.html 是您应用程序的入口点。当您运行开发服务器时,Vite 将爬取您的源代码并自动发现依赖项导入。
由于我们没有 index.html,当 Vite 启动时无法执行此预捆绑步骤,但当您浏览一个包含他尚未缓存的包的页面时,Vite 将重新运行依赖项捆绑过程并重新加载页面。
如果您的依赖项很多,此行为可能会令人烦恼,因为它会在最终渲染之前创建很多页面重新加载。
您可以在 vite.config.js 中声明项目中最常见的依赖项来限制此行为。
// vite.config.js export default defineConfig({ server: { //Set to true to force dependency pre-bundling. force: true, }, // ... optimizeDeps: { include: ["my-package"], }, });
一个文件由入口点
Vite 尝试将您的 js 文件拆分为多个较小的文件,这些文件在入口点之间共享。在某些情况下,这并不是一个好的选择,您可能更喜欢每个入口点输出一个 js 文件。
// vite.config.js export default defineConfig({ build: { rollupOptions: { output: { manualChunks: undefined, }, }, }, });
https / http 在开发中
默认情况下,您的 Vite 开发服务器不使用 https,如果使用 https 提供应用程序可能会引起不必要的重新加载(可能由于证书无效)。如果您在没有 https 的情况下开发应用程序,配置会更简单。
npm run dev symfony serve --no-tls
浏览:http://127.0.0.1:8000
如果您仍然想使用 https,则需要为您 Vite 开发服务器生成证书。
您可以使用 mkcert:https://github.com/FiloSottile/mkcert
mkcert -install mkcert -key-file certs/vite.key.pem -cert-file certs/vite.crt.pem localhost 127.0.0.1
// vite.config.js import fs from "fs"; export default defineConfig({ // ... server: { https: { key: fs.readFileSync('certs/vite.key.pem'), cert: fs.readFileSync('certs/vite.crt.pem'), }, cors: true }, });
npm run dev symfony serve
浏览:https://127.0.0.1:8000
依赖注入
如果您想有更多的控制(例如创建自定义 Twig 函数),您可以使用依赖注入与 EntrypointRenderer / EntrypointsLookup。
use Twig\Extension\AbstractExtension; use Pentatrion\ViteBundle\Asset\EntrypointRenderer; use Pentatrion\ViteBundle\Asset\EntrypointsLookup; class YourTwigExtension extends AbstractExtension { public function __contruct( private EntrypointsLookup $entrypointsLookup, private EntrypointRenderer $entrypointsRenderer ) { // ... } }
此捆绑如何工作
{% block stylesheets %}
{{ vite_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ vite_entry_script_tags('app') }}
{% endblock %}
将在开发中渲染
<!--Nothing with vite_entry_link_tags('app') --> <!-- vite_entry_script_tags('app') --> <script src="https://:5173/build/@vite/client" type="module"></script> <script src="https://:5173/build/app.js" type="module"></script>
将在生产中渲染
<!-- vite_entry_link_tags('app') --> <link rel="stylesheet" href="/build/app.[hash].css" /> <link rel="modulepreload" href="/build/vendor.[hash].js" /> <!-- vite_entry_script_tags('app') --> <script src="/build/app.[hash].js" type="module"></script>
在开发环境中,该包还充当代理,将不针对它的请求转发到 Vite 开发服务器。
迁移
此版本 3 与 Vite v4 兼容。要从 v2.X 迁移到 v3,您只需将 vite-plugin-symfony 包更新到版本 >= 0.7.2。
Vite-bundle 版本 2 与 Vite v3 兼容。
如果您使用的是该插件的前一个版本,请查阅迁移页面。