From 1d4513dbcff624978ee0bf3758a74b0bdf58ad15 Mon Sep 17 00:00:00 2001 From: Thomas Boutell Date: Fri, 25 Sep 2026 12:50:27 -0400 Subject: [PATCH] solve PRO-9899 by not using hash URLs in the first place, we already have release IDs in the URLs --- .changeset/vite-unhashed-public-assets.md | 5 ++++ packages/vite/lib/vite-base-config.js | 20 +++++++++++++-- .../article-page/public/fonts/sans.woff2 | Bin 0 -> 8192 bytes .../modules/article-page/ui/src/index.scss | 9 +++++++ .../article-widget/public/fonts/sans.woff2 | Bin 0 -> 8192 bytes packages/vite/test/vite.test.js | 24 ++++++++++++++++++ 6 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 .changeset/vite-unhashed-public-assets.md create mode 100644 packages/vite/test/modules/article-page/public/fonts/sans.woff2 create mode 100644 packages/vite/test/modules/article-page/ui/src/index.scss create mode 100644 packages/vite/test/modules/article-widget/public/fonts/sans.woff2 diff --git a/.changeset/vite-unhashed-public-assets.md b/.changeset/vite-unhashed-public-assets.md new file mode 100644 index 0000000000..a6876ecda4 --- /dev/null +++ b/.changeset/vite-unhashed-public-assets.md @@ -0,0 +1,5 @@ +--- +"@apostrophecms/vite": minor +--- + +Assets from a module's `public/` folder that are referenced from CSS, such as web fonts loaded with `url('/modules/...')`, are now emitted at their original path instead of a content-hashed copy under `assets/`. As a result, `apos.asset.url('/modules/...')` in a template now matches the URL requested by the built CSS, so `` tags for web fonts work as intended rather than downloading each font twice. Cache busting is still provided by the release directory. Note that Vite still inlines assets smaller than 4 KB into the CSS, so such small fonts should not be preloaded. Also fixes the `assetsDir` build option, which was misspelled and silently ignored. diff --git a/packages/vite/lib/vite-base-config.js b/packages/vite/lib/vite-base-config.js index 2f668cff5d..1633f47038 100644 --- a/packages/vite/lib/vite-base-config.js +++ b/packages/vite/lib/vite-base-config.js @@ -35,10 +35,11 @@ module.exports = ({ manifest: manifestRelPath, sourcemap: sourceMaps, emptyOutDir: false, - assetDir: 'assets', + assetsDir: 'assets', rollupOptions: { output: { - entryFileNames: '[name]-build.js' + entryFileNames: '[name]-build.js', + assetFileNames } } } @@ -46,3 +47,18 @@ module.exports = ({ return config; }; + +// Assets that come from a module's `public/` folder (e.g. fonts referenced +// from CSS via `url('/modules/...')`) are emitted at their original path, +// without a content hash. This way `apos.asset.url('/modules/...')` in a +// template matches the URL the built CSS requests, e.g. for preloading. +// Cache busting is already provided by the release directory, just like +// for the unhashed `[name]-build.js` entry files. +function assetFileNames({ names = [], originalFileNames = [] }) { + const original = originalFileNames[0]?.replaceAll('\\', '/'); + const isCss = names.some((name) => name.endsWith('.css')); + if (!isCss && original?.startsWith('modules/')) { + return original; + } + return 'assets/[name]-[hash][extname]'; +} diff --git a/packages/vite/test/modules/article-page/public/fonts/sans.woff2 b/packages/vite/test/modules/article-page/public/fonts/sans.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..3af129a6fb021bcba4df24d2cc805f706fd4b8c5 GIT binary patch literal 8192 zcmV+bAphUILdwgYcE$@IRv6S!rJju%G|1TNwB}_)b!}Tx-Y`Cr0=Cz^^HsMNc`lbo z;SGSK-G7u#-48lKheb;mbMgnIvZN+j+rED&ql3y|B@Ct~e;P4r5`c5j+uQli zT@Tk=m=Sm6W9w&qKWg9uVHKwFlNVJGG*4T`O1)7JE2RewEazA+D`GTv23HA5iloa4 zXnHp{U31|56fp@P{?{^zkCG7%_~wrhA@@UAgX(j;zv_PmXJ#Dpv_}pM>{gM zh$zZ$ALo9fe(}Pn8{M@TbBrm}of}i32?B6Nu&PXLJfTLj#O;Kp(H^f=g-pwc-JROu zit%3$irxRY?M!-R;(3v9onQi4c|J-P()F%c9Cg}EiqmvaSPm|ls|5o9u2M>R=-%Z+ z*%v-<_7d=SW{@`zoH~AneOKNXSp`KY-8>pQOCr8lM*LG5fPhwb#d3}t5G={IWDw+u z=tE|rTeY~oYFs%w)dY*F=U*uC38<%Amf2 zyxx$J;rjYJ_lMIuSJX?IP;R_sKe}CyX<~st1tsEj1ZcYA?@u zVR`Q&Y67Nn{mvm)GY@S;p<3cKhNen=&%L&f;9UO}z_;Kuci?o?iv%K~A-_-0#<0nl zD*!y$ioP;NR%vcVn9Ux@rj|4;lL=IZt7}`mk`e12H2Tn?do{8ZjLNvwGM4V_hQ}8w zayJ%7CsT8@i_Ss5PuO1|)cAz}3EgTd4eS=;ux`Lp`Ti|A_AC;bF}y27^E`kX15te1 zDT8>lFoHLW0r0Ywp2(CTT}mmc>_agHClVcGM?yCL>&b3BX zem8kcz#g^zukdi%Wp6IqpM{j@)QNWqPo|h zQyDlWZcXw$0>ZiW{uKi(h@VKwHLu{C2yxIbHW;Wc#mq~X^vYucfTsNcs11;6(-VrM zd36%lD~KM@HK$(@2Nq|DZI}~;({pVUusE7MuJ3I=@xrbK(8kKgQKO(t7oYy|twD7M zJyuQ%;8lAno_jSWy0xx*8M`JiwQ@m9&5WZhs5|#<1Liix*b0F!ec6BC?J6+EsIb-z zS4NL~itXOPREIl5V4Ntmf1Dt4WkwgYAtH;5_TwCjb1gZ#j5fskgUAZG~!D1rqhD!~&A}m68gw zGpKaAo(PkFfS(T4K~bdRWKPWVq@+Sq7Sm94a=MP2mtJ$Y;qwnz#SkI^N;PD*qE8>z zDE|teQ?UIZHTsa=^zW_Ac8S-PXfE25W6*fAAT}NWe-~9>1gd&ady3*W zbsAdn83Z50=B1}oTBbEh8ZSk~wtqTrMNJG((67{aeP`quPW71@L`1HF0$;;1OA25L zfmT=9<85pEqPi7Qy||S8inKaDvB^XrF@An@?uCL>-XV4j@p`Gp7SKz7zUnE`mWht0D65r=>^a5PeCA`yS>Pv;Oon!>}0O2p!QvmfnU7SEiRc z)+Hag1n6Rxb{m;Gk~h}``S<+alZOROb%nm%NBl4wZ`5vrI{jrb(i6H^8*78|SY z&1&lr7O|Cnxbhtfto1%Cb^=vk1ERUkl$X{3-(pd2kCY<5F+KgwDkwn2%Kn%2fsa5R zJPwlz3&06!_KfWw#FXjNC~U=B?FsaZ>jjm;$&3>h%s!GD9(YaK1`aDn#t1OEBpHcq zkU_?%3iL;GbtVM8tuVgv{uv78V!EK(qQ|&igf;8Yz4QHg^rg}q4Ne(%HRT&Da?j8k!cwmRr}g zT|A&$J6x3N{ttC8Nrmx^@nW0tfWk?yL{yXPgi@oLpOx%eFdi6)1yI^9P3UcgrAxLusa z;~40>)JDU>9yqN+yw3glL(1k1hk9tf^_yc*CrT%DT%o6{k~_}ffZJ}S{Asnr?;VRS;nr^SbP6LZDOmm%3S)M zHDMd)v!%~qw{O7CU+iG%j(n)%U^TI}I8p>H7)hR%oQ4nP_b9xO6U<`AoFhrFkZjUn zI>1x?8J)-e>Qi$ZdMAGERrDBf+16D(fX?!6G(sXmd9Q+Z^o?ux=D5K(k`?6Q=PeTZ zE)ia0{Xt+%q7rtwc1&Ab~}$AwCMF=XE!*d=`>w1AT}a zH`J$wbf&T^%(JvWC1^6|S7%_6LoharfO3l2n5S^bMIi8yCcDztKht#QAG!rWQeehO zCIE0_{0@EP4xF$O!ojwP)RqZP{esXX1_~keQG(Vs(ld|OYsndw@w&LEv}EbFJKrzb zemMRzH|X1UPJX5pUAVr3#Ph3VmsB5$M3bepzogJ-4Hf0DBw!37W*>nR@RQuty?_lVNdzd0eY%7hm4uOamRFwVyCIdl^SfE9^7gn82bejU zq-U-rGmyMiMass?`vp@(@rm+g*Q7~HF|8+eDbmy{&WZMA%7%68$&lcQQ(2mTks&xI zQ>=;41;}!-mHtT4pe&!6bo13kfg4I+>in9V3r0Wh{9C7R*gSB2$Lk0L8CVVcIK^Fd&M3_ysl{fYfgDP7 zSLCs}FUIweq*>w`%6reP8`k7e| zBrg;7yN2?J!gGMAUzn*inkKZtC)2@88B1bayvmS#{mklI|EEm-knL$=w8OzXfr1Rf z70v?E;O(JX&dF&R9~Te1RLknCy_q`o8}Mv!St*jdMYK})Q3-oXpwUWaQCTX9S>&sC*n2b}(YI;5A6#>nwIpVOf%A9X?)&^{N3;KrmwHm$Y8?`86aau zy&_vxhw_H)WfAQ`!O6*wm~~mRrwuj&>YU)7-$B)+Kh@mG4nm~ndW#L5P_;ENdUQ1= zTHR5&!h0RkkS@zo&?WY=tu{yoyS@^cabt`Bc)&8sakV6Jn>bFt>3C!kkdrHlX3aN4 zB|3XU^};y{`Zoe>6>V^oyWsEvfd5s+Nc(KcbH>`>!MTZKj2({&E1WKHNNo+>Z2hD1vYX+0%U@Nv)k#tx&lC@l{w9slAN z%!hpp+RDJmD+_CMg}eVj=b2yysFpbsAI!XlBi)XiR!MR09-nKE?L>1M)3TS@4&+x% z$^wLt@rHm&@O@#)CzHV*qD9z#Kh?HVAZt@xK7(+%SU-OVm^!l-6{&Z}G8V4Qq zPoKL2(MDM0%gQB|d|S5_%WhODx%fDW;~-Hzk@(eEO`CKwTG+}WBO~%W>*uR*fI^5c zrEbrz!l8&J zBPs|rfOk9IKc-(-R`FxA+tgt+UaTUp2 zRBS9vPE*#l+et=E%(l!(U;dbNCC;KPDk|ftO~l7sb9QhTRdLqw2N=zi=Txj7er`2@ zEk?X}kld7Ag+*}Rm2Vu%#tZByvO$2Rjw1tk9^IV_F%2D)#_>ILBf_%y%Rm5VYSj#@ zxuM8UMFY;VARp%8#Zg7szph#N+Sh~jJf6}?q3dJFZ9S%gwD#w`%8;gXt@z7^=Uw9x zs2;5_vGvco2ityC4$XuKqdbwNs-1VNI^8I#WDhs=+#m7+SVx;m{pus*W@x4|*MR%j zg7UCmd$Uf_j^Kdr!=iyW)i1KjR!iu>qckcsd+0P7RKsL(Y4X$><{BfszYB~T4}-yo z&`Ihe?)5b5pOGG2I!rb=qG}@nCQ6YW$#f*0pw!)>7v7A_xAp}6Ow4N!gtHuB_hoDO z1PBUQ1P{a|Rp;rFv#=C!Funa}InfZ0-dGK8<}b6dN`Vs==z@_$66My_(K)N`8<$ur zjI<3W4Abxp(=OY%0g@t05Tr?fRoVM9raAYEFX)2y(Hj(`JY;%Aikc{Xl=$IvrG_)f zAp|>JHo>`rI28|1e8@E|2{XNN1?ZCQuADg+5J5r#Pybq zCcn|c-~S|mJUe1lMdL=}rbv_pS4JJwHeMR4-0~Uux0~t`tgsSQKkjy(EH7)S^lHF_&By;v{L?X%YOpK+UonhtX3tOeQqQ$Z zh1#iCMTeX&_a7axBP$=mizAy6rp+|s+3aQ6CxQ=&H|g2fiISFXf;%s?hWry-SthAV zEg3|rH=E8juMbh$BqR_y&=^vOnRApmTA&V0lJ?D1t4#m^I%-n|qN6B(#wMINZ@xCA! zd6Z>QAlL|_dJNi;?XtN0Vm970r+f}P`6WMig%uW{f_mltdcRl--lRB`zA1zZJ@4MH zcA-92SN!%1j^#fQIylAFjtWLuJLMJqu{2V6gPkB6L>W9Jt2a^>0-|c;1k6`bC}em$ zBqCm12b-B%;g4$|^HSneXt3Z=jb~a!(?Ym|Yy|2<3ka4nXLa?Yw&W>-!z+ZQj6!P;(TS*8y9wDPO zC?4j@+{2PdsjLSm>n0EwSgFFQ;YI1CNH9j>tvt?W*; z96UE;D$Ku_S+E8zovdY=iZq3g*GXdBskB)@;l5a=#piBz?yes_tKZ6s?By|8IEhA< zm4$Dw@ZFw?XIj113H_K^C40ng8nkb3!^Zd4E&t48;M1={gW}@LH36A1GdcUZ*zJYU zVW}Vk9DJDFRs~G5Usrvm3|eJ=>q+|$?Lw}9Y@-Q^h8^LMe05=5{_a*=t&OSRcXd12 zFX-`VVkM!7J^G|MkZNtQ8?x9-6f8_O9Ww$h?=9p5Y=)L9#Tg)E z5KTqg@i5+a(8JXrva`41xRM&dtV8RJJo+{)Mg5bE`;{NWE8!aiIIypOt?Ac!#w?%a}?q5wM@hFIAGrZ>&GedQsBKGp}4Xcagh+ zMp+lTrL?4pQ$AE64!Gf%%AkFJCU=%j+{?va8gFnwQrK@L3qG%h>3BR*P(ig7s&I`q z_B8*DW}-h^3Ya8om#q$F9!dY3TQGh(^5n%Y(|#U&LmPCwcq*_5bQj; zG{&u@xTTUtojY)b1906{L!wbw_-&%$)j}aKyJ}%a{ug8Fb^ux|kujkBFPM;+G>q5j zmh|H&s=V;7qBcUJLX@}gb2aNVfTn6OH#bRoYj{(l3`Zy~Br`5|SnC^OoZ9X;a0_al zTX~m^`+5I%B=@W}>4(n{roV7fVB?7xDFsEh4Pl!y!ty?pziWy5t)K2MP)nI|Q+-Rs zynH=uZtVJP;vY$mscP`fp!8N%1&MPs{!ANTq*gL{AdB;a(eTqT1iY9PVYZtdTq?3= zl)|5aKpxt`6W)DDYJo{J8FPIjSI^kzA$fGXcnAWh+qBK(j~wXN$cTD$uPNMOSUu&z zgyD^eGP%GDcsv|58k@cMdDlYi?!n<~W{96sH7|XqVlo!DOh!=LVg(sykN^57Wa@7g z|CHyXFa{F|QULRNJ|LuoLQEg}wVwXNF-SoL08G<(vFCYKCR)#3M$lcS04R*_VBVWl{=+3Ti&6hvKDl_L|Wolen@x(Fncf;+RMSMMEV>G}>3q3}}*B#lOFo zq9{Jujn^)<5~KfP#qilij5_{u8>ZDqA4!$Ftx5{s9;8a>h5r5!;z1;4*BQDlEmvw= zbUAPWtT0=v6&88G*pu%YD`QN1UGe|TM6Y#5(hBcgnir#JZXSV!2zKR!N zALBO`n4VKl1&#;)24537j`UBb#jtz+l{Gp~Pb*s0L`pRM^uj~UdOwJV$o@Ph^h0V7 z$=eXjS6DI$quWv^8P+*4P-?Qn_6{RF7>jPrYx%#yciSYQ)?kmb5(7=cf04_a=m4G% zF3Z=aCxFHKgQpGA;9sEjJeU>gU$G-nglp*X4B0YivNh%AU4Uw@mEuFbJt_x0#**AY z`(}vrl=-rS-Q~!5#dD2Jk9)GaKw`sK0Uxr&#@^U!Hf~ZW!~5x9QqWR)W!Gd^`LG!o z-LCUW0yqF6290xafAJK#LTt$T{IS+badI4nj+#JcaL(B$D!RW5YkUd&O69|mS0CGt z0Wv`UZj7{z!`&2Hfdhx2*BCj{OXxQom1At;cbiN|S;dmefb{ zeS;cIU!)rehP&~5GLzpBzU4erfmYmrC-K|=vbyE2UZWBOyo(QIIfxi)ZkJ0~P;3)< zU9MUR3Mr)rz2t7@!xE-m8;D;)Dgp2NXJKx~?9mM4zQFhgKPRnI@e3LB==FiEUSL9N z0rLLvK|(9lL?O16*xzD$Wo0~aainH;;)Be>GbnO)N2q>?L5>Q3a#190@l*cb|Av#= z}kjCX`EHW>4)u{4$ z!EN~}3#cpKqb;&*_)8ianhH@YnxT{q4N+`+%i*};%zsQe)+c&86tb?X_yKxTKn4v- z#5^C1|=+VZnMssfK5pP1P0>;nZw4zxBhXI6V4$IHE6Od zfxanDNoU^z%4gp3EooGHeN}Lxa-m0RZNI13N_~$;!Fg)`@TvVtfW5=VfQZ#1>Y9Bd zlg7t|$yeoT?Z$Tc%C}kJpc2Gb*CmutY#o-eD;T35fM$#GFEA4C0(>}>ftC$Wg_v{8WVb+*^i!mRJL-Lab6BD0jeor&w#sRPA#KUm z-92u93~yr=0mn%6!P}eA7aB4TLda#w`VpIa+3@dcg+)cZQK{?X8ikl;*h}As+-T9B zbIgGxX|EhPqctDqb?1pT@!1)vAmmg6^l?dH(sIQPVthzF7C8E&rNbtiKe0D;!{t!$gZ#$Llq#76+)E8bXH@KN07s@c_WJuEjqgQl|!3>Q`YpIs;+PwCYt4cysPhCD58Cej~xfteI0 zSA5wn-&-}N4yXQ+dkiTSZWDoJ4im8dPm$)@W2A*1d7#JyimV;7+-I4uK(GyKQ1ibA zmaJa_)_OCGCtlSzNQ_d8EDtq>~ulP^8mpoRe*D zUpE2D{*$9DPwIP(;*eRp(uPeJ=KvIqAd^0r^vm0AT48f!czq5gDV(HO~O2K>CeS`J`iZvj-xK3FutMSQ`vCZE`3UjqP07ccmZx& zK|3P+WYfwn3LxNOGyY2X<#u~i%HwGt=}x}t@7UY{iA^3Mv~{i1&Aa!4v8srpR!6e~RF$epcLkikOOZOcs=K@jO{;Fagl>)o7f1gndRM z27oE14COT+nQe;a5*8=+?n1d|Pax?W@TmGx9qN6JuznF1mN*!^MI00ivkLj)PpBcs zkHAXqK9EV@oO>M?o+8D=bzDlGg^gye4s7<@g-TyjI4BS4vD`VFRG=0s=o?G%;pG|~ mArM_#Vk<5v0E6qr{vs1aDmV6;ILG9z4jY;h1?aoIfS?XQNk zlWA3Ta-ThU@omZ3qT(!4Hq?12BTYuBa(xa%$%FxI=_^*cppp&3XTEmazhMxPm#2aD zXV^Re(_y+){vA@q!{_}}3)UjMr}G4sd`Gcx;sfO+Q+Tw&U+i80coau3#%=lD5`&GG zku;%%*z`{-3~9}UW7G!D4p?MxNz|zx_*E13cZcqb$Mpn>iOj(NIvaoo)=Hz;T(EWt z=LhdX8d-(WUawvs4Nn|ZAQpw-@D%PD$i%jpKsZ$bbrSfq<$p#sU@)AbOsPu;-QV|W z1)UUtQb*b1q6}`m4Y`G~_FA8$@%A61GL>afcIo(zu#8c02Yl}b=?wuIL7y$%=`yfN zA>gHwOlnr~SxCQ6RQMxQZD0L5isQ9q+7UbK4l8^l2y*xkJDN5Qmk}r6@VB1ox+2Q^ z6caWRtA-_1C@F^cN}Unt=mjsF(~dsf(*8`g81-w$iCF{-wG!je$wsTUe5gl|2OygE zLXlR68efzX3apkSu?Di1xh6~4giqXrC|6#Xi%rZLd{!T?juhbHMph2d!#m@Gn+;LE zPlg-OkJrh1wEc|}lG$1WJKWA*T+Gyv_XGq<5p?L(=#EG`lIcYs)lo%*i@M|N>X4ban^-#dEBm2M|*xcyM#M}sv9Ns5p;Z{R^K8|4@`)_nJRYP=krX7W$ zn$H++bN0!dax6~5Q@LolBFWSHwfVtVbapb?AvDY-QGc0MW5q1Go$@fI4kB*i0dASA zA$PPQ|I_gai64!2L_Ivayfi^&SV*I5%uPW5M(gt1k0;J9ztBLJf!|70^M)5w`If0_ zSm{o?eYGD=8NzQ`7?OZnpJeVF>6ml`?j4#Q%R%H0DNJWW8FVS7_7PICFPH^7ucQy* z9;`RGi$s%JAf)^eMfpKWBv;BuPBJF@Y%EL0BMMr6j@oX6dug#PRy0jjAqw>-u(UD9 z{e23U47G;Id%8jfvUaiTu~8Ib!ESYOsAs)6U%o+B-U?B*i~TB=ILJNPJC7Ag`K9kE zV*}G@7JK=GsF15`XHF68sn(3q^>^eLRbGeivm|~g$aDG{=Dps$!=@|P2|xJ3X)U>q z0NQR^*fq=xw)p#&adiP?J^hs0`SoTq4~y_bHAe^VEGunVH8KqL(-lwVG3SthhLj4* zG* z?Su<0HW{EQV3l(6o_Gf-x@>P5yf(&sO~%O|(jl4$L-8BN(T9zXk-H@zu$s1fw*%F) z$G=BWTAMYji{_&ME1J?@96DAw7s*8)s+BBtXSZBDUkf-0i#`I7Cf?7{XOin9dk@Z+ z`ShuGqdLythCTetdQ&Bm?Rcf%5)7KIMF6>xkE_=ZrGG7>2Bx~iSNk2{qkMV@g?r_e zy&Nme=t6#JZF%&7v3aN~z?q_S($$vlo}W2tH3nOT&pCvM%rw=etF-Cq7$&Un+4yae zX{bsA*5J!=1#H%3DOa9=c4bWe@k8qt+o*0{NPif&T3}f!9A&PswE|&Xmp2G>f@=g0 zN%;w?f&YCtW4KYzKLX0@RO**_2;5}E3URX}_g{=7EUnCeX?TsXM+x7pKu$zD>4}of z9@Wr3b|h6TOYF?iDjp=D&sTIlk*&aw4kb+S$>?|*(9Iay`m@jEcd0n zhiuU^8iaH-URNcb`5QE`hxI1mB@j3_F$OR?ZCZ5q4gI;di09;!AT=>diivfcVsBLp zJtj`l0%J|P1lD&H1`3w`JK2?Gg3R>8^cI}a=BX=uvd!kOTRq{2t1I^-K} z_p!199J?}cpt}C$aB~`C?tuqkHsJnu@%$ZlHYR_o91L|C8Df8i@z@7hwnS1Um-p!n z`%O4%Yw>dH=weOhV$m8yzPtq6J(VIb;W+O*Ez(331}bTZDC77;|Wiypw7?a;1Sm z6}=OB_Gkl!7sLvAD^ZhMH)bP8-`b*8;5}Ap$+q#e<=4Uf5%r8G6Uw zSR}=gL3)N`pnk+I!}*20y3&p4mk;DWGz%yb$mW*(-ko;353sg)5jiby|L~({ zgNuV4ZlsPuLHl#FB2P_pBi&HKqL~C^xfBTkS$J)cN2HVYtgF`x8xK9yR9N6<2Vta; z8#N5D`;lQ!us011s>AUJ#qfYAFAfBY@y-aq_{LUc@RFMP5tQjW5FPuMCF1&u%N{9l zyV2V|zK%W&g}Uo=@TRAFGzn%1)|Jewst`UDrVGObM7BZ#pZkyN;xoQrM-1U8)Lv5k z`j4#Tg+fu1tYO%`95;&-Dt zM6PHWvF5=U%-Ie2QEDoAr=SHdmTt%vm_ACLG$_%?XT~MICvb&2&4L6=XB{k-fnUp( z4nc=-k}3w0S3&6A2_)lWCz**tDW=MSw7 zv{7d-1k&kI>T`=bTQMovD!)?|?WpV_rQ2`yU>lHi-pL2uBEh{Z-xCyi9en4;koGsA*u;j^)aXmWB~+dO^3WNv3+?aDUYs~3bDBw)w)ZMy>b zYN%83*kKsW+pm?wNLW_)qHAGI2*yM%O3L;sZ-}b&?>B{vd5uW+ZK`ZP+-+)cZb++1 zIEJ65(vXlsYy$+M?2tz9o`g&ggfEqLsicnZwsEon6vER%9f1Wk8Af=zpTb_O;C^t` zT=_tk4J7EQXA42bv2tgKBf}w`3}|HN1ekOg$6rAWXKsd$NfE*rXRogLGE~$K?(1v! zO&nYdx0>N^=$NrCHf$V;BcQjqKjAsyMMcqw5#Dh$&;2NfA4nO){!I0V)+kmx)=u(9 z)Ov}{`EzxO69CtstRD~tm8%UR`K{Z&XS#8kBuk@C^%M+q?`()G^dushU-!)4@GZn( zncF(W<|^LFG*M^3YU$5vkSG)d$;8s%x9)d48^5~9noYfy88eB3&KE0H`ePR`AsWlg5;XG#!{nED2%|s2Xk-(NWTxc4( z-H>o6($JdvkdA^){Zf7Dn;OacU0`STF( zNsmJvPb*Dp{KojWS1@*;wich>ZOdSb4v`r*-I_{QKFz6lBb8mYtZP_Ou4L1zW-nvB z|K6nFoeqlqMM&EU>_W+%kQ2_m1r-O|WW;Pzh-uic%d6UsE}?#WvLRLKeZwU?!(r_z z^x)nS4&PA3P8F}XQC#CGDm!|a-VY#JFbJCdWIyXY301lsLyJgBxV;>`?#O~7pK(;P1uAR zm!tz3y_Q!9KizbDbsiz0_d6*?#)zc{tjnX)2p zFfIj775bNZ4l!+O`lJ9hLL2@7G}I5?ci2p5+GtG(&)?;Ge(ai^jw#@1gg3PKLl9#_ z2Wv%OR-UE7=s@ej-Q7(Ai16&;9O0HZ&jfSC=I-4MyEdz7T*mPL%Kwtw^h*&wnKx(v6kOEmmACiN`*!T1 zFZ=xq|Jv*OrCRMeMnp=Aj|~m96p+vcGx5lD1{7tiZL+f$Ki+BUQa%nqP`>DWOU9xp z_cuS7^qi__Lt;LLrhiCzrnsM7l@0A1tb)KB$6ngWSW_ian(3$+A2Z{{y>qjn{6FU) z+Dcv;tp%)0Cy6mHUhj4>>zhl_jS+nN_}wUOhva2xOikM*n}paB^|eLxC@!~*QL*&9pK9Upq^X6RN24RZmfM|@j-+Ur);TZ5VvW z={ZZ_P-oxi>qHaZ#vJr za-yx*S#k+$ck7wsBuC`Wmv6xejywPtXDXYyWGh7X1Gm*UpFV@oAd+-PXY2LpggW`b z8K;i3Z7&{fVhCl0y^u+(`bTI)=VVubpYCWo<5Mqxoxt*!StFhng|mgp30{W!G-N!*W zHK+XsCA=4iY(?eCQS1aDY8#1FdpR|}%n++mjoKK=y4lep=qj#2PBBfFDd%bU{+iCT z#OPji&4fpTtG0XIh$GIkIgl+KFq-yx&H5*&pr271w`O=1lyFMI74%_CMwFzKvFc!sg%qjcrw=0V@R@#l zKF;-UD5hMzPdmVOG0+k=fuyR&+V89Zf7ukETCz>Tu|;SBjOSXKKK>el)b6eG#|0NV^P+Sx`0@_pBjRuR<1;#q+xc>z z_OD#wm7cN^An@ka?+Df7=BV_BVKvh9%%%=NL{hK8p-Mq@Ymwf}1^xK7tF;#l+z8v- zmN_rfS~^aBP4s&CHm#<)c9WnSIw^|oACJ^AGxBF$B$j_kj%4E#=9u-Gj;#l$??)6c z(OP}mK5s&tpIA;2?se$>?phI$(Px%RJ%}|);EHIHB@e7J*|ULywcvugT;J{i;e|q3 zuU(gLaBha8#8Xyi+PY|DR6xl0BQ zWlwT1m1KVv<0!DS>xQlB?x2gd^~Vp{VkHekX{=HHY0efo422K_ji3QhkH=BHNQ@-{Hd!c=aX>9}Pn(ARRy(w)eK6tWdJ z?li%td?bj({N~r+9Pc;FvM_8uwt`m_3Z|KL8mu}#Evqusl$9GIC0rDayez_jY-39f zD8nh;k3U|yBx1jouSss?n%;DwfWVvpJ&o}q2k%(}U>e+dWbCCw=)Bn}h{8&9#;p#L zR1&$2YBjilm2D+++>OSPz&st<39V>WG`q7MgyNST)C9r`gTrP^$5zU(^8Xrwnziz0 z;?k|7o-{@mJgOf+@1XH-8K+b|hbCd0n&Rc|oIQ0N1*p#P_~tWsXkG4{hZ8bZo~kr(vVO!VG#2hbCFJ z!95k890Mgx1L3|lV`%+q{z_+l)@A7Gbfu@Wrf&yu;*LTY5Ju~5< z8YycnqNvhUjInfcG0umJ86kBtdMQ|fElyoR)_eTPdr7-XfEG6=Agwa2UlC3TH*1WNw+j-g#$v{SXhC(LuUEnE9`7pz$+k`dTbc#L}>7RY=O$81ReYO;L-A}EU(v9l4yrOZ*X^?~m*2T?Z4 zFOl3)+^l%J7@{#HR+qB>5=$ryx_zwKn5u)(j*~voeqYBzn94P*h82V^A_?29&+-YB zwWqzrOPgDa$NdCXwM9mSUFCkpeo<&F-;o)H1v#;6Ab(EK{AB8MS;;!IRh>8Ar2?3| zou$+D1w1O&W;&s8UctgXC^9n#HpVJ8g6%?xw+n3u?A`2q>D{#~`TI+X_j)Av0jSZ9 z-vS+W(mR0^8W4Mwwa!|m!iF%A18`@PCA*q>b&tFEeeY_~3cL|quNpC|uwOFlO#C=c z;MEB^QbwjT4Eo719B9J=V7@z=sKVbgMBvk_aR!#J7?Tb!-IRlHRwvcxI`rbzuG|=# zD@uXHN}=`ru;!80Si11H4YK54?Da?E;=b-X4?YyiuvG(FwI_At9DU8bOG&9IKn4qQxAm zgMrKrRD<}vJ=<80BhFm<$w>Cz8)i@6{-?n<;rcQ2dX<_&E=q^KEL){=jCh$CW#CL8 zEd-j;!52Tfzy#2#ArbSfb0O$xAvfD=J38NNO!ltPlh8;7WSJR5c2$V-tz%9D@++@ji>`igwf5zkj5!Mrf_K)(S4J&B7yq!fzCX#F;RG02twUx z+h;&l*bN?R=Va0C=eyjUT(wAn9F;*EUAnMh3palJ`e<}ScC0^s&rK_;JoWw3L{uGU zeA1;97Mxdk-Gblaw%c^(F$(la`kd)S_Jjt4?`ZdAsXeI2lRAdUiIY<^XwF2KQ=-f( zkIg!s2tY9DKpqw1@}kMHCre}mOOx_1IV0t>gQ*#lhrXkSgJaw(EVrC93a_Jb-XJuP z)o-_Pwt13lXhcWPTLF#d6n_mO{Jl5m_ybcc5BAk=5jL;{N1OuidT=l{?D-f;&*Gz- zDC+-%7V-h|du)YD5F5HYkV_$@BzxZWqTzmC?HS1KuXhqRyCCir@L#5N#66~St`|_f z1SLEA4fL#On`B(jcyCed^n?K0JL;9b?ZLZt8=U!tJX^T*+lV9ubRNaSj~(5{LDKTl zT?gwoJPzCF^tAognBy2p_;II=bwMqqX)fwTeDXRYB$?Ht$)bpH;oVePLzh9T?0&K^ z^llC3&)Q!#S>!f|yOjfSz@dJ&Y=BY*`4C^%z3jnD*{DKsdY&pNMt-(Bw zW!pj&h~6H#)#F*(&L&&ygrup&-}K|>`w0hyn2%;~7y=Ow81yxQAH6uL%22K6oA8wX z^$UoF$&iV8CfX8+rIm@ezSJNPTk)cL5jPhXf|y>E%E#jUPPQ#sB7FVQI@Wq&WknVd z!b<^2^#fa&BfE_%g3ot8Ohz=7sWw4DGq*8x{0cwT#oGl(?7J^V%rMjK6wPQ&^>9+w z{LZPS20XuR(Pq}>R?mz{;)9djlQbz%X3d=H%B$xh)>K%#@FKkB66N&#e*|fdi|0|C z`u-A@AP;P;_o{>Wv%^Q=5?m=GV1;D^Kt$#Z!G=#i4{(6cdJ)dtl2F1&D8e$Bb2toA z2WM6KE^>!hM%Px?`OvW_T8>T!JN|4V9T9K^x3V!eLvhN9+&7*9tK*r<%m$R|UzGbr0V_`e_oI;q`(MsS)BI@w literal 0 HcmV?d00001 diff --git a/packages/vite/test/vite.test.js b/packages/vite/test/vite.test.js index b44b024493..7cc05bebf3 100644 --- a/packages/vite/test/vite.test.js +++ b/packages/vite/test/vite.test.js @@ -687,6 +687,30 @@ describe('@apostrophecms/vite', function () { assert.ok(fs.existsSync(path.join(bundleDir, 'public-src-module-bundle.js'))); assert.ok(fs.existsSync(path.join(bundleDir, 'tools-module-bundle.js'))); }); + + it('should emit public module assets at the URL apos.asset.url() returns', async function () { + const bundleDir = apos.asset.getBundleRootDir(); + const css = await fs.readFile(path.join(bundleDir, 'article-bundle.css'), 'utf8'); + const fonts = [ + // Same file name in two modules must not collide + '/modules/article-page/fonts/sans.woff2', + '/modules/article-widget/fonts/sans.woff2' + ]; + for (const font of fonts) { + assert.ok(css.includes(`url(${apos.asset.url(font)})`), `CSS does not reference ${font}`); + const built = await fs.readFile(path.join(bundleDir, font)); + const source = await fs.readFile(path.join( + __dirname, + 'modules', + font.replace(/^\/modules\/([^/]+)\//, '$1/public/') + )); + assert.ok(built.equals(source), `unexpected content for ${font}`); + } + const hashed = fs.existsSync(path.join(bundleDir, 'assets')) + ? (await fs.readdir(path.join(bundleDir, 'assets'))).filter(f => f.endsWith('.woff2')) + : []; + assert.deepEqual(hashed, [], 'no hashed copies of fonts expected'); + }); }); });