Rails使用 Webpacker 管理靜態檔案
簡介
Rails專案中可能會有許多靜態的檔案,例如:JavaScript、Stylesheets 和圖檔,把所有的靜態檔案都放在public
目錄或許是個選擇,但是檔案一多的時候,就不好管理了。
因此為了便於管理這些檔案,Rails 提供以下兩種方式:
- Webpacker
- Assets Pipeline
雖然從Rails 6後預設使用 Webpacker 來管理 Javascript 並使用 Asset Pipeline 管理 CSS,但是要使用其中一邊管理全部的靜態資源也是可以的,因為上篇已經寫過使用 Assets Pipeline 的方式管理靜態資料,因此本篇介紹使用 Webpacker 的方式來實作。
操作步驟
以下示範使用 Webpacker 搭配已經寫好的模板:
- 下載模板
- 複製模板必要內容至專案
- 安裝 bootstrap
- 更改靜態資源的取得路徑
- 其他問題
下載模板
本篇文章使用Start Bootstrap-Landing Page
作為模板範例,首先請先下載該專案或使用git進行下載
git clone https://github.com/StartBootstrap/startbootstrap-landing-page.git
·
下載完成後可以進入該資料夾執行
npm start
,即可瀏覽網頁,如果沒裝npm也沒關係,直接點擊dist/index.html
就好
複製模板必要內容至專案
必要內容包含 scss
、image
和 dist/index.html
中的程式碼
- 複製模板
src/scss
之下所有內容到專案app/javascript/stylesheets
資料夾(沒有就新增) - 複製模板
src/assets/img
之下所有圖片到專案app/javascript/images
資料夾(沒有就新增)
新增 Controller
由於我們下載的是一個首頁的模板,為了不打亂原本的專案,因此我們另外創建一個 Controller
- 執行
rails g controller landing
新增 Controller - 修改
landing_controller
中的內容
把此段程式碼刪除
class LandingController < ApplicationController end
替換成以下
class LandingController < ActionController::Base def index end end
-
在
config/routes
中設定根路徑root to: "landing#index"
-
在
app/views/landing
中新增index.html.erb
,並且複製模板dist/index.html
的body
區塊到index.html.erb
-
在
app/views/layouts
中新增landing.html.erb
,複製app/views/layouts/application.html.erb
的內容到裡面 -
把模板
dist/index.html
中的以下內容全部貼到app/views/layouts/landing.html.erb
的head
區塊<!-- Font Awesome icons (free version)--> <script src="https://use.fontawesome.com/releases/v5.15.3/js/all.js" crossorigin="anonymous"><script> <!-- Simple line icons--> <link href="https://cdnjs.cloudflare.com/ajax/libs/simple-line-icons/2.5.5/csssimple-line-icons.min.css" rel="stylesheet" type="text/css" /> <!-- Google fonts--> <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic700italic" rel="stylesheet" type="text/css" />
-
在
app/javascript/packs/application.js
之中加入此段,引入模板 scss
import 'stylesheets/styles.scss'
安裝 bootstrap
由於此模板需要 bootstrap,因此必須安裝,安裝步驟參考Rails 6 使用 Bootstrap,但有少許修改,依下方為主
- 執行
yarn add bootstrap@4 jquery popper.js
安裝 bootstrap 相關套件 - 在
app/javascript/packs/application.js
之中加入 bootstrap 相關套件
import 'jquery' import 'popper.js' import 'bootstrap' window.jQuery = $ #jquery使用,此範例不加此行也可以正常執行 window.$ = $ #jquery使用,此範例不加此行也可以正常執行
- 新增
app/javascript/stylesheets/site.scss
檔案,在其中加入以下內容
@import "~bootstrap/scss/bootstrap.scss";
- 在
app/javascript/packs/application.js
之中加入此段,引入 bootstrap
import 'stylesheets/site.scss'
- 設定 Webpacker,在
config/webpack/environment.js
加入以下內容
const { environment } = require('@rails/webpacker') const webpack = require('webpack'); environment.plugins.append( 'Provide', new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', Popper: ['popper.js', 'default'], }) ); module.exports = environment
更改靜態資源的取得路徑
- 在
app/javascript/packs/application.js
加入此段
require.context("../images", true)
- 更改
app/views/layouts/landing.html.erb
的圖片 url
將有使用到圖片 url,替換成以下 helper 寫法
asset_pack_path 'media/images/檔名.jpg'
- 將
app/javascript/stylesheets
資料下的圖檔 url 更改為相對路徑
到了這一步,執行 rails s
就應該可以看到正常的畫面了。
其他設定
如果想要指定在 production 環境運行的話,需要進行以下動作:
RAILS_ENV=production webpacker:compile
Webpacker重新編譯RAILS_SERVE_STATIC_FILES=true rails server -e production
config.serve_static_files在預設時是true
,但在 production 環境下會是false
,這是因為提供靜態資源應為伺服器軟體負責的,如 Apache、Nginx 等。相關連結、Rails指南
結語
本篇文章主要是拿來紀錄使用 Webpacker 的過程,寫這篇文得時候我感覺是在做一件挖坑給自己跳的事情,雖然之前有做過,但當時為了趕工,留下了許多技術負債,也因為要寫這篇文,我不得不把每一個坑都跳過一遍,但藉著這個機會也讓我對於 Webpacker 更加了解。