@fastify/react 1.1.5 → 1.1.6-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -4
- package/plugin/index.js +0 -4
- package/plugin/parsers.test.js +1 -1
- package/plugin/preload.js +5 -22
- package/rendering.js +1 -1
- package/routing.js +1 -0
- package/templating.js +10 -33
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastify/react",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6-rc.0",
|
|
4
4
|
"description": "The official @fastify/vite renderer for React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fastify",
|
|
@@ -67,9 +67,8 @@
|
|
|
67
67
|
"acorn": "^8.14.1",
|
|
68
68
|
"acorn-strip-function": "^1.2.0",
|
|
69
69
|
"acorn-walk": "^8.3.4",
|
|
70
|
-
"devalue": "^5.6.
|
|
70
|
+
"devalue": "^5.6.2",
|
|
71
71
|
"history": "latest",
|
|
72
|
-
"html-rewriter-wasm": "^0.4.1",
|
|
73
72
|
"minipass": "latest",
|
|
74
73
|
"mlly": "^1.7.4",
|
|
75
74
|
"react": "^19.2.3",
|
|
@@ -77,7 +76,7 @@
|
|
|
77
76
|
"react-router": "^7.12.0",
|
|
78
77
|
"valtio": "latest",
|
|
79
78
|
"youch": "^3.3.4",
|
|
80
|
-
"@fastify/vite": "^
|
|
79
|
+
"@fastify/vite": "^9.0.0-rc.0"
|
|
81
80
|
},
|
|
82
81
|
"scripts": {}
|
|
83
82
|
}
|
package/plugin/index.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { readFileSync, existsSync } from 'node:fs'
|
|
2
|
-
import { join } from 'node:path'
|
|
3
1
|
import viteFastify from '@fastify/vite/plugin'
|
|
4
2
|
import {
|
|
5
3
|
prefix,
|
|
@@ -9,8 +7,6 @@ import {
|
|
|
9
7
|
createPlaceholderExports,
|
|
10
8
|
} from './virtual.js'
|
|
11
9
|
import { closeBundle } from './preload.js'
|
|
12
|
-
import { parseStateKeys } from './parsers.js'
|
|
13
|
-
import { generateStores } from './stores.js'
|
|
14
10
|
|
|
15
11
|
export default function viteFastifyReactPlugin({ ts } = {}) {
|
|
16
12
|
const context = {
|
package/plugin/parsers.test.js
CHANGED
package/plugin/preload.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
|
|
2
2
|
import { join, isAbsolute, parse as parsePath } from 'node:path'
|
|
3
|
-
import { HTMLRewriter } from 'html-rewriter-wasm'
|
|
4
3
|
|
|
5
4
|
const imageFileRE = /\.((png)|(jpg)|(svg)|(webp)|(gif))$/
|
|
6
5
|
|
|
@@ -18,7 +17,7 @@ export async function closeBundle(resolvedBundle) {
|
|
|
18
17
|
}
|
|
19
18
|
const indexHtml = readFileSync(join(distDir, 'index.html'), 'utf8')
|
|
20
19
|
const pages = Object.fromEntries(
|
|
21
|
-
Object.entries(resolvedBundle ?? {}).filter(([
|
|
20
|
+
Object.entries(resolvedBundle ?? {}).filter(([, meta]) => {
|
|
22
21
|
if (meta.facadeModuleId?.includes('/pages/')) {
|
|
23
22
|
meta.htmlPath = meta.facadeModuleId.replace(/.*pages\/(.*)\.(j|t)sx$/, 'html/$1.html')
|
|
24
23
|
return true
|
|
@@ -44,30 +43,14 @@ export async function closeBundle(resolvedBundle) {
|
|
|
44
43
|
for (const js of jsImports) {
|
|
45
44
|
jsPreloads += ` <link rel="modulepreload" crossorigin href="${base}${js}">\n`
|
|
46
45
|
}
|
|
47
|
-
const pageHtml =
|
|
46
|
+
const pageHtml = appendHead(indexHtml, imagePreloads, cssPreloads, jsPreloads)
|
|
48
47
|
writeHtml(page, pageHtml, distDir)
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
let output = ''
|
|
56
|
-
const rewriter = new HTMLRewriter((outputChunk) => {
|
|
57
|
-
output += decoder.decode(outputChunk)
|
|
58
|
-
})
|
|
59
|
-
rewriter.on('head', {
|
|
60
|
-
element(element) {
|
|
61
|
-
element.prepend(tags.join('\n '), { html: true })
|
|
62
|
-
},
|
|
63
|
-
})
|
|
64
|
-
try {
|
|
65
|
-
await rewriter.write(encoder.encode(html))
|
|
66
|
-
await rewriter.end()
|
|
67
|
-
return output
|
|
68
|
-
} finally {
|
|
69
|
-
rewriter.free()
|
|
70
|
-
}
|
|
51
|
+
function appendHead(html, ...tags) {
|
|
52
|
+
const content = tags.join('\n ')
|
|
53
|
+
return html.replace(/<head([^>]*)>/i, `<head$1>\n ${content}`)
|
|
71
54
|
}
|
|
72
55
|
|
|
73
56
|
function writeHtml(page, pageHtml, distDir) {
|
package/rendering.js
CHANGED
|
@@ -75,7 +75,7 @@ async function createResponse(req, routes) {
|
|
|
75
75
|
export async function createHtmlFunction(source, _, config) {
|
|
76
76
|
// Creates `universal` and `serverOnly` sets of
|
|
77
77
|
// HTML `beforeElement` and `afterElement` templates
|
|
78
|
-
const templates =
|
|
78
|
+
const templates = createHtmlTemplates(source, config)
|
|
79
79
|
|
|
80
80
|
// Registered as reply.html()
|
|
81
81
|
return async function () {
|
package/routing.js
CHANGED
|
@@ -106,6 +106,7 @@ export async function createRoute({ client, errorHandler, route }, scope, config
|
|
|
106
106
|
} else {
|
|
107
107
|
const { id } = route
|
|
108
108
|
const htmlPath = id.replace('pages/', 'html/').replace(/\.(j|t)sx$/, '.html')
|
|
109
|
+
// TODO: Switch to config.viteConfig once deprecated config.vite alias is removed.
|
|
109
110
|
let distDir = config.vite.build.outDir
|
|
110
111
|
if (!isAbsolute(config.vite.build.outDir)) {
|
|
111
112
|
distDir = join(config.vite.root, distDir)
|
package/templating.js
CHANGED
|
@@ -1,51 +1,28 @@
|
|
|
1
1
|
import { createHtmlTemplateFunction } from '@fastify/vite/utils'
|
|
2
|
-
import { HTMLRewriter } from 'html-rewriter-wasm'
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
const moduleScriptPattern = /<script\s[^>]*\btype\s*=\s*["']module["'][^>]*>[\s\S]*?<\/script>/gi
|
|
4
|
+
|
|
5
|
+
export function createHtmlTemplates(source, config) {
|
|
5
6
|
const el = '<!-- element -->'
|
|
6
7
|
|
|
7
8
|
const universal = source.split(el)
|
|
8
|
-
const serverOnlyRaw =
|
|
9
|
+
const serverOnlyRaw = removeClientModule(source, config)
|
|
9
10
|
const serverOnly = serverOnlyRaw.split(el)
|
|
10
11
|
|
|
11
12
|
return {
|
|
12
13
|
// Templates for client-only and universal rendering
|
|
13
14
|
universal: {
|
|
14
|
-
beforeElement:
|
|
15
|
-
afterElement:
|
|
15
|
+
beforeElement: createHtmlTemplateFunction(universal[0]),
|
|
16
|
+
afterElement: createHtmlTemplateFunction(universal[1]),
|
|
16
17
|
},
|
|
17
18
|
// Templates for server-only rendering
|
|
18
19
|
serverOnly: {
|
|
19
|
-
beforeElement:
|
|
20
|
-
afterElement:
|
|
20
|
+
beforeElement: createHtmlTemplateFunction(serverOnly[0]),
|
|
21
|
+
afterElement: createHtmlTemplateFunction(serverOnly[1]),
|
|
21
22
|
},
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
let output = ''
|
|
29
|
-
const rewriter = new HTMLRewriter((outputChunk) => {
|
|
30
|
-
output += decoder.decode(outputChunk)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
rewriter.on('script', {
|
|
34
|
-
element(element) {
|
|
35
|
-
for (const [attr, value] of element.attributes) {
|
|
36
|
-
if (attr === 'type' && value === 'module') {
|
|
37
|
-
element.replace('')
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const encoder = new TextEncoder()
|
|
45
|
-
await rewriter.write(encoder.encode(html))
|
|
46
|
-
await rewriter.end()
|
|
47
|
-
return output
|
|
48
|
-
} finally {
|
|
49
|
-
rewriter.free()
|
|
50
|
-
}
|
|
26
|
+
function removeClientModule(html) {
|
|
27
|
+
return html.replace(moduleScriptPattern, '')
|
|
51
28
|
}
|