Rails使用 Webpacker 管理靜態檔案

簡介

Rails專案中可能會有許多靜態的檔案,例如:JavaScript、Stylesheets 和圖檔,把所有的靜態檔案都放在public目錄或許是個選擇,但是檔案一多的時候,就不好管理了。

因此為了便於管理這些檔案,Rails 提供以下兩種方式:

  1. Webpacker
  2. Assets Pipeline

雖然從Rails 6後預設使用 Webpacker 來管理 Javascript 並使用 Asset Pipeline 管理 CSS,但是要使用其中一邊管理全部的靜態資源也是可以的,因為上篇已經寫過使用 Assets Pipeline 的方式管理靜態資料,因此本篇介紹使用 Webpacker 的方式來實作。

操作步驟

以下示範使用 Webpacker 搭配已經寫好的模板:

  1. 下載模板
  2. 複製模板必要內容至專案
  3. 安裝 bootstrap
  4. 更改靜態資源的取得路徑
  5. 其他問題

下載模板

本篇文章使用Start Bootstrap-Landing Page作為模板範例,首先請先下載該專案或使用git進行下載
git clone https://github.com/StartBootstrap/startbootstrap-landing-page.git·

下載完成後可以進入該資料夾執行npm start,即可瀏覽網頁,如果沒裝npm也沒關係,直接點擊dist/index.html就好

複製模板必要內容至專案

必要內容包含 scssimagedist/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.htmlbody 區塊到 index.html.erb

  • app/views/layouts 中新增 landing.html.erb,複製 app/views/layouts/application.html.erb 的內容到裡面

  • 把模板dist/index.html中的以下內容全部貼到app/views/layouts/landing.html.erbhead區塊

    <!-- 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 更加了解。

參考連結