iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
Vue.js

Nuxt.js 3.x 筆記-打造 SSR 專案系列 第 12

D12:Nuxt 3.x Assets vs Public 目錄-靜態資源管理

  • 分享至 

  • xImage
  •  

本篇文章同步更新於個人部落格,歡迎交流指教~謝謝您的閱讀

Nuxt3 提供兩個資料夾 assets/ 以及 public/,用來管理靜態資源,像是圖片、CSS 樣式、字體、icon 等,接下來說明兩個目錄適合存放的檔案類型與使用方式


Public

靜態資源資料夾(同 Nuxt2 的 static/),用來存放不需被編譯的靜態檔,可以透過根目錄 / 直接使用檔案

適合檔案性質

  • 不需經由 Vite / Webpack 等打包工具編譯: 像是 sitemap.xml 通常不需另外壓縮處理
  • 檔案固定性高 / 檔名不能被更改: 經過編譯後的檔案,檔名後會加上一組 hash,像是 robots.txt 必須固定檔名,搜尋引擎爬蟲才能正確解析,適合放在 public/

常見檔案類型

  • favicon.ico
  • robots.txt
  • sitemap.xml
  • CNAME(DNS 紀錄)

使用方式

透過根目錄 / 直接使用 public/ 檔案

範例:

public/
|—— favicon.ico
|—— image/
  |—— picture.jpg

使用 favicon.ico

// nuxt.config.js
export default defineNuxtConfig({
  app: {
    head: {
      link: [
        { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
      ]
    }
  }
});

使用 image/picture.jpg

// pages/index.vue
<template>
  <div>
    <img src="/image/picture.jpg">
  </div>
</template>

透過開發者工具檢視

圖片來源:https://unsplash.com/

Assets

用來存放像是 CSS、Sass、圖片等需要被 webpack 或是 Vite 編譯的靜態資源。一般來說,assets/ 的使用頻率較 public/

適合檔案性質

  • 需要透過 Vite / Webpack 打包工具編譯(壓縮、最佳化): 像是 JS 或是 CSS、圖片等,希望在專案發佈前,預先對檔案進行壓縮和最佳化處理,提升網站載入速度與效能
  • 檔案較常更新,避免被快取影響: 經過編譯後的檔案,檔名會加上依據文件內容產生的 hash,每次更新編譯後 hash 會變更,能避免受瀏覽器快取影響,強制瀏覽器讀取更新後的檔案。例如:img.png 編譯後變成 img.2d8efhg.png

常見檔案類型

  • CSS、Sass
  • Javascript
  • 圖片
  • 字體

使用方式

透過 ~/assets/ 路徑使用檔案

範例:

assets/
|—— scss/
|———— style.scss
|—— image/
  |—— picture.jpg

全域使用 scss/style.scss

// nuxt.config.js
export default defineNuxtConfig({
  css: [
    '~/assets/scss/app.scss'
  ]
});

使用 image/picture.jpg

// pages/index.vue
<template>
  <div>
    <img src="~/assets/image/picture.jpg">
  </div>
</template>

執行生產環境編譯 nuxt build (npm run build) 後,可以看到檔名加上了 hash

圖片來源:https://unsplash.com/

路徑別名

Nuxt3 預設路徑別名如下:

{
  "~": "/<rootDir>",
  "@": "/<rootDir>",
  "~~": "/<rootDir>",
  "@@": "/<rootDir>",
  "assets": "/<rootDir>/assets",
  "public": "/<rootDir>/public"
}

因此也可以透過 @/assets/image/picture.jpg 取得圖片,或是自訂別名來簡化路徑

動態圖片

在 Nuxt2 搭配 Webpack 打包工具,透過 require 即可動態載入圖片

// Nuxt2 + Webpack
<img :src="require(`~/assets/image/${imageName}`)" />

Nuxt3 搭配 Vite 解決方法如下(討論串),透過 import.meta.glob 方法一次引入多張圖片

// Nuxt3 + Vite
<template>
  <div>
    <img :src="getImageUrl(imageName)" />
  </div>
</template>

<script setup>
const getImageUrl = name => {
  const assets = import.meta.glob('~/assets/image/*', { eager: true, import: 'default' });
  return assets[`/assets/image/${name}`];
};

const imageName = 'picture.jpg';
</script>

.output 資料夾

執行生產環境編譯 nuxt buildnpm run build)時自動生成的資料夾,assets/public/ 打包後會放在 .output/public/

原始檔案:

public/
|—— public-pic.jpg
assets/
|—— assets-pic.jpg

打包後:

  • public/ 內的檔案不經處理直接放到 .output/public/
  • assets/ 內的檔案編譯後加上 hash 放到 .output/public/_nuxt/
.output/
|—— public/
  |—— _nuxt/
    |—— assets-pic.ef9916a0.jpg
  |—— public-pic.jpg

參考資源:
https://nuxt.com/docs/getting-started/assets
https://masteringnuxt.com/blog/handling-assets-in-nuxt-3
https://vitejs.dev/guide/assets.html


上一篇
D11:Nuxt 3.x Middleware 目錄-監聽路由變化
下一篇
D13:Nuxt 3.x API 請求方法-$fetch、useAsyncData、useFetch
系列文
Nuxt.js 3.x 筆記-打造 SSR 專案30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言