jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

Vite · Part 7 — Static Assets & Glob Imports

Import assets like code: the default URL form, the ?url / ?raw / ?worker queries, inlining small assets, public/ vs imported assets, and import.meta.glob for bulk imports. With an asset import explorer.

3 MIN READ

Trong Vite, asset là một phần đồ thị module — bạn import ảnh giống import code. Điều đó cho bạn hash, cache-busting, và loại asset chết miễn phí. Mẹo là biết mỗi dạng import trả về gì.

Mở rộng mỗi dạng import để xem bạn nhận gì và khi nào dùng:


1. Mặc định: import trả về URL

import imgUrl from "./logo.png";
// imgUrl === "/assets/logo-a1b2c3.png"  (hashed)

document.querySelector("img").src = imgUrl;

Import một asset cho bạn một URL đã phân giải, gắn vân tay. Khi build nó được copy vào dist/assets/ với hash nội dung, nên cache an toàn và cập nhật tự bust cache. Asset không module nào import sẽ không vào dist.


2. Asset nhỏ được inline

Dưới ngưỡng kích thước (mặc định 4 KB), Vite inline asset thành data URI base64 để tiết kiệm request:

export default defineConfig({
  build: { assetsInlineLimit: 4096 }, // bytes; set 0 to disable inlining
});

Nên icon nhỏ có thể thành data URI (không request thêm), còn ảnh lớn vẫn là file hash riêng.


3. Hậu tố query đổi cái bạn nhận

Cùng một file import khác nhau tùy query:

ImportTrả vềDùng cho
"./a.png"chuỗi URL<img src> etc.
"./a.svg?url"URL (ép)khi plugin sẽ biến đổi nó
"./a.glsl?raw"file dạng chuỗishader, SQL, template
"./w.js?worker"constructor Workernew MyWorker()
import shaderSrc from "./fragment.glsl?raw"; // the text
import Worker from "./heavy.js?worker"; // const w = new Worker()

?worker đặc biệt hay: nó bundle worker đúng cách nên bạn bỏ được nghi thức new Worker(new URL(...)) thường lệ.


4. public/ vs asset import

Hai cơ chế, chọn có chủ đích:

  • xử lý, hash, thuộc đồ thị. Dùng cho asset code tham chiếu.
  • copy nguyên văn ra gốc output, tham chiếu bằng đường dẫn tuyệt đối.
<!-- file: public/favicon.svg → served at /favicon.svg -->
<link rel="icon" href="/favicon.svg" />

Dùng public/ cho file phải giữ tên chính xác, hoặc được tham chiếu bởi code bạn không kiểm soát. Đừng để vào đó chỉ để né import — bạn mất hash và loại asset chết.


5. import.meta.glob — import hàng loạt

Khi cần import nhiều file khớp pattern — routing theo file, plugin tự đăng ký, thư mục nội dung — dùng import.meta.glob:

// lazy by default: an object of dynamic-import functions
const pages = import.meta.glob("./pages/*.tsx");
// { "./pages/Home.tsx": () => import("./pages/Home.tsx"), ... }

for (const path in pages) {
  pages[path]().then((mod) => registerRoute(path, mod.default));
}

Truyền { eager: true } để import tất cả ngay thay vì lazy:

const modules = import.meta.glob("./icons/*.svg", { eager: true, query: "?raw" });

Đây là tính năng lúc biên dịch — Vite mở rộng glob tĩnh, nên pattern phải là chuỗi literal. Đây là cách đa số router theo file và thiết lập “tự import mọi thứ trong thư mục này” hoạt động.


6. Bài tập

1. Bạn import ./hero.png và dùng kết quả làm <img src>. Vì sao URL được hash, lợi ích gì?

Lời giải

Vite gắn vân tay asset bằng hash nội dung để cache dài hạn an toàn — khi file đổi, URL đổi, tự bust cache.

2. Bạn cần nội dung file .sql dạng chuỗi trong JS, không phải URL. Dùng import nào?

Lời giải

import sql from "./query.sql?raw" — hậu tố ?raw trả file dạng chuỗi.

3. Bạn muốn router theo file tự đăng ký mọi component trong src/pages/, tải lazy. API nào?

Lời giải

trả map đường dẫn → hàm dynamic-import (lazy). Thêm { eager: true } chỉ khi muốn tải hết ngay.

Nâng cao:trong explorer, so ?url, ?raw, và ?worker cho cùng file và để ý giá trị trả đổi từ chuỗi URL sang văn bản file sang constructor.


Điểm chính

  • Import asset trả về URL đã hash mặc định.
  • Asset nhỏ (< 4 KB) được inline thành data URI.
  • Hậu tố query: ?url, ?raw (chuỗi), ?worker (constructor).
  • public/ là nguyên văn, đường dẫn tuyệt đối, không hash — cho file tên chính xác.
  • import.meta.glob import hàng loạt theo pattern (lazy, hoặc eager).

Tiếp theo

Phần 8 — Biến môi trường & mode: import.meta.env, file .env, tiền tố VITE_ và vì sao quan trọng cho bảo mật, define, và mode tùy chỉnh.