@@ -16,6 +16,25 @@ const node_fs_1 = require("node:fs");
1616const node_path_1 = require ( "node:path" ) ;
1717const node_url_1 = require ( "node:url" ) ;
1818const lexer_1 = require ( "./lexer" ) ;
19+ /**
20+ * Ensures that a bare specifier URL path that is intended to be treated as
21+ * a relative path has a leading `./` or `../` prefix.
22+ *
23+ * @param url A bare specifier URL path that should be considered relative.
24+ * @returns
25+ */
26+ function ensureRelative ( url ) {
27+ // Empty
28+ if ( ! url ) {
29+ return url ;
30+ }
31+ // Already relative
32+ if ( url [ 0 ] === '.' && ( url [ 1 ] === '/' || ( url [ 1 ] === '.' && url [ 2 ] === '/' ) ) ) {
33+ return url ;
34+ }
35+ // Needs prefix
36+ return './' + url ;
37+ }
1938/**
2039 * A Sass Importer base class that provides the load logic to rebase all `url()` functions
2140 * within a stylesheet. The rebasing will ensure that the URLs in the output of the Sass compiler
@@ -46,8 +65,13 @@ class UrlRebasingImporter {
4665 // Rebase any URLs that are found
4766 let updatedContents ;
4867 for ( const { start, end, value } of ( 0 , lexer_1 . findUrls ) ( contents ) ) {
49- // Skip if value is empty, a Sass variable, or Webpack-specific prefix
50- if ( value . length === 0 || value [ 0 ] === '$' || value [ 0 ] === '~' || value [ 0 ] === '^' ) {
68+ // Skip if value is empty or Webpack-specific prefix
69+ if ( value . length === 0 || value [ 0 ] === '~' || value [ 0 ] === '^' ) {
70+ continue ;
71+ }
72+ // Skip if value is a Sass variable.
73+ // Sass variable usage either starts with a `$` or contains a namespace and a `.$`
74+ if ( value [ 0 ] === '$' || / ^ \w + \. \$ / . test ( value ) ) {
5175 continue ;
5276 }
5377 // Skip if root-relative, absolute or protocol relative url
@@ -57,9 +81,10 @@ class UrlRebasingImporter {
5781 const rebasedPath = ( 0 , node_path_1 . relative ) ( this . entryDirectory , ( 0 , node_path_1 . join ) ( stylesheetDirectory , value ) ) ;
5882 // Normalize path separators and escape characters
5983 // https://developer.mozilla.org/en-US/docs/Web/CSS/url#syntax
60- const rebasedUrl = './' + rebasedPath . replace ( / \\ / g, '/' ) . replace ( / [ ( ) \s ' " ] / g, '\\$&' ) ;
84+ const rebasedUrl = ensureRelative ( rebasedPath . replace ( / \\ / g, '/' ) . replace ( / [ ( ) \s ' " ] / g, '\\$&' ) ) ;
6185 updatedContents ??= new magic_string_1 . default ( contents ) ;
62- updatedContents . update ( start , end , rebasedUrl ) ;
86+ // Always quote the URL to avoid potential downstream parsing problems
87+ updatedContents . update ( start , end , `"${ rebasedUrl } "` ) ;
6388 }
6489 if ( updatedContents ) {
6590 contents = updatedContents . toString ( ) ;
0 commit comments