@@ -3,7 +3,7 @@ import { readdir, readFile, writeFile } from 'node:fs/promises';
3
3
import { existsSync , readFileSync } from 'node:fs' ;
4
4
import { dirname , extname , resolve } from 'node:path' ;
5
5
import { transform , composeVisitors } from 'lightningcss' ;
6
- import { Timer } from './utils/timer.mjs' ;
6
+ import { Timer } from '.. /utils/timer.mjs' ;
7
7
8
8
const RootPath = process . cwd ( ) ;
9
9
const skipExternal = true ;
@@ -37,17 +37,13 @@ function version(urlString, fromFile) {
37
37
* @param {from: String } - the filepath for the css file
38
38
* @returns {import('lightningcss').Visitor } - A visitor that replaces the url
39
39
*/
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
+ } ) ;
51
47
52
48
/**
53
49
* Adds a hash to the url() parts of the static css
@@ -57,8 +53,25 @@ function urlVersioning(fromFile) {
57
53
*/
58
54
const fixVersion = async ( file ) => {
59
55
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
+
60
73
const { code } = transform ( {
61
- code : await readFile ( file ) ,
74
+ code : Buffer . from ( content ) ,
62
75
minify : file . endsWith ( '.min.css' ) ,
63
76
visitor : composeVisitors ( [ urlVersioning ( file ) ] ) ,
64
77
} ) ;
@@ -76,13 +89,15 @@ const fixVersion = async (file) => {
76
89
*
77
90
* @returns {Promise<void> }
78
91
*/
79
- export const cssVersioning = async ( ) => {
92
+ const cssVersioningVendor = async ( ) => {
80
93
const bench = new Timer ( 'Versioning' ) ;
81
94
82
- const cssFiles = ( await readdir ( `${ RootPath } /media` , { withFileTypes : true , recursive : true } ) )
95
+ const cssFiles = ( await readdir ( `${ RootPath } /media/vendor ` , { withFileTypes : true , recursive : true } ) )
83
96
. filter ( ( file ) => ( ! file . isDirectory ( ) && extname ( file . name ) === '.css' ) )
84
97
. map ( ( file ) => `${ file . path } /${ file . name } ` ) ;
85
98
86
99
Promise . all ( cssFiles . map ( ( file ) => fixVersion ( file ) ) )
87
100
. then ( ( ) => bench . stop ( ) ) ;
88
101
} ;
102
+
103
+ export { urlVersioning , cssVersioningVendor } ;
0 commit comments