fix(desktop): keep react-router in one runtime chunk
This commit is contained in:
parent
e400dca96e
commit
481ccdafb7
|
|
@ -11,10 +11,12 @@
|
|||
// inherits it. It fails loud and early instead of shipping a broken bundle.
|
||||
// See issues #39484 (renderer blank page) and #41327 / #39472 (dashboard 404).
|
||||
|
||||
import { existsSync, statSync, readdirSync } from "fs"
|
||||
import { existsSync, readFileSync, statSync, readdirSync } from "fs"
|
||||
import { join, resolve } from "path"
|
||||
import { isMain } from "./utils.mjs"
|
||||
|
||||
const ROUTER_CONTEXT_ERROR = "may be used only in the context of a"
|
||||
|
||||
// Pure check — returns { ok: true } or { ok: false, error: "..." }.
|
||||
// Kept side-effect-free so it can be unit tested without spawning a process.
|
||||
export function checkDistBuilt(distDir) {
|
||||
|
|
@ -41,6 +43,17 @@ export function checkDistBuilt(distDir) {
|
|||
return { ok: false, error: `dist/assets has no built JS bundle (expected vite output under ${assetsDir})` }
|
||||
}
|
||||
|
||||
const routerContextAssets = readdirSync(assetsDir)
|
||||
.filter(name => name.endsWith(".js"))
|
||||
.filter(name => readFileSync(join(assetsDir, name), "utf8").includes(ROUTER_CONTEXT_ERROR))
|
||||
|
||||
if (routerContextAssets.length > 1) {
|
||||
return {
|
||||
ok: false,
|
||||
error: `react-router context invariant found in multiple JS assets: ${routerContextAssets.join(", ")}`
|
||||
}
|
||||
}
|
||||
|
||||
return { ok: true }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,14 @@ function makeDist(extra) {
|
|||
return { tempRoot, distDir }
|
||||
}
|
||||
|
||||
function writeRouterAsset(distDir, name) {
|
||||
fs.writeFileSync(
|
||||
path.join(distDir, 'assets', name),
|
||||
`throw new Error('may be used only in the context of a <Router>')`,
|
||||
'utf8',
|
||||
)
|
||||
}
|
||||
|
||||
test('checkDistBuilt passes when index.html + an assets JS bundle exist', () => {
|
||||
const { tempRoot, distDir } = makeDist(d => {
|
||||
fs.writeFileSync(path.join(d, 'index.html'), '<!doctype html><div id=root></div>', 'utf8')
|
||||
|
|
@ -82,3 +90,35 @@ test('checkDistBuilt fails when assets/ has no JS bundle', () => {
|
|||
fs.rmSync(tempRoot, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
test('checkDistBuilt passes when the Router context invariant is in one JS asset', () => {
|
||||
const { tempRoot, distDir } = makeDist(d => {
|
||||
fs.writeFileSync(path.join(d, 'index.html'), '<!doctype html>', 'utf8')
|
||||
fs.mkdirSync(path.join(d, 'assets'))
|
||||
writeRouterAsset(d, 'vendor-react-abc123.js')
|
||||
fs.writeFileSync(path.join(d, 'assets', 'command-def456.js'), 'console.log(1)', 'utf8')
|
||||
})
|
||||
try {
|
||||
assert.deepEqual(checkDistBuilt(distDir), { ok: true })
|
||||
} finally {
|
||||
fs.rmSync(tempRoot, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
test('checkDistBuilt fails when the Router context invariant is in multiple JS assets', () => {
|
||||
const { tempRoot, distDir } = makeDist(d => {
|
||||
fs.writeFileSync(path.join(d, 'index.html'), '<!doctype html>', 'utf8')
|
||||
fs.mkdirSync(path.join(d, 'assets'))
|
||||
writeRouterAsset(d, 'vendor-react-abc123.js')
|
||||
writeRouterAsset(d, 'command-def456.js')
|
||||
})
|
||||
try {
|
||||
const result = checkDistBuilt(distDir)
|
||||
assert.equal(result.ok, false)
|
||||
assert.match(result.error, /react-router context invariant found in multiple JS assets/)
|
||||
assert.match(result.error, /vendor-react-abc123\.js/)
|
||||
assert.match(result.error, /command-def456\.js/)
|
||||
} finally {
|
||||
fs.rmSync(tempRoot, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ export default defineConfig(({ command }) => ({
|
|||
// the heavy chunk, and the entry then statically imports 19 MB of
|
||||
// shiki just to reach react/hast utils — putting the heavy chunk
|
||||
// right back on the boot path.
|
||||
{ name: 'vendor-react', test: /node_modules[\\/](react|react-dom|scheduler)[\\/]/ },
|
||||
{ name: 'vendor-react', test: /node_modules[\\/](react|react-dom|scheduler|react-router)[\\/]/ },
|
||||
{
|
||||
name: 'vendor-md',
|
||||
test: /node_modules[\\/](property-information|hast-util-[^\\/]+|mdast-util-[^\\/]+|micromark[^\\/]*|unist-util-[^\\/]+|vfile[^\\/]*|unified|stringify-entities|space-separated-tokens|comma-separated-tokens|zwitch|html-void-elements|devlop|style-to-js|style-to-object|clsx)[\\/]/
|
||||
|
|
@ -152,7 +152,7 @@ export default defineConfig(({ command }) => ({
|
|||
'react/jsx-dev-runtime': path.resolve(__dirname, '../../node_modules/react/jsx-dev-runtime.js'),
|
||||
'react/jsx-runtime': path.resolve(__dirname, '../../node_modules/react/jsx-runtime.js')
|
||||
},
|
||||
dedupe: ['react', 'react-dom']
|
||||
dedupe: ['react', 'react-dom', 'react-router']
|
||||
},
|
||||
server: {
|
||||
host: '127.0.0.1',
|
||||
|
|
|
|||
Loading…
Reference in New Issue