v7.0.0
更多資訊請前往 rubyonrails.org: 更多在 Ruby on Rails

打包機

本指南將向您展示如何安裝和使用 Webpacker 為 Rails 應用程式的客戶端打包 JavaScript、CSS 和其他資產。

閱讀本指南後,您將瞭解:

1 什麼是 Webpacker?

Webpacker 是 webpack 構建系統的 Rails 包裝器,提供標準的 webpack 設定和合理的預設值。

1.1 什麼是webpack?

webpack 或任何前端構建系統的目標是讓您以一種方便開發人員的方式編寫前端程式碼,然後以一種方便瀏覽器的方式打包這些程式碼。使用 webpack,您可以管理 JavaScript、CSS 和靜態資產,如影象或字型。 Webpack 將允許您編寫程式碼、引用應用程式中的其他程式碼、轉換程式碼並將程式碼組合成易於下載的包。

有關資訊,請參閱 webpack 文件

1.2 Webpacker 與 Sprockets 有何不同?

Rails 還附帶了鏈輪,這是一種資產打包工具,其功能與 Webpacker 重疊。這兩種工具都會將您的 JavaScript 編譯成瀏覽器友好的檔案,並在生產中縮小和指紋它們。在開發環境中,Sprockets 和 Webpacker 允許您增量更改檔案。

鏈輪設計用於與 Rails 一起使用,整合起來更簡單一些。特別是,可以通過 Ruby gem 將程式碼新增到 Sprockets。然而,webpack 更擅長與更多當前的 JavaScript 工具和 NPM 包整合,並允許更廣泛的整合。新的 Rails 應用程式設定為對 JavaScript 使用 webpack,對 CSS 使用 Sprockets,儘管您可以在 webpack 中執行 CSS。

如果您想使用 NPM 包和/或想要訪問最新的 JavaScript 功能和工具,您應該在新專案中選擇 Webpacker 而不是 Sprockets。對於 migration 可能成本較高的遺留應用程式,如果您想使用 Gems 進行整合,或者如果您要打包的程式碼量非常少,您應該選擇 Sprockets 而不是 Webpacker。

如果您熟悉 Sprockets,以下指南可能會讓您對如何翻譯有所瞭解。請注意,每個工具的結構略有不同,並且這些概念不會直接相互對映。

任務 鏈輪 網路打包器
附加 JavaScript javascript_include_tag javascript_pack_tag
附加 CSS stylesheet_link_tag stylesheet_pack_tag
圖片連結 image_url image_pack_tag
連結到資產 asset_url asset_pack_tag
需要指令碼 //= 需要 import 或需要

2 安裝 Webpacker

要使用 Webpacker,您必須安裝 Yarn 包管理器,版本 1.x 或更高版本,並且您必須安裝 Node.js,版本 10.13.0 或更高版本。

Webpacker 依賴於 NPM 和 Yarn。 NPM,Node 包管理器登錄檔,是釋出和下載開源 JavaScript 專案的主要儲存庫,適用於 Node.js 和瀏覽器執行時。它類似於 ruby​​gems.org 的 Ruby gems。 Yarn 是一個命令列實用程式,可以安裝和管理 JavaScript 依賴項,就像 Bundler 為 Ruby 所做的那樣。

要在新專案中包含 Webpacker,請將 --webpack 新增到 rails new 命令。要將 Webpacker 新增到現有專案,請將 webpacker gem 新增到專案的 Gemfile,執行 bundle install,然後執行 ​​bin/rails webpacker:install

安裝 Webpacker 會建立以下本地檔案:

檔案 位置 說明
JavaScript 資料夾 app/javascript 前端源的地方
Webpacker 設定 config/webpacker.yml 設定Webpacker gem
Babel 設定 babel.config.js Babel JavaScript 編譯器的設定
PostCSS 設定 postcss.config.js PostCSS CSS 後處理器的設定
瀏覽器列表 .browserslistrc Browserlist 管理目標瀏覽器設定

安裝還會呼叫 yarn 包管理器,建立一個 package.json 檔案,其中列出了一組基本的包,並使用 Yarn 來安裝這些依賴項。

3 用法

3.1 在 JavaScript 中使用 Webpacker

安裝了 Webpacker 後,app/javascript/packs 目錄中的任何 JavaScript 檔案都會預設編譯為自己的包檔案。

因此,如果您有一個名為 app/javascript/packs/application.js 的檔案,Webpacker 將建立一個名為 application 的包,您可以使用程式碼 <%= javascript_pack_tag "application" %> 將其新增到 Rails 應用程式中。有了它,在開發中,Rails 每次更改時都會重新編譯 application.js 檔案,並且您載入使用該包的頁面。通常,實際 packs 目錄中的檔案將是一個主要載入其他檔案的清單,但它也可以包含任意 JavaScript 程式碼。

Webpacker 為您建立的預設包將連結到 Rails 的預設 JavaScript 包(如果它們已包含在專案中):

import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"

Rails.start()
Turbolinks.start()
ActiveStorage.start()

您需要包含一個包,該包需要這些包才能在您的 Rails 應用程式中使用它們。

需要注意的是,app/javascript/packs目錄下只能放置webpack入口檔案; Webpack 會為每個入口點建立一個單獨的依賴圖,因此大量的包會增加編譯開銷。儘管 Webpacker 不會對如何構建原始碼設定任何限制或提出任何建議,但您的資產原始碼的其餘部分應位於此目錄之外。下面是一個例子:

app/javascript:
  ├── packs:
  │   # only webpack entry files here
  │   └── application.js
  │   └── application.css
  └── src:
  │   └── my_component.js
  └── stylesheets:
  │   └── my_styles.css
  └── images:
      └── logo.svg

通常,包檔案本身主要是一個清單,它使用 importrequire 來載入必要的檔案,也可能會進行一些初始化。

如果要更改這些目錄,可以調整config/webpacker.yml檔案中的source_path(預設為app/javascript)和source_entry_path(預設為packs)。

在原始檔中,import 語句相對於執行匯入的檔案進行解析,因此 import Bar from "./foo" 在與當前檔案相同的目錄中找到一個 foo.js 檔案,而 import Bar from "../src/foo" 在名為 src 的同級目錄中找到一個檔案。

3.2 為 CSS 使用 Webpacker

開箱即用,Webpacker 使用 PostCSS 處理器支援 CSS 和 SCSS。

要在您的包中包含 CSS 程式碼,首先將您的 CSS 檔案包含在您的頂級包檔案中,就像它是一個 JavaScript 檔案一樣。因此,如果您的 CSS 頂級清單在 app/javascript/styles/styles.scss 中,您可以使用 import styles/styles 匯入它。這告訴 webpack 在下載中包含你的 CSS 檔案。要在頁面中實際載入它,請在 view 中包含 <%= stylesheet_pack_tag "application" %>,其中 application 與您使用的包名稱相同。

如果您使用的是 CSS 框架,則可以按照說明將框架作為 NPM module 使用 yarn(通常為 yarn add <framework>)載入到 Webpacker 中。框架應該有關於將其匯入 CSS 或 SCSS 檔案的說明。

3.3 使用 Webpacker 處理靜態資產

預設的 Webpacker 設定 應該對靜態資產開箱即用。 該設定包括多個影象和字型檔案格式擴充套件,允許 webpack 將它們包含在產生的 manifest.json 檔案中。

使用 webpack,可以直接在 JavaScript 檔案中匯入靜態資產。匯入的 value 表示資產的 URL。例如:

import myImageUrl from '../images/my-image.jpg'

// ...
let myImage = new Image();
myImage.src = myImageUrl;
myImage.alt = "I'm a Webpacker-bundled image";
document.body.appendChild(myImage);

如果您需要從 Rails view 引用 Webpacker 靜態資產,則需要從 Webpacker 捆綁的 JavaScript 檔案中明確要求這些資產。與 Sprockets 不同,Webpacker 預設不會匯入您的靜態資源。預設的 app/javascript/packs/application.js 檔案有一個用於從給定目錄匯入檔案的模板,您可以為每個要在其中放置靜態檔案的目錄取消註釋。這些目錄與 app/javascript 相關。該模板使用目錄 images,但您可以使用 app/javascript 中的任何內容:

const images = require.context("../images", true)
const imagePath = name => images(name, true)

靜態資源將輸出到 public/packs/media 下的目錄中。例如,位於 app/javascript/images/my-image.jpg 並匯入的影象將在 public/packs/media/images/my-image-abcd1234.jpg 輸出。要在 Rails view 中為該影象渲染影象標記,請使用 image_pack_tag 'media/images/my-image.jpg

靜態資源的Webpacker ActionView helpers對應的asset pipeline helpers如下表:

ActionView helper Webpacker helper
favicon_link_tag favicon_pack_tag
image_tag image_pack_tag

此外,通用 helper asset_pack_path 獲取檔案的本地位置並返回其 Webpacker 位置以用於 Rails views。

您還可以通過直接從 app/javascript 中的 CSS 檔案引用檔案來訪問影象。

Rails 引擎中的 ### Webpacker

從 Webpacker 版本 6 開始,Webpacker 不是“引擎感知的”,這意味著 Webpacker 在 Rails 引擎中使用時不具有與鏈輪相同的功能。

鼓勵希望支援使用 Webpacker 的消費者的 Rails 引擎的 Gem 作者將前端資產作為 NPM 包分發到 gem 本身,並提供說明(或安裝程式)來演示主機應用程式應該如何整合。這種方法的一個很好的例子是 Alchemy CMS

3.4 熱 Module 更換 (HMR)

Webpacker 開箱即用地支援帶有 webpack-dev-server 的 HMR,您可以通過在 webpacker.yml 中設定 dev_server/hmr 選項來切換它。

檢視 webpack 在 DevServer 上的文件 瞭解更多資訊。

要使用 React 支援 HMR,您需要新增 react-hot-loader。檢視 React Hot Loader 的 Getting Started 指南

如果您沒有執行 webpack-dev-server,請不要忘記禁用 HMR;否則,您將收到樣式表的“未找到錯誤”。

4 不同環境下的Webpacker

Webpacker 預設有 developmenttestproduction 三種環境。您可以在 webpacker.yml 檔案中新增其他環境設定,併為每個環境設定不同的預設值。 Webpacker 還將載入檔案 config/webpack/<environment>.js 以進行額外的環境設定。

5 在開發中執行 Webpacker

Webpacker 附帶了兩個要在開發中執行的 binstub 檔案:./bin/webpack./bin/webpack-dev-server。兩者都是標準 webpack.jswebpack-dev-server.js 可執行檔案的瘦包裝器,並確保根據您的環境載入正確的設定檔案和環境變數。

預設情況下,當 Rails 頁面載入時,Webpacker 會在開發中按需自動編譯。這意味著您不必執行任何單獨的程序,並且編譯錯誤將被記錄到標準的 Rails 日誌中。您可以通過在 config/webpacker.yml 檔案中更改為 compile: false 來更改此設定。執行 bin/webpack 將強制編譯您的包。

如果你想使用實時程式碼重新載入或有足夠多的 JavaScript 以至於按需編譯太慢,你需要執行 ./bin/webpack-dev-serverruby ./bin/webpack-dev-server。此過程將監視 app/javascript/packs/*.js 檔案中的更改並自動重新編譯並重新載入瀏覽器以進行匹配。

Windows 使用者需要在與 bundle exec rails server 分開的終端中執行這些命令。

一旦你啟動了這個開發伺服器,Webpacker 將自動開始將所有 webpack 資產請求代理到這個伺服器。當您停止伺服器時,它將恢復為按需編譯。

Webpacker 文件 提供了有關可用於控制 webpack-dev-server 的環境變數的資訊。請參閱 rails/webpacker 文件中關於 webpack-dev-server 使用的附加說明

5.1 部署 Webpacker

Webpacker 將 webpacker:compile 任務新增到 assets:precompile rake 任務,因此任何使用 assets:precompile 的現有部署管道都應該可以工作。編譯任務將編譯包並將它們放置在 public/packs 中。

6 附加檔案

有關高階主題的更多資訊,例如將 Webpacker 與流行框架一起使用,請參閱 Webpacker 文件

回饋

我們鼓勵您幫助提高本指南的品質。

如果您發現任何拼寫錯誤或資訊錯誤,請提供回饋。 要開始回饋,您可以閱讀我們的 回饋 部分。

您還可能會發現不完整的內容或不是最新的內容。 請務必為 main 新增任何遺漏的文件。假設是 非穩定版指南(edge guides) 請先驗證問題是否已經在主分支上解決。 請前往 Ruby on Rails 指南寫作準則 查看寫作風格和慣例。

如果由於某種原因您發現要修復的內容但無法自行修補,請您 提出 issue

關於 Ruby on Rails 的任何類型的討論歡迎提供任何文件至 rubyonrails-docs 討論區