@@ -3,7 +3,7 @@ import { readdir, readFile, writeFile } from 'node:fs/promises';
33import { existsSync , readFileSync } from 'node:fs' ;
44import { dirname , extname , resolve } from 'node:path' ;
55import { transform , composeVisitors } from 'lightningcss' ;
6- import { Timer } from './utils/timer.mjs' ;
6+ import { Timer } from '.. /utils/timer.mjs' ;
77
88const RootPath = process . cwd ( ) ;
99const skipExternal = true ;
@@ -37,17 +37,13 @@ function version(urlString, fromFile) {
3737 * @param {from: String } - the filepath for the css file
3838 * @returns {import('lightningcss').Visitor } - A visitor that replaces the url
3939 */
40- function urlVersioning ( fromFile ) {
41- return {
42- /**
43- * @param {import('lightningcss').Url } url - The url object to transform
44- * @returns {import('lightningcss').Url } - The transformed url object
45- */
46- Url ( url ) {
47- return { ...url , ...{ url : version ( url . url , fromFile ) } } ;
48- } ,
49- } ;
50- }
40+ const urlVersioning = ( fromFile ) => ( {
41+ /**
42+ * @param {import('lightningcss').Url } url - The url object to transform
43+ * @returns {import('lightningcss').Url } - The transformed url object
44+ */
45+ Url : ( url ) => ( { ...url , url : version ( url . url , fromFile ) } ) ,
46+ } ) ;
5147
5248/**
5349 * Adds a hash to the url() parts of the static css
@@ -57,8 +53,25 @@ function urlVersioning(fromFile) {
5753 */
5854const fixVersion = async ( file ) => {
5955 try {
56+ let content = await readFile ( file , { encoding : 'utf8' } ) ;
57+ // To preserve the licence the comment needs to start at the beginning of the file
58+ const replaceUTF8String = file . endsWith ( '.min.css' ) ? '@charset "UTF-8";' : '@charset "UTF-8";\n' ;
59+ content = content . startsWith ( replaceUTF8String ) ? content . replace ( replaceUTF8String , '' ) : content ;
60+
61+ // Preserve a leading license comment (/** ... */)
62+ const firstLine = content . split ( / \r ? \n / ) [ 0 ] || '' ;
63+ if ( firstLine . includes ( '/*' ) && ! firstLine . includes ( '/*!' ) ) {
64+ const endCommentIdx = content . indexOf ( '*/' ) ;
65+ if ( endCommentIdx !== - 1
66+ && ( content . substring ( 0 , endCommentIdx ) . includes ( 'license' )
67+ || content . substring ( 0 , endCommentIdx ) . includes ( 'copyright' ) )
68+ ) {
69+ content = firstLine . includes ( '/**' ) ? content . replace ( '/**' , '/*!' ) : content . replace ( '/*' , '/*!' ) ;
70+ }
71+ }
72+
6073 const { code } = transform ( {
61- code : await readFile ( file ) ,
74+ code : Buffer . from ( content ) ,
6275 minify : file . endsWith ( '.min.css' ) ,
6376 visitor : composeVisitors ( [ urlVersioning ( file ) ] ) ,
6477 } ) ;
@@ -76,13 +89,15 @@ const fixVersion = async (file) => {
7689 *
7790 * @returns {Promise<void> }
7891 */
79- export const cssVersioning = async ( ) => {
92+ const cssVersioningVendor = async ( ) => {
8093 const bench = new Timer ( 'Versioning' ) ;
8194
82- const cssFiles = ( await readdir ( `${ RootPath } /media` , { withFileTypes : true , recursive : true } ) )
95+ const cssFiles = ( await readdir ( `${ RootPath } /media/vendor ` , { withFileTypes : true , recursive : true } ) )
8396 . filter ( ( file ) => ( ! file . isDirectory ( ) && extname ( file . name ) === '.css' ) )
8497 . map ( ( file ) => `${ file . path } /${ file . name } ` ) ;
8598
8699 Promise . all ( cssFiles . map ( ( file ) => fixVersion ( file ) ) )
87100 . then ( ( ) => bench . stop ( ) ) ;
88101} ;
102+
103+ export { urlVersioning , cssVersioningVendor } ;
0 commit comments