@@ -3,6 +3,7 @@ import fs from "node:fs";
33import path from "node:path" ;
44
55import type { AstroIntegration } from "astro" ;
6+ import symlinkDir from "symlink-dir" ;
67
78import { ASSET_DIR , CACHE_DIR_ASSETS } from "../constants" ;
89
@@ -12,42 +13,20 @@ export default (): AstroIntegration => ({
1213 "astro:config:setup" : async ( { command } ) => {
1314 fs . mkdirSync ( CACHE_DIR_ASSETS , { recursive : true } ) ;
1415
15- // In dev mode, create symlink to public directory
16+ // In dev mode, create symlink to public directory for serving assets
1617 if ( command === "dev" ) {
17- const publicAssetDir = path . join ( "public" , ASSET_DIR ) ;
18-
19- // Remove existing symlink or directory
20- try {
21- const stats = fs . lstatSync ( publicAssetDir ) ;
22- // If it's a symlink, use unlinkSync; otherwise use rmSync
23- if ( stats . isSymbolicLink ( ) ) {
24- fs . unlinkSync ( publicAssetDir ) ;
25- console . log ( `astrotion: removed existing symlink ${ publicAssetDir } ` ) ;
26- } else {
27- fs . rmSync ( publicAssetDir , { recursive : true , force : true } ) ;
28- console . log ( `astrotion: removed existing directory ${ publicAssetDir } ` ) ;
29- }
30- } catch ( error : any ) {
31- // ENOENT means the file doesn't exist, which is fine
32- if ( error . code !== "ENOENT" ) {
33- console . error ( `astrotion: error checking ${ publicAssetDir } :` , error ) ;
34- }
35- }
36-
37- // Create symlink
38- const relativeTarget = path . relative (
39- path . dirname ( publicAssetDir ) ,
40- CACHE_DIR_ASSETS
41- ) ;
42- fs . symlinkSync ( relativeTarget , publicAssetDir , "dir" ) ;
43- console . log ( `astrotion: created symlink ${ publicAssetDir } -> ${ CACHE_DIR_ASSETS } ` ) ;
18+ await createPublicSymlink ( ) ;
4419 }
4520 } ,
4621 "astro:build:start" : async ( ) => {
22+ // Runs before build starts
23+ // Create cache directory and symlink so Vite can find assets during build
4724 fs . mkdirSync ( CACHE_DIR_ASSETS , { recursive : true } ) ;
25+ await createPublicSymlink ( ) ;
4826 } ,
4927 "astro:build:done" : async ( { dir } ) => {
50- // only triggerd in build mode
28+ // Runs after build completes
29+ // Copy assets from cache to final dist directory
5130 const outDir = new URL ( ASSET_DIR , dir . href ) . pathname ;
5231 fs . mkdirSync ( outDir , { recursive : true } ) ;
5332
@@ -57,3 +36,39 @@ export default (): AstroIntegration => ({
5736 } ,
5837 } ,
5938} ) ;
39+
40+ /**
41+ * Creates a symlink from public/static to the cache directory.
42+ * Uses symlink-dir for cross-platform compatibility (Windows support).
43+ * This allows Astro to serve cached assets during dev and build.
44+ */
45+ async function createPublicSymlink ( ) {
46+ const publicAssetDir = path . join ( "public" , ASSET_DIR ) ;
47+
48+ // Remove existing symlink or directory
49+ try {
50+ const stats = fs . lstatSync ( publicAssetDir ) ;
51+ // If it's a symlink, use unlinkSync; otherwise use rmSync
52+ if ( stats . isSymbolicLink ( ) ) {
53+ fs . unlinkSync ( publicAssetDir ) ;
54+ console . log ( `astrotion: removed existing symlink ${ publicAssetDir } ` ) ;
55+ } else {
56+ fs . rmSync ( publicAssetDir , { recursive : true , force : true } ) ;
57+ console . log ( `astrotion: removed existing directory ${ publicAssetDir } ` ) ;
58+ }
59+ } catch ( error : any ) {
60+ // ENOENT means the file doesn't exist, which is fine
61+ if ( error . code !== "ENOENT" ) {
62+ console . error ( `astrotion: error checking ${ publicAssetDir } :` , error ) ;
63+ }
64+ }
65+
66+ // Create symlink using symlink-dir for cross-platform support
67+ try {
68+ await symlinkDir ( CACHE_DIR_ASSETS , publicAssetDir ) ;
69+ console . log ( `astrotion: created symlink ${ publicAssetDir } -> ${ CACHE_DIR_ASSETS } ` ) ;
70+ } catch ( error ) {
71+ console . error ( `astrotion: failed to create symlink:` , error ) ;
72+ throw error ;
73+ }
74+ }
0 commit comments