Encore:設定你的專案
在安裝 Encore之後,您的應用程式已經有一些檔案,組織在 assets/
目錄中
assets/app.js
assets/styles/app.css
使用 Encore,將您的 app.js
檔案視為獨立的 JavaScript 應用程式:它將請求它需要的所有依賴項(例如 jQuery 或 React),包括任何 CSS。您的 app.js
檔案已經使用 JavaScript import
語句執行此操作
1 2 3 4
// assets/app.js
// ...
import './styles/app.css';
Encore 的工作(透過 Webpack)很簡單:讀取並遵循所有 import
語句,並建立一個最終的 app.js
(和 app.css
),其中包含您的應用程式所需的一切。Encore 可以做更多的事情:縮小檔案、預處理 Sass/LESS、支援 React、Vue.js 等。
設定 Encore/Webpack
Encore 中的所有內容都透過專案根目錄中的 webpack.config.js
檔案進行設定。它已經包含您需要的基本設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// webpack.config.js
const Encore = require('@symfony/webpack-encore');
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
.addEntry('app', './assets/app.js')
// uncomment this if you want use jQuery in the following example
.autoProvidejQuery()
;
// ...
關鍵部分是 addEntry()
:這告訴 Encore 載入 assets/app.js
檔案並遵循所有 require()
語句。然後,它將所有內容打包在一起,並感謝第一個 app
參數,將最終的 app.js
和 app.css
檔案輸出到 public/build
目錄中。
若要建置 assets,如果您使用 npm 套件管理器,請執行以下命令
1 2 3 4 5 6 7 8 9 10 11
# compile assets and automatically re-compile when files change
$ npm run watch
# or, run a dev-server that can sometimes update your code without refreshing the page
$ npm run dev-server
# compile assets once
$ npm run dev
# on deploy, create a production build
$ npm run build
所有這些命令(例如 dev
或 watch
)都是在您的 package.json
檔案中定義的快捷方式。
提示
如果您使用 Symfony CLI 工具,您可以設定 workers 與 webserver 自動一起執行。您可以在Symfony CLI Workers 文件中找到更多資訊。
警告
每當您在 webpack.config.js
檔案中進行變更時,您必須停止並重新啟動 encore
。
恭喜!您現在有三個新檔案
public/build/app.js
(包含您的 “app” 入口點的所有 JavaScript)public/build/app.css
(包含您的 “app” 入口點的所有 CSS)public/build/runtime.js
(一個協助 Webpack 完成其工作的檔案)
注意
實際上,您可能在 public/build
中有更多檔案。其中一些是由於程式碼分割,這是一種有助於效能的優化,但不影響事物的工作方式。其他的則協助 Encore 完成其工作。
接下來,若要將這些包含在您的基礎版面配置中,您可以利用 WebpackEncoreBundle 中的兩個 Twig 輔助函式
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
{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<!-- ... -->
{% block stylesheets %}
{# 'app' must match the first argument to addEntry() in webpack.config.js #}
{{ encore_entry_link_tags('app') }}
<!-- Renders a link tag (if your module requires any CSS)
<link rel="stylesheet" href="/build/app.css"> -->
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
<!-- Renders app.js & a webpack runtime.js file
<script src="/build/runtime.js" defer></script>
<script src="/build/app.js" defer></script>
See note below about the "defer" attribute -->
{% endblock %}
</head>
<!-- ... -->
</html>
就是這樣!當您重新整理頁面時,來自 assets/app.js
的所有 JavaScript(以及它包含的任何其他 JavaScript 檔案)都將被執行。所有請求的 CSS 檔案也將顯示。
encore_entry_link_tags()
和 encore_entry_script_tags()
函式從 Encore 產生的 public/build/entrypoints.json
檔案中讀取,以了解要呈現的確切檔案名稱。此檔案特別有用,因為您可以啟用版本控制或將 assets 指向 CDN,而無需對您的範本進行任何變更:entrypoints.json
中的路徑將始終是最終的正確路徑。如果您使用 splitEntryChunks()(Webpack 在其中將輸出分割成更多檔案),則所有必要的 script
和 link
標籤將自動呈現。
如果您未使用 Symfony,您將無法使用 encore_entry_*
函式。相反地,您可以直接指向最終建置的檔案,或編寫程式碼手動解析 entrypoints.json
。只有在您使用某些選用功能(例如 splitEntryChunks()
)時,才需要 entrypoints 檔案。
1.9.0
script
標籤上的 defer
屬性會延遲 JavaScript 的執行,直到頁面載入完成(類似於將 script
放在頁面底部)。在 WebpackEncoreBundle 1.9.0 中引入了始終新增此屬性的功能,並在 config/packages/webpack_encore.yaml
檔案中該套件的 recipe 中自動啟用。請參閱 WebpackEncoreBundle 設定 以取得更多詳細資訊。
請求 JavaScript 模組
Webpack 是一個模組打包器,這表示您可以 import
其他 JavaScript 檔案。首先,建立一個匯出函式、類別或任何其他值的文件
1 2 3 4
// assets/greet.js
export default function(name) {
return `Yo yo ${name} - welcome to Encore!`;
};
我們將使用 jQuery 在頁面上印出此訊息。透過以下方式安裝它
1
$ npm install jquery --save-dev
太棒了!使用 import
來匯入 jquery
和 greet.js
1 2 3 4 5 6 7 8 9 10 11 12 13
// assets/app.js
// ...
+ // loads the jquery package from node_modules
+ import $ from 'jquery';
+ // import the function from greet.js (the .js extension is optional)
+ // ./ (or ../) means to look for a local file
+ import greet from './greet';
+ $(document).ready(function() {
+ $('body').prepend('<h1>'+greet('jill')+'</h1>');
+ });
就是這樣!如果您先前執行了 encore dev --watch
,則您的最終建置檔案已更新:jQuery 和 greet.js
已自動新增至輸出檔案(app.js
)。重新整理以查看訊息!
Stimulus & Symfony UX
雖然上面的範例很簡單,但我們建議使用 Stimulus,而不是在 app.js
內部建置您的應用程式:一個小型 JavaScript 框架,可讓您輕鬆地將行為附加到 HTML。它功能強大,您會喜歡它!Symfony 甚至提供套件來為 Stimulus 新增更多功能。這些稱為 Symfony UX 套件。
若要使用 Stimulus,請先安裝 StimulusBundle
1
$ composer require symfony/stimulus-bundle
Flex recipe 應該新增幾個檔案/目錄
assets/bootstrap.js
- 初始化 Stimulus;assets/controllers/
- 您將放置 Stimulus 控制器的目錄;assets/controllers.json
- 檔案,可協助載入您將安裝的 UX 套件中的 Stimulus 控制器。
讓我們看一下簡單的 Stimulus 範例。在 Twig 範本中,假設您有
1 2 3 4 5 6 7 8 9
<div {{ stimulus_controller('say-hello') }}>
<input type="text" {{ stimulus_target('say-hello', 'name') }}>
<button {{ stimulus_action('say-hello', 'greet') }}>
Greet
</button>
<div {{ stimulus_target('say-hello', 'output') }}></div>
</div>
stimulus_controller('say-hello')
呈現 data-controller="say-hello"
屬性。每當此元素出現在頁面上時,Stimulus 將自動尋找並初始化名為 say-hello-controller.js
的控制器。在您的 assets/controllers/
目錄中建立該控制器
1 2 3 4 5 6 7 8 9 10
// assets/controllers/say-hello-controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['name', 'output']
greet() {
this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`
}
}
結果?當您點擊 “Greet” 按鈕時,它會印出您的名字!如果將更多 {{ stimulus_controller('say-hello') }}
元素新增到頁面(例如透過 Ajax),這些元素也會立即運作:無需重新初始化任何內容。
準備好了解更多關於 Stimulus 的資訊了嗎?
- 閱讀 Stimulus 文件
- 了解更多關於 StimulusBundle 和 UX 系統
-
螢幕錄影
或在 SymfonyCasts 上查看 Stimulus 螢幕錄影。
Turbo:閃電般快速的單頁應用程式體驗
Symfony 緊密整合了另一個名為 Turbo 的 JavaScript 函式庫。Turbo 自動將所有連結點擊和表單提交轉換為 Ajax 呼叫,而您的 Symfony 程式碼幾乎(或完全)無需變更!結果?您獲得了單頁應用程式的速度,而無需編寫任何 JavaScript。
若要了解更多資訊,請查看 symfony/ux-turbo 套件。
螢幕錄影
或在 SymfonyCasts 上查看 Turbo 螢幕錄影。
頁面特定的 JavaScript 或 CSS
到目前為止,您只有一個最終的 JavaScript 檔案:app.js
。Encore 可能會為了效能而分割成多個檔案(請參閱分割區塊),但所有這些程式碼仍然會在每個頁面上下載。
如果您有一些額外的 JavaScript 或 CSS(例如為了效能),您只想在特定頁面上包含,該怎麼辦?
延遲載入控制器
如果您使用 Stimulus,一個非常好的解決方案是利用 延遲載入控制器。若要在控制器上啟用此功能,請在您的控制器類別上方新增特殊的 stimulusFetch: 'lazy'
1 2 3 4 5 6 7
// assets/controllers/lazy-example-controller.js
import { Controller } from '@hotwired/stimulus';
/* stimulusFetch: 'lazy' */
export default class extends Controller {
// ...
}
就是這樣!此控制器的程式碼(及其匯入的任何模組)將由 Encore 分割到個別檔案。然後,這些檔案將不會被下載,直到符合的元素(例如 <div data-controller="lazy-example">
)出現在頁面上!
注意
如果您使用 TypeScript 編寫控制器,請確保 removeComments
在您的 TypeScript 設定中未設定為 true
。
多個入口點
另一個選項是建立頁面特定的 JavaScript 或 CSS(例如 checkout、account 等)。若要處理此問題,請為每個頁面建立新的 “entry” JavaScript 檔案
1 2
// assets/checkout.js
// custom code for your checkout page
1 2
// assets/account.js
// custom code for your account page
接下來,使用 addEntry()
告訴 Webpack 在建置時讀取這兩個新檔案
1 2 3 4 5 6 7
// webpack.config.js
Encore
// ...
.addEntry('app', './assets/app.js')
+ .addEntry('checkout', './assets/checkout.js')
+ .addEntry('account', './assets/account.js')
// ...
由於您剛才變更了 webpack.config.js
檔案,請務必停止並重新啟動 Encore
1
$ npm run watch
Webpack 現在將在您的建置目錄中輸出新的 checkout.js
檔案和新的 account.js
檔案。而且,如果這些檔案中的任何一個請求/匯入 CSS,Webpack 也會輸出 checkout.css
和 account.css
檔案。
最後,在您需要它們的個別頁面上包含 script
和 link
標籤
1 2 3 4 5 6 7 8 9 10 11 12
{# templates/.../checkout.html.twig #}
{% extends 'base.html.twig' %}
+ {% block stylesheets %}
+ {{ parent() }}
+ {{ encore_entry_link_tags('checkout') }}
+ {% endblock %}
+ {% block javascripts %}
+ {{ parent() }}
+ {{ encore_entry_script_tags('checkout') }}
+ {% endblock %}
現在,結帳頁面將包含 app
入口點的所有 JavaScript 和 CSS(因為這包含在 base.html.twig
中,並且有 {{ parent() }}
呼叫)和您的 checkout
入口點。有了這個,每個頁面所需的 JavaScript 和 CSS 都可以放在 app
入口點內,而僅結帳頁面所需的程式碼可以放在 checkout
內。
使用 Sass/LESS/Stylus
您已經掌握了 Encore 的基礎知識。真棒!但是,如果您需要它們,還有許多其他功能可供您選擇使用。例如,您可以改用 Sass、LESS 或 Stylus,而不是使用純 CSS。若要使用 Sass,請將 app.css
檔案重新命名為 app.scss
並更新 import
語句
1 2 3
// assets/app.js
- import './styles/app.css';
+ import './styles/app.scss';
然後,告訴 Encore 啟用 Sass 預處理器
1 2 3 4 5 6
// webpack.config.js
Encore
// ...
+ .enableSassLoader()
;
由於您剛才變更了 webpack.config.js
檔案,因此您需要重新啟動 Encore。當您執行此操作時,您會看到錯誤!
1
> Error: Install sass-loader & sass to use enableSassLoader()
Encore 支援許多功能。但是,當您需要某個功能時,Encore 不會強迫您使用所有功能,而是會告訴您需要安裝什麼。執行
1 2
$ npm install sass-loader@^13.0.0 sass --save-dev
$ npm run watch
您的應用程式現在支援 Sass。Encore 也支援 LESS 和 Stylus。請參閱CSS 預處理器:Webpack Encore 的 Sass 等。
僅編譯 CSS 檔案
警告
支援使用 addStyleEntry()
,但不建議使用。更好的選擇是遵循上面的模式:使用 addEntry()
指向 JavaScript 檔案,然後從該檔案內部請求所需的 CSS。
如果您只想編譯 CSS 檔案,可以透過 addStyleEntry()
實現
1 2 3 4 5 6
// webpack.config.js
Encore
// ...
.addStyleEntry('some_page', './assets/styles/some_page.css')
;
這將輸出一個新的 some_page.css
。
繼續前進!
Encore 支援更多功能!如需您可以執行的完整列表,請參閱 Encore 的 index.js 檔案。或者,回到前端文章列表。