@@ -6,6 +6,7 @@ const requireFromString = require("require-from-string");
6
6
const vueCompiler = require ( "vue-template-compiler" ) ;
7
7
// @ts -ignore
8
8
const vueify = require ( "vueify" ) ;
9
+ vueify . compiler . loadConfig ( ) ;
9
10
const vueServerRenderer = require ( "vue-server-renderer" ) ;
10
11
const Vue = require ( "vue" ) ;
11
12
const uglify = require ( "uglify-js" ) ;
@@ -60,10 +61,12 @@ class Renderer {
60
61
max : 500 ,
61
62
maxAge : 1000 * 60 * 60 ,
62
63
} ;
64
+ this . renderer = vueServerRenderer . createRenderer ( ) ;
63
65
this . lruCache = LRU ( this . cacheOptions ) ;
64
66
this . internalCache = new Utils . Cache ( ) ;
65
67
this . head = options . head || { } ;
66
68
this . data = options . data || { } ;
69
+ this . propsData = options . propsData || { } ;
67
70
this . template = options . template || { } ;
68
71
const version = Utils . VueVersion ( options . vueVersion ) ;
69
72
if ( version . enabled ) {
@@ -93,15 +96,18 @@ class Renderer {
93
96
console . error ( `Error Precaching \nfilePath -> ${ filePath } \n-------\n${ error } ` ) ;
94
97
} ) ;
95
98
}
96
- } ) ;
99
+ } ) ;
97
100
}
98
101
99
102
this . nodeModulesPath = Utils . FindNodeModules ( this . rootPath ) ;
100
103
this . jsToStringOptions = {
101
104
functions : [
102
105
{
103
106
name : "data" ,
104
- // @ts -ignore
107
+ /**
108
+ * @param {function } script
109
+ * @return {string|void }
110
+ */
105
111
toString : function ( script ) {
106
112
const func = `module.exports = function data() { return ${ jsToString ( script ( ) ) } ; };` ;
107
113
const required = requireFromString ( func ) ;
@@ -123,6 +129,14 @@ class Renderer {
123
129
return mergedData ;
124
130
} ;
125
131
}
132
+ /**
133
+ * @param {Object } oldPropsData
134
+ * @param {Object } newPropsData
135
+ * @returns {Function }
136
+ */
137
+ FixPropsData ( oldPropsData , newPropsData ) {
138
+ return Object . assign ( { } , oldPropsData , this . propsData , newPropsData ) ;
139
+ }
126
140
/**
127
141
* @param {string } componentFile
128
142
* @param {string } filePath
@@ -144,25 +158,27 @@ class Renderer {
144
158
let reg ;
145
159
const isES6 = compiledObject . compiled . includes ( "use strict" ) ;
146
160
if ( isES6 ) {
147
- reg = / (?: " u s e s t r i c t " ; ) ( .* ) (?: m o d u l e .e x p o r t s = { | e x p o r t s .d e f a u l t = { ) ( .* ) (?: } } \( \) ; ? ) (?: .* ) (?: _ _ v u e _ _ o p t i o n s _ _ .r e n d e r = f u n c t i o n \( \) { ) ( .* ) (?: } , ? ; ? _ _ v u e _ _ o p t i o n s _ _ .s t a t i c R e n d e r F n s = \[ ) ( .* ) (?: \] ) / gm;
161
+ reg = / (?: " u s e s t r i c t " ; ) ( .* ) (?: m o d u l e .e x p o r t s = { | e x p o r t s .d e f a u l t = { ) ( .* ) (?: } } \( \) ; ? ) (?: .* ) (?: _ _ v u e _ _ o p t i o n s _ _ .r e n d e r = f u n c t i o n \( \) { ) ( .* ) (?: } , ? ; ? _ _ v u e _ _ o p t i o n s _ _ .s t a t i c R e n d e r F n s = \[ ) ( .* ) (?: \] ) ( (?: , ? ; ? _ _ v u e _ _ o p t i o n s _ _ . _ s c o p e I d = " ) ( . * ) (?: " ) ) ? / gm;
148
162
} else {
149
- reg = / (? ! " u s e s t r i c t " ; ) ( .* ) (?: m o d u l e .e x p o r t s = { | e x p o r t s .d e f a u l t = { ) ( .* ) (?: } \( ? \) ? ; ? ) (?: .* ) (?: _ _ v u e _ _ o p t i o n s _ _ .r e n d e r = f u n c t i o n \( \) { ) ( .* ) (?: } , ? ; ? _ _ v u e _ _ o p t i o n s _ _ .s t a t i c R e n d e r F n s = \[ ) ( .* ) (?: \] ) / gm;
163
+ reg = / (? ! " u s e s t r i c t " ; ) ( .* ) (?: m o d u l e .e x p o r t s = { | e x p o r t s .d e f a u l t = { ) ( .* ) (?: } \( ? \) ? ; ? ) (?: .* ) (?: _ _ v u e _ _ o p t i o n s _ _ .r e n d e r = f u n c t i o n \( \) { ) ( .* ) (?: } , ? ; ? _ _ v u e _ _ o p t i o n s _ _ .s t a t i c R e n d e r F n s = \[ ) ( .* ) (?: \] ) ( (?: , ? ; ? _ _ v u e _ _ o p t i o n s _ _ . _ s c o p e I d = " ) ( . * ) (?: " ) ) ? / gm;
150
164
}
151
165
152
166
let vueComponent = "" ;
153
167
let imports = "" ;
154
168
let moduleExports = "" ;
155
169
let renderFunctionContents = "" ;
156
170
let staticRenderFns = "" ;
171
+ let scopeId = "" ;
157
172
158
- let { code} = uglify . minify ( compiledObject . compiled , { mangle : false } ) ;
173
+ let { code } = uglify . minify ( compiledObject . compiled , { mangle : false } ) ;
159
174
160
175
const matches = reg . exec ( code ) ;
161
176
if ( matches && matches . length > 0 ) {
162
177
const importMatch = matches [ 1 ] ;
163
178
const exportMatch = matches [ 2 ] ;
164
179
const renderMatch = matches [ 3 ] ;
165
180
const staticMatch = matches [ 4 ] ;
181
+ const scopeMatch = matches [ 6 ] ;
166
182
167
183
if ( importMatch && importMatch !== "" ) {
168
184
imports = importMatch ;
@@ -180,12 +196,16 @@ class Renderer {
180
196
staticRenderFns = `,staticRenderFns: [${ staticMatch } ]` ;
181
197
}
182
198
199
+ if ( scopeMatch && scopeMatch !== "" ) {
200
+ scopeId = `,_scopeId: "${ scopeMatch } "` ;
201
+ }
202
+
183
203
}
184
204
185
205
if ( imports === "" ) {
186
- vueComponent = `{${ moduleExports } ${ renderFunctionContents } ${ staticRenderFns } }` ;
206
+ vueComponent = `{${ moduleExports } ${ renderFunctionContents } ${ staticRenderFns } ${ scopeId } }` ;
187
207
} else {
188
- vueComponent = `function(){${ imports } return {${ moduleExports } ${ renderFunctionContents } ${ staticRenderFns } }}()` ;
208
+ vueComponent = `function(){${ imports } return {${ moduleExports } ${ renderFunctionContents } ${ staticRenderFns } ${ scopeId } }}()` ;
189
209
}
190
210
if ( vueComponent . includes ( "Object.defineProperty(exports,\"__esModule\",{value:!0}),return" ) ) {
191
211
vueComponent = vueComponent . replace ( "Object.defineProperty(exports,\"__esModule\",{value:!0}),return" , "Object.defineProperty(exports,\"__esModule\",{value:!0});return" ) ;
@@ -325,7 +345,7 @@ class Renderer {
325
345
filePath : filePath ,
326
346
} ;
327
347
328
- const stylesArray = vueCompiler . parseComponent ( content , { pad : true } ) . styles ;
348
+ const stylesArray = vueCompiler . parseComponent ( content , { pad : true } ) . styles ;
329
349
// @ts -ignore
330
350
const compiler = vueify . compiler ;
331
351
compiler . compile ( content , filePath ,
@@ -334,31 +354,42 @@ class Renderer {
334
354
* @param {string } stringFile
335
355
*/
336
356
function ( error , stringFile ) {
337
- if ( error ) {
338
- reject ( error ) ;
339
- }
340
- stringFile = vm . FindAndReplaceScripts ( stringFile , filePath ) ;
341
- if ( stylesArray . length > 0 ) {
342
- processStyle ( stylesArray [ 0 ] , filePath , "" , resolvedParts )
343
- . then ( processedStyle => {
344
- compiled . compiled = stringFile ;
345
- compiled . style += processedStyle ;
346
- resolve ( compiled ) ;
347
- } )
348
- . catch ( reject ) ;
349
- } else {
350
- compiled . compiled = stringFile ;
351
- resolve ( compiled ) ;
352
- }
353
- } ) ;
357
+ if ( error ) {
358
+ reject ( error ) ;
359
+ }
360
+ stringFile = vm . FindAndReplaceScripts ( stringFile , filePath ) ;
361
+ let id = "" ;
362
+ stringFile . replace ( / _ _ v u e _ _ o p t i o n s _ _ \. _ s c o p e I d = " ( .* ?) " / gm,
363
+ /**
364
+ * @param {string } match
365
+ * @param {string } p1
366
+ * @return {string }
367
+ */
368
+ function ( match , p1 ) {
369
+ id = p1 ;
370
+ return "" ;
371
+ } ) ;
372
+ if ( stylesArray . length > 0 ) {
373
+ processStyle ( stylesArray [ 0 ] , filePath , id , resolvedParts )
374
+ . then ( processedStyle => {
375
+ compiled . compiled = stringFile ;
376
+ compiled . style += processedStyle ;
377
+ resolve ( compiled ) ;
378
+ } )
379
+ . catch ( reject ) ;
380
+ } else {
381
+ compiled . compiled = stringFile ;
382
+ resolve ( compiled ) ;
383
+ }
384
+ } ) ;
354
385
} ) ;
355
386
} ) ;
356
387
}
357
388
/**
358
389
*
359
390
* @param {CompiledObjectType } compiledObject
360
391
* @param {string } filePath
361
- * @returns {Promise<{data: object}> }
392
+ * @returns {Promise<{data: object, propsData: object, props: object }> }
362
393
*/
363
394
MakeBundle ( compiledObject , filePath ) {
364
395
return new Promise ( ( resolve , reject ) => {
@@ -374,18 +405,27 @@ class Renderer {
374
405
*
375
406
* @param {string } filePath
376
407
* @param {Object } data
408
+ * @param {{data: Object, propsData: Object} | Object } vueOptions
377
409
* @returns {Promise<{vue: object, css: string, script: string}> }
378
410
*/
379
- MakeVueClass ( filePath , data ) {
411
+ MakeVueClass ( filePath , data , vueOptions = { } ) {
380
412
return new Promise ( ( resolve , reject ) => {
381
413
let cachedBundle = this . internalCache . get ( filePath ) ;
382
414
if ( cachedBundle ) {
415
+ const cachedData = Object . assign ( { } , cachedBundle . data ( ) ) ;
416
+ const newbundle = Object . assign ( { } , cachedBundle . bundle ) ;
417
+
383
418
if ( cachedBundle . bundle . data && typeof cachedBundle . bundle . data === "function" ) {
384
- cachedBundle . bundle . data = this . FixData ( cachedBundle . bundle . data ( ) , data ) ;
419
+ newbundle . data = this . FixData ( cachedData , data ) ;
385
420
}
421
+ if ( vueOptions . propsData && ( cachedBundle . bundle . propsData || cachedBundle . bundle . props ) ) {
422
+ newbundle . propsData = this . FixPropsData ( cachedBundle . bundle . propsData || { } , vueOptions . propsData ) ;
423
+ }
424
+
386
425
// @ts -ignore
387
- const vue = new Vue ( cachedBundle . bundle ) ;
388
- const cleanBundle = this . _deleteCtor ( cachedBundle . bundle ) ;
426
+ const vue = new Vue ( newbundle ) ;
427
+ // vue._data = newbundle.data();
428
+ const cleanBundle = this . _deleteCtor ( newbundle ) ;
389
429
const object = {
390
430
vue : vue ,
391
431
css : cachedBundle . style ,
@@ -398,11 +438,15 @@ class Renderer {
398
438
. then ( compiled => {
399
439
this . MakeBundle ( compiled , filePath )
400
440
. then ( bundle => {
401
- this . internalCache . set ( filePath , { bundle : bundle , style : compiled . style } ) ;
441
+ this . internalCache . set ( filePath , { bundle : bundle , style : compiled . style , data : bundle . data } ) ;
402
442
//Insert Data
403
443
if ( bundle . data && typeof bundle . data === "function" ) {
404
444
bundle . data = this . FixData ( bundle . data ( ) , data ) ;
405
445
}
446
+ //Insert propsData
447
+ if ( vueOptions . propsData && ( bundle . propsData || bundle . props ) ) {
448
+ bundle . propsData = this . FixPropsData ( bundle . propsData || { } , vueOptions . propsData ) ;
449
+ }
406
450
407
451
//Create Vue Class
408
452
// @ts -ignore
@@ -479,12 +523,8 @@ class Renderer {
479
523
return new Promise ( ( resolve , reject ) => {
480
524
this . FindFile ( vueFile )
481
525
. then ( filePath => {
482
- this . MakeVueClass ( filePath , data )
526
+ this . MakeVueClass ( filePath , data , vueOptions )
483
527
. then ( vueClass => {
484
- const rendererOptions = {
485
- cache : this . lruCache ,
486
- } ;
487
- this . renderer = vueServerRenderer . createRenderer ( rendererOptions ) ;
488
528
const mergedHeadObject = Utils . MergeHead ( vueOptions . head , this . head ) ;
489
529
const template = Object . assign ( { } , this . template , vueOptions . template ) ;
490
530
//Init Renderer
@@ -511,19 +551,15 @@ class Renderer {
511
551
* renderToStream returns a stream from res.renderVue to the client
512
552
* @param {string } vueFile - full path to .vue component
513
553
* @param {Object } data - data to be inserted when generating vue class
514
- * @param {VueOptionsType } vueOptions - vue options to be used when generating head
554
+ * @param {( VueOptionsType|object) } vueOptions - vue options to be used when generating head
515
555
* @return {Promise<NodeJS.ReadableStream> }
516
556
*/
517
557
RenderToStream ( vueFile , data , vueOptions ) {
518
558
return new Promise ( ( resolve , reject ) => {
519
559
this . FindFile ( vueFile )
520
560
. then ( filePath => {
521
- this . MakeVueClass ( filePath , data )
561
+ this . MakeVueClass ( filePath , data , vueOptions )
522
562
. then ( vueClass => {
523
- const rendererOptions = {
524
- cache : this . lruCache ,
525
- } ;
526
- this . renderer = vueServerRenderer . createRenderer ( rendererOptions ) ;
527
563
const mergedHeadObject = Utils . MergeHead ( vueOptions . head , this . head ) ;
528
564
const headString = Utils . BuildHead ( mergedHeadObject ) ;
529
565
const template = Object . assign ( { } , this . template , vueOptions . template ) ;
0 commit comments