跳到內容

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.jsapp.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

所有這些命令(例如 devwatch)都是在您的 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 在其中將輸出分割成更多檔案),則所有必要的 scriptlink 標籤將自動呈現。

如果您未使用 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 來匯入 jquerygreet.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 的資訊了嗎?

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.cssaccount.css 檔案。

最後,在您需要它們的個別頁面上包含 scriptlink 標籤

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 檔案。或者,回到前端文章列表

這項工作,包括程式碼範例,均根據 Creative Commons BY-SA 3.0 授權條款授權。
目錄
    版本