Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ cedar build:
*SSR/RSC: falls back to legacy separate builds; adds route hooks build, route
manifest, SSR client+server builds.

Vite plugins: cell transform | entry injection | html env | node polyfills |
Vite plugins: cell transform | entry injection | html env | data-uri-to-buffer shim |
auto-imports | import-dir | js-as-jsx | merged config | api-babel-transform |
cedar-routes-auto-loader | cedar-universal-deploy | cedar-wait-for-api-server
*SSR/RSC: adds RSC transforms
Expand Down
2 changes: 0 additions & 2 deletions packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@
"acorn": "8.16.0",
"acorn-loose": "8.5.2",
"ansis": "4.2.0",
"buffer": "6.0.3",
"busboy": "^1.6.0",
"cookie": "1.1.1",
"dotenv-defaults": "5.0.2",
Expand All @@ -99,7 +98,6 @@
"rou3": "^0.8.1",
"vite": "7.3.5",
"vite-plugin-cjs-interop": "2.4.4",
"vite-plugin-node-polyfills": "0.26.0",
"ws": "8.20.0",
"yargs-parser": "21.1.1"
},
Expand Down
20 changes: 4 additions & 16 deletions packages/vite/src/devFeServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,22 +278,10 @@ async function createServer() {
'busboy',
'cookie',
],
Comment thread
Tobbe marked this conversation as resolved.
// Without excluding `util` we get "TypeError: util.TextEncoder is not
// a constructor" in react-server-dom-webpack.server because it'll try
// to use Browserify's `util` instead of Node's. And Browserify's
// polyfill is missing TextEncoder+TextDecoder. The reason it's using
// the Browserify polyfill is because we have
// `vite-plugin-node-polyfills` as a dependency, and that'll add
// Browserify's `node-util` to `node_modules`, so when Vite goes to
// resolve `import { TextEncoder } from 'util` it'll find the one in
// `node_modules` instead of Node's internal version.
// We only see this in dev, and not in prod. I'm not entirely sure why
// but I have two guesses: 1. When RSC is enabled we don't actually use
// `vite-plugin-node-polyfill`, so some kind of tree shaking is
// happening, which prevents the issue from occurring. 2. In prod we
// only use Node's dependency resolution. Vite is not involved. And
// that difference in resolution is what prevents the issue from
// occurring.
// Ensure `util` resolves to Node's built-in module and not to
// Browserify's `node-util` polyfill (which lacks TextEncoder).
// The polyfill may be hoisted into node_modules by optional
// dependencies like `@cedarjs/storybook`.
exclude: ['util'],
Comment thread
Tobbe marked this conversation as resolved.
},
},
Expand Down
6 changes: 3 additions & 3 deletions packages/vite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import {
} from '@cedarjs/testing/web/vitest'

import { cedarCellTransform } from './plugins/vite-plugin-cedar-cell.js'
import { cedarDataUriShim } from './plugins/vite-plugin-cedar-data-uri-shim.js'
import { cedarEntryInjectionPlugin } from './plugins/vite-plugin-cedar-entry-injection.js'
import { cedarHtmlEnvPlugin } from './plugins/vite-plugin-cedar-html-env.js'
import { cedarNodePolyfills } from './plugins/vite-plugin-cedar-node-polyfills.js'
import { cedarRemoveDevFatalErrorPage } from './plugins/vite-plugin-cedar-remove-dev-fatal-error-page.js'
import { cedarRemoveFromBundle } from './plugins/vite-plugin-cedar-remove-from-bundle.js'
import { cedarRoutesAutoLoaderPlugin } from './plugins/vite-plugin-cedar-routes-auto-loader.js'
Expand All @@ -28,7 +28,7 @@ export { cedarCellTransform } from './plugins/vite-plugin-cedar-cell.js'
export { cedarEntryInjectionPlugin } from './plugins/vite-plugin-cedar-entry-injection.js'
export { cedarHtmlEnvPlugin } from './plugins/vite-plugin-cedar-html-env.js'
export { cedarImportDirPlugin } from './plugins/vite-plugin-cedar-import-dir.js'
export { cedarNodePolyfills } from './plugins/vite-plugin-cedar-node-polyfills.js'
export { cedarDataUriShim } from './plugins/vite-plugin-cedar-data-uri-shim.js'
export { cedarRemoveDevFatalErrorPage } from './plugins/vite-plugin-cedar-remove-dev-fatal-error-page.js'
export { cedarRoutesAutoLoaderPlugin } from './plugins/vite-plugin-cedar-routes-auto-loader.js'
export { cedarRemoveFromBundle } from './plugins/vite-plugin-cedar-remove-from-bundle.js'
Expand Down Expand Up @@ -65,7 +65,7 @@ export function cedar({ mode }: PluginOptions = {}): PluginOption[] {
mode === 'test' && createAuthImportTransformPlugin(),
mode === 'test' && autoImportsPlugin(),
cedarWaitForApiServer(),
cedarNodePolyfills(),
cedarDataUriShim(),
cedarHtmlEnvPlugin(),
cedarEntryInjectionPlugin(),
cedarMergedConfig(),
Expand Down
61 changes: 61 additions & 0 deletions packages/vite/src/plugins/vite-plugin-cedar-data-uri-shim.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { Plugin } from 'vite'

import { getConfig } from '@cedarjs/project-config'

function dataUriToBuffer(uri: string) {
const match = uri.match(/^data:(.*?)(;(.*?))?(,(.*))$/)
if (!match) {
throw new Error('Invalid data URI')
}

const mediaType = match[1] || 'text/plain'
const params = match[3] || ''
const data = match[5]

const [type] = mediaType.split(';')
const typeFull = params ? mediaType + ';' + params : mediaType

const lowerParams = params.toLowerCase()
const isBase64 = lowerParams.includes('base64')

const charset = lowerParams.startsWith('charset=') ? lowerParams.slice(8) : ''

const bytes = isBase64
? Uint8Array.from(atob(data), (c) => c.charCodeAt(0))
: new TextEncoder().encode(decodeURIComponent(data))

const decoder = new TextDecoder()
bytes.toString = () => decoder.decode(bytes)

return Object.assign(bytes, { type, typeFull, charset })
}

export function cedarDataUriShim(): Plugin | undefined {
// `stacktracey` pulls in `get-source`, which uses an old version of
// `data-uri-to-buffer` that returns a `Buffer`. Since `data-uri-to-buffer`
// is only used for inline source map parsing in the dev error page, we
// replace it with a tiny shim that returns a `Uint8Array` instead.
//
// This avoids needing a full Buffer polyfill.

if (getConfig().experimental?.rsc?.enabled) {
return undefined
}

return {
name: 'cedar-data-uri-shim',
apply: 'serve',
resolveId(id) {
if (id === 'data-uri-to-buffer') {
return '\0cedar-data-uri-to-buffer'
}
return undefined
},
load(id) {
if (id === '\0cedar-data-uri-to-buffer') {
return 'export default ' + dataUriToBuffer.toString()
}
return undefined
},
}
}
23 changes: 0 additions & 23 deletions packages/vite/src/plugins/vite-plugin-cedar-node-polyfills.ts

This file was deleted.

4 changes: 1 addition & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3772,7 +3772,6 @@ __metadata:
acorn: "npm:8.16.0"
acorn-loose: "npm:8.5.2"
ansis: "npm:4.2.0"
buffer: "npm:6.0.3"
busboy: "npm:^1.6.0"
concurrently: "npm:9.2.1"
cookie: "npm:1.1.1"
Expand All @@ -3797,7 +3796,6 @@ __metadata:
typescript: "npm:5.9.3"
vite: "npm:7.3.5"
vite-plugin-cjs-interop: "npm:2.4.4"
vite-plugin-node-polyfills: "npm:0.26.0"
vitest: "npm:3.2.6"
ws: "npm:8.20.0"
yargs-parser: "npm:21.1.1"
Expand Down Expand Up @@ -13721,7 +13719,7 @@ __metadata:
languageName: node
linkType: hard

"buffer@npm:6.0.3, buffer@npm:^6.0.3":
"buffer@npm:^6.0.3":
version: 6.0.3
resolution: "buffer@npm:6.0.3"
dependencies:
Expand Down
Loading