1
1
import { isString } from '@vuepress/shared'
2
+ import { path } from '@vuepress/utils'
2
3
import type { App , Page } from '../types/index.js'
3
4
4
5
const TEMPLATE_WRAPPER_TAG_OPEN = '<div>'
@@ -10,6 +11,13 @@ const SCRIPT_TAG_CLOSE = '</script>'
10
11
const SCRIPT_TAG_OPEN_LANG_TS_REGEX = / < \s * s c r i p t [ ^ > ] * \b l a n g = [ ' " ] t s [ ' " ] [ ^ > ] * /
11
12
const SCRIPT_TAG_OPEN_LANG_TS = '<script lang="ts">'
12
13
14
+ const SCRIPT_DEFAULT_EXPORT_REGEX = / ( (?: ^ | \n | ; ) \s * ) e x p o r t ( \s * ) d e f a u l t /
15
+ const SCRIPT_DEFAULT_NAMED_EXPORT_REGEX =
16
+ / ( (?: ^ | \n | ; ) \s * ) e x p o r t ( .+ ) a s ( \s * ) d e f a u l t /
17
+
18
+ const SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE_OUTLET = '__SCRIPT_DEFAULT_EXPORT__'
19
+ const SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE = `export default { name: ${ SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE_OUTLET } }`
20
+
13
21
const PAGE_DATA_CODE_VAR_NAME = '_pageData'
14
22
const PAGE_DATA_CODE_TEMPLATE_OUTLET = '__PAGE_DATA__'
15
23
const PAGE_DATA_CODE_TEMPLATE = `export const ${ PAGE_DATA_CODE_VAR_NAME } = JSON.parse(${ PAGE_DATA_CODE_TEMPLATE_OUTLET } )`
@@ -27,37 +35,65 @@ if (import.meta.hot) {
27
35
}
28
36
`
29
37
30
- /**
31
- * Util to resolve the page data code
32
- */
33
- const resolvePageDataCode = ( data : Page [ 'data' ] ) : string =>
34
- PAGE_DATA_CODE_TEMPLATE . replace (
35
- PAGE_DATA_CODE_TEMPLATE_OUTLET ,
36
- JSON . stringify ( JSON . stringify ( data ) ) ,
37
- )
38
-
39
38
/**
40
39
* Util to resolve the open tag of script block
41
40
*/
42
- const resolveScriptTagOpen = ( sfcBlocks : Page [ 'sfcBlocks' ] ) : string => {
41
+ const resolveScriptTagOpen = ( page : Page ) : string => {
43
42
// use existing script open tag
44
- if ( sfcBlocks . script ?. tagOpen ) {
45
- return sfcBlocks . script . tagOpen
43
+ if ( page . sfcBlocks . script ?. tagOpen ) {
44
+ return page . sfcBlocks . script . tagOpen
46
45
}
47
46
// if the setup script block is using typescript, we should use the same language for script block
48
- const isUsingTs = sfcBlocks . scriptSetup ?. tagOpen . match (
47
+ const isUsingTs = page . sfcBlocks . scriptSetup ?. tagOpen . match (
49
48
SCRIPT_TAG_OPEN_LANG_TS_REGEX ,
50
49
)
51
50
return isUsingTs ? SCRIPT_TAG_OPEN_LANG_TS : SCRIPT_TAG_OPEN
52
51
}
53
52
53
+ /**
54
+ * Util to resolve the default export code
55
+ */
56
+ const resolveDefaultExportCode = ( page : Page ) : string =>
57
+ SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE . replace (
58
+ SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE_OUTLET ,
59
+ JSON . stringify ( path . basename ( page . chunkFilePath ) ) ,
60
+ )
61
+
62
+ /**
63
+ * Util to resolve the page data code
64
+ */
65
+ const resolvePageDataCode = ( page : Page ) : string =>
66
+ PAGE_DATA_CODE_TEMPLATE . replace (
67
+ PAGE_DATA_CODE_TEMPLATE_OUTLET ,
68
+ JSON . stringify ( JSON . stringify ( page . data ) ) ,
69
+ )
70
+
71
+ /**
72
+ * Resolve the stripped content of script block
73
+ */
74
+ const resolveScriptContentStripped = ( app : App , page : Page ) : string => {
75
+ const rawContentStripped = page . sfcBlocks . script ?. contentStripped
76
+ const hasDefaultExport = rawContentStripped
77
+ ? SCRIPT_DEFAULT_EXPORT_REGEX . test ( rawContentStripped ) ||
78
+ SCRIPT_DEFAULT_NAMED_EXPORT_REGEX . test ( rawContentStripped )
79
+ : false
80
+ return [
81
+ rawContentStripped ,
82
+ resolvePageDataCode ( page ) , // inject page data code
83
+ ! hasDefaultExport && resolveDefaultExportCode ( page ) , // inject default export with component name
84
+ app . env . isDev && HMR_CODE , // inject HMR code in dev mode
85
+ ]
86
+ . filter ( isString )
87
+ . join ( '\n' )
88
+ }
89
+
54
90
/**
55
91
* Render page to vue component
56
92
*/
57
- export const renderPageToVue = (
58
- app : App ,
59
- { data , sfcBlocks } : Page ,
60
- ) : string => {
93
+ export const renderPageToVue = ( app : App , page : Page ) : string => {
94
+ const { sfcBlocks } = page
95
+
96
+ // get the content of template block
61
97
// #688: wrap the content of `<template>` with a `<div>` to avoid some potential issues of fragment component
62
98
const templateContent =
63
99
sfcBlocks . template &&
@@ -69,14 +105,10 @@ export const renderPageToVue = (
69
105
sfcBlocks . template . tagClose ,
70
106
] . join ( '' )
71
107
72
- // inject page data code and HMR code into the script content
73
- const scriptTagOpen = resolveScriptTagOpen ( sfcBlocks )
74
- const pageDataCode = resolvePageDataCode ( data )
108
+ // get the content of script block
75
109
const scriptContent = [
76
- scriptTagOpen ,
77
- sfcBlocks . script ?. contentStripped ,
78
- pageDataCode ,
79
- app . env . isDev && HMR_CODE ,
110
+ resolveScriptTagOpen ( page ) ,
111
+ resolveScriptContentStripped ( app , page ) ,
80
112
sfcBlocks . script ?. tagClose ?? SCRIPT_TAG_CLOSE ,
81
113
]
82
114
. filter ( isString )
0 commit comments