@@ -31,7 +31,8 @@ import {
31
31
compileScript as sfc_compileScript ,
32
32
compileTemplate as sfc_compileTemplate ,
33
33
SFCAsyncStyleCompileOptions ,
34
- SFCTemplateCompileOptions
34
+ SFCTemplateCompileOptions ,
35
+ SFCBlock
35
36
} from '@vue/compiler-sfc'
36
37
37
38
import {
@@ -84,6 +85,12 @@ interface PathHandlers {
84
85
type File = string | { content : string , extname : string } ;
85
86
86
87
88
+ /**
89
+ * CustomBlockCallback function type
90
+ */
91
+ type CustomBlockCallback = ( component : Module ) => undefined ;
92
+
93
+
87
94
interface Options {
88
95
// ts: https://www.typescriptlang.org/docs/handbook/interfaces.html#indexable-types
89
96
@@ -294,6 +301,28 @@ interface Options {
294
301
*/
295
302
pathHandlers : PathHandlers ,
296
303
304
+
305
+ /**
306
+ * Called for each custom block.
307
+ * @returns A Promise of the module or undefined
308
+ *
309
+ * ```javascript
310
+ * ...
311
+ * customBlockHandler(block, filename, options) {
312
+ *
313
+ * if ( block.type !== 'i18n' )
314
+ * return;
315
+ *
316
+ * return (component) => {
317
+ *
318
+ * component.i18n = JSON.parse(block.content);
319
+ * }
320
+ * }
321
+ * ...
322
+ * ```
323
+ */
324
+ customBlockHandler ( block : SFCBlock , filename : string , options : Options ) : Promise < CustomBlockCallback | undefined > ,
325
+
297
326
}
298
327
299
328
@@ -592,16 +621,19 @@ async function createJSModule(source : string, moduleSourceType : boolean, filen
592
621
/**
593
622
* @internal
594
623
*/
595
- async function createSFCModule ( source : string , filename : string , options : Options ) {
624
+ async function createSFCModule ( source : string , filename : string , options : Options ) : Promise < Module > {
596
625
597
- const { delimiters, moduleCache, compiledCache, addStyle, log, additionalBabelPlugins = [ ] } = options ;
626
+ const { delimiters, moduleCache, compiledCache, addStyle, log, additionalBabelPlugins = [ ] , customBlockHandler } = options ;
598
627
599
628
// vue-loader next: https://github.com/vuejs/vue-loader/blob/next/src/index.ts#L91
600
629
const { descriptor, errors } = sfc_parse ( source , {
601
630
filename,
602
631
sourceMap : genSourcemap ,
603
632
} ) ;
604
633
634
+
635
+ const customBlockCallbacks : CustomBlockCallback [ ] = customBlockHandler !== undefined ? await Promise . all ( descriptor . customBlocks . map ( block => customBlockHandler ( block , filename , options ) ) ) : [ ] ;
636
+
605
637
const componentHash = hash ( filename , version ) ;
606
638
const hasScoped = descriptor . styles . some ( e => e . scoped ) ;
607
639
const scopeId = `data-v-${ componentHash } ` ;
@@ -758,6 +790,8 @@ async function createSFCModule(source : string, filename : string, options : Opt
758
790
addStyle ( style , descStyle . scoped ? scopeId : undefined ) ;
759
791
}
760
792
793
+ await Promise . all ( customBlockCallbacks . map ( cb => cb ?.( component ) ) ) ;
794
+
761
795
return component ;
762
796
}
763
797
0 commit comments