🦊zeckli筆記

在 Remix Loader 讀取 Public 資料夾檔案

2024 年 11 月 30 日

Remix 因為設計關係,雖然在頁面或組件中無法直接 import 載入 Public 資料夾中的檔案,但是我們仍可在 loader 中實現,所以接下來將介紹兩種讀取方式。首先假設我們的應用結構如下:


  .
  ├── app
  │   ├── main.css
  │   ├── root.tsx
  │   └── routes
  │       └── _index
  │           └── index.tsx
  ├── public
  │   └── data
  │       └── your.json
        

使用 import.meta

通常在 Node.js 執行環境中常用 __dirname 來組合靜態資源的路徑。但是 Remix 基於 ES module 因此 __dirname 不是全局可用變數,所以我們得利用 import.meta.dirname 來取得當前路徑。假設在 _index/index.tsx 要讀取 Public 底下的 JSON 檔案,可以這樣使用:


import type { LoaderFunctionArgs } from '@remix-run/node'
import { json } from '@remix-run/node'
import fs from 'fs-extra'
import path from 'path'

export const loader = async ({ request }: LoaderFunctionArgs) => {
  const __dirname = import.meta.dirname
  const dataPath = path.join(__dirname, '..', '..', '..', 'public', 'data', 'your.json')
  const data = JSON.parse(await fs.readFile(dataPath, 'utf8'))
  return json({ anything: '' })
}
          

利用 path.resovle

除了 import.meta 之外,我們還能用更直接的 path.resolve 來取得指定路徑。假設同樣以 _index/index.tsx 為範例讀取 JSON 檔案:


export const loader = async ({ request }: LoaderFunctionArgs) => {
  const dataPath = path.resolve('./public/data/your.json')
  const data2 = JSON.parse(await fs.readFile(dataPath, 'utf8'))
  return json({ anything: '' })
}
        

以上就是兩種讀取 Public 資料夾內的資源方式,感謝閱讀!