@@ -45,6 +45,13 @@ export const endOfLoadProtocol = 'sass-embedded-legacy-load-done:';
4545 */
4646export const legacyImporterFileProtocol = 'legacy-importer-file:' ;
4747
48+ /**
49+ * A random namespace for `sass:meta`, so we can use `meta.load-css()` at the end
50+ * of the file to signal that a load has finished without polluting a namespace
51+ * a user might actually use.
52+ */
53+ export const metaNamespace = `---${ Math . random ( ) . toString ( 36 ) . substring ( 2 ) } ` ;
54+
4855// A count of `endOfLoadProtocol` imports that have been generated. Each one
4956// must be a different URL to ensure that the importer results aren't cached.
5057let endOfLoadCount = 0 ;
@@ -247,22 +254,20 @@ export class LegacyImporterWrapper<sync extends 'sync' | 'async'>
247254 this . lastContents ??
248255 fs . readFileSync ( legacyFileUrlToPath ( canonicalUrl ) , 'utf-8' ) ;
249256 this . lastContents = undefined ;
250- if ( syntax === 'scss' ) {
251- contents += this . endOfLoadImport ;
252- } else if ( syntax === 'indented' ) {
253- contents += `\n@import "${ endOfLoadProtocol } ${ endOfLoadCount ++ } "` ;
254- } else {
257+ if ( syntax === 'css' ) {
255258 this . prev . pop ( ) ;
259+ } else {
260+ contents = this . wrapContents ( contents , syntax ) ;
256261 }
257262
258263 return { contents, syntax, sourceMapUrl : canonicalUrl } ;
259264 }
260265
261- const lastContents = this . lastContents ;
266+ const lastContents = this . lastContents ! ;
262267 assert . notEqual ( lastContents , undefined ) ;
263268 this . lastContents = undefined ;
264269 return {
265- contents : lastContents + this . endOfLoadImport ,
270+ contents : this . wrapContents ( lastContents , 'scss' ) ,
266271 syntax : 'scss' ,
267272 sourceMapUrl : canonicalUrl ,
268273 } ;
@@ -333,10 +338,22 @@ export class LegacyImporterWrapper<sync extends 'sync' | 'async'>
333338 } ) as PromiseOr < LegacyImporterResult , sync > ;
334339 }
335340
336- // The `@import` statement to inject after the contents of files to ensure
337- // that we know when a load has completed so we can pass the correct `prev`
338- // argument to callbacks.
339- private get endOfLoadImport ( ) : string {
340- return `\n;@import "${ endOfLoadProtocol } ${ endOfLoadCount ++ } ";` ;
341+ // Modifies {@link contents } to ensure that we know when a load has completed
342+ // so we can pass the correct `prev` argument to callbacks.
343+ private wrapContents ( contents : string , syntax : 'scss' | 'indented' ) : string {
344+ const url = `"${ endOfLoadProtocol } ${ endOfLoadCount ++ } "` ;
345+ if ( syntax === 'scss' ) {
346+ return (
347+ `@use "sass:meta" as ${ metaNamespace } ;` +
348+ contents +
349+ `\n;@include ${ metaNamespace } .load-css(${ url } );`
350+ ) ;
351+ } else {
352+ return (
353+ `@use "sass:meta" as ${ metaNamespace } \n` +
354+ contents +
355+ `\n@include ${ metaNamespace } .load-css(${ url } )`
356+ ) ;
357+ }
341358 }
342359}
0 commit comments