Skip to content

Commit

Permalink
chore(refactor): vite - extract default vite config (#10110)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobbe authored Mar 4, 2024
1 parent e126c75 commit 4c8151e
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 141 deletions.
142 changes: 3 additions & 139 deletions packages/vite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import fs from 'fs'
import path from 'path'

import react from '@vitejs/plugin-react'
import type { InputOption } from 'rollup'
import type { ConfigEnv, UserConfig, PluginOption } from 'vite'
import type { PluginOption } from 'vite'
import { normalizePath } from 'vite'

import { getWebSideDefaultBabelConfig } from '@redwoodjs/babel-config'
import { getConfig, getPaths } from '@redwoodjs/project-config'

import { getEnvVarDefinitions } from './envVarDefinitions'
import { getDefaultViteConfig } from './lib/getDefaultViteConfig'
import handleJsAsJsx from './plugins/vite-plugin-jsx-loader'
import removeFromBundle from './plugins/vite-plugin-remove-from-bundle'
import swapApolloProvider from './plugins/vite-plugin-swap-apollo-provider'
Expand Down Expand Up @@ -126,114 +125,7 @@ export default function redwoodPluginVite(): PluginOption[] {
},
// ---------- End Bundle injection ----------

config: (options: UserConfig, env: ConfigEnv): UserConfig => {
let apiHost = process.env.REDWOOD_API_HOST
apiHost ??= rwConfig.api.host
apiHost ??= process.env.NODE_ENV === 'production' ? '0.0.0.0' : '[::]'

let apiPort
if (process.env.REDWOOD_API_PORT) {
apiPort = parseInt(process.env.REDWOOD_API_PORT)
} else {
apiPort = rwConfig.api.port
}

return {
root: rwPaths.web.src,
// Disabling for now, let babel handle this for consistency
// resolve: {
// alias: [
// {
// find: 'src',
// replacement: redwoodPaths.web.src,
// },
// ],
// },
envPrefix: 'REDWOOD_ENV_',
publicDir: path.join(rwPaths.web.base, 'public'),
define: getEnvVarDefinitions(),
css: {
// @NOTE config path is relative to where vite.config.js is if you use relative path
// postcss: './config/',
postcss: rwPaths.web.config,
},
server: {
open: rwConfig.browser.open,
port: rwConfig.web.port,
host: true, // Listen to all hosts
proxy: {
[rwConfig.web.apiUrl]: {
target: `http://${apiHost}:${apiPort}`,
changeOrigin: false,
// Remove the `.redwood/functions` part, but leave the `/graphql`
rewrite: (path) => path.replace(rwConfig.web.apiUrl, ''),
configure: (proxy) => {
// @MARK: this is a hack to prevent showing confusing proxy errors on startup
// because Vite launches so much faster than the API server.
let waitingForApiServer = true

// Wait for 2.5s, then restore regular proxy error logging
setTimeout(() => {
waitingForApiServer = false
}, 2500)

proxy.on('error', (err, _req, res) => {
if (
waitingForApiServer &&
err.message.includes('ECONNREFUSED')
) {
err.stack =
'⌛ API Server launching, please refresh your page...'
}
const msg = {
errors: [
{
message:
'The RedwoodJS API server is not available or is currently reloading. Please refresh.',
},
],
}

res.writeHead(203, {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
})
res.write(JSON.stringify(msg))
res.end()
})
},
},
},
},
build: {
outDir: options.build?.outDir || rwPaths.web.dist,
emptyOutDir: true,
manifest: !env.ssrBuild ? 'client-build-manifest.json' : undefined,
sourcemap: !env.ssrBuild && rwConfig.web.sourceMap, // Note that this can be boolean or 'inline'
rollupOptions: {
input: getRollupInput(!!env.ssrBuild),
},
},
legacy: {
buildSsrCjsExternalHeuristics: rwConfig.experimental?.rsc?.enabled
? false
: env.ssrBuild,
},
optimizeDeps: {
esbuildOptions: {
// @MARK this is because JS projects in Redwood don't have .jsx extensions
loader: {
'.js': 'jsx',
},
// Node.js global to browser globalThis
// @MARK unsure why we need this, but required for DevFatalErrorPage atleast
define: {
global: 'globalThis',
},
},
},
}
},
config: getDefaultViteConfig(rwConfig, rwPaths),
},
// We can remove when streaming is stable
rwConfig.experimental.streamingSsr.enabled && swapApolloProvider(),
Expand All @@ -259,31 +151,3 @@ export default function redwoodPluginVite(): PluginOption[] {
}),
]
}

/**
* This function configures how vite (actually Rollup) will bundle.
*
* By default, the entry point is the index.html file - even if you don't specify it in RollupOptions
*
* With streaming SSR, out entrypoint is different - either entry.client.tsx or entry.server.tsx
* and the html file is not used at all, because it is defined in Document.tsx
*
* @param ssr {boolean} Whether to return the SSR inputs or not
* @returns Rollup input Options
*/
function getRollupInput(ssr: boolean): InputOption | undefined {
const rwConfig = getConfig()
const rwPaths = getPaths()

// @NOTE once streaming ssr is out of experimental, this will become the default
if (rwConfig.experimental.streamingSsr.enabled) {
return ssr
? {
'entry.server': rwPaths.web.entryServer as string,
Document: rwPaths.web.document, // We need the document for React's fallback
}
: (rwPaths.web.entryClient as string)
}

return rwPaths.web.html
}
File renamed without changes.
149 changes: 149 additions & 0 deletions packages/vite/src/lib/getDefaultViteConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import path from 'node:path'

import type { InputOption } from 'rollup'
import type { ConfigEnv, UserConfig } from 'vite'

import type { Config, Paths } from '@redwoodjs/project-config'
import { getConfig, getPaths } from '@redwoodjs/project-config'

import { getEnvVarDefinitions } from './envVarDefinitions'

export function getDefaultViteConfig(rwConfig: Config, rwPaths: Paths) {
return (options: UserConfig, env: ConfigEnv): UserConfig => {
let apiHost = process.env.REDWOOD_API_HOST
apiHost ??= rwConfig.api.host
apiHost ??= process.env.NODE_ENV === 'production' ? '0.0.0.0' : '[::]'

let apiPort
if (process.env.REDWOOD_API_PORT) {
apiPort = parseInt(process.env.REDWOOD_API_PORT)
} else {
apiPort = rwConfig.api.port
}

return {
root: rwPaths.web.src,
// Disabling for now, let babel handle this for consistency
// resolve: {
// alias: [
// {
// find: 'src',
// replacement: redwoodPaths.web.src,
// },
// ],
// },
envPrefix: 'REDWOOD_ENV_',
publicDir: path.join(rwPaths.web.base, 'public'),
define: getEnvVarDefinitions(),
css: {
// @NOTE config path is relative to where vite.config.js is if you use relative path
// postcss: './config/',
postcss: rwPaths.web.config,
},
server: {
open: rwConfig.browser.open,
port: rwConfig.web.port,
host: true, // Listen to all hosts
proxy: {
[rwConfig.web.apiUrl]: {
target: `http://${apiHost}:${apiPort}`,
changeOrigin: false,
// Remove the `.redwood/functions` part, but leave the `/graphql`
rewrite: (path) => path.replace(rwConfig.web.apiUrl, ''),
configure: (proxy) => {
// @MARK: this is a hack to prevent showing confusing proxy errors on startup
// because Vite launches so much faster than the API server.
let waitingForApiServer = true

// Wait for 2.5s, then restore regular proxy error logging
setTimeout(() => {
waitingForApiServer = false
}, 2500)

proxy.on('error', (err, _req, res) => {
if (
waitingForApiServer &&
err.message.includes('ECONNREFUSED')
) {
err.stack =
'⌛ API Server launching, please refresh your page...'
}
const msg = {
errors: [
{
message:
'The RedwoodJS API server is not available or is currently reloading. Please refresh.',
},
],
}

res.writeHead(203, {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
})
res.write(JSON.stringify(msg))
res.end()
})
},
},
},
},
build: {
outDir: options.build?.outDir || rwPaths.web.dist,
emptyOutDir: true,
manifest: !env.ssrBuild ? 'client-build-manifest.json' : undefined,
sourcemap: !env.ssrBuild && rwConfig.web.sourceMap, // Note that this can be boolean or 'inline'
rollupOptions: {
input: getRollupInput(!!env.ssrBuild),
},
},
legacy: {
buildSsrCjsExternalHeuristics: rwConfig.experimental?.rsc?.enabled
? false
: env.ssrBuild,
},
optimizeDeps: {
esbuildOptions: {
// @MARK this is because JS projects in Redwood don't have .jsx extensions
loader: {
'.js': 'jsx',
},
// Node.js global to browser globalThis
// @MARK unsure why we need this, but required for DevFatalErrorPage
// at least
define: {
global: 'globalThis',
},
},
},
}
}
}

/**
* This function configures how vite (actually Rollup) will bundle.
*
* By default, the entry point is the index.html file - even if you don't specify it in RollupOptions
*
* With streaming SSR, out entrypoint is different - either entry.client.tsx or entry.server.tsx
* and the html file is not used at all, because it is defined in Document.tsx
*
* @param ssr {boolean} Whether to return the SSR inputs or not
* @returns Rollup input Options
*/
function getRollupInput(ssr: boolean): InputOption | undefined {
const rwConfig = getConfig()
const rwPaths = getPaths()

// @NOTE once streaming ssr is out of experimental, this will become the default
if (rwConfig.experimental.streamingSsr.enabled) {
return ssr
? {
'entry.server': rwPaths.web.entryServer as string,
Document: rwPaths.web.document, // We need the document for React's fallback
}
: (rwPaths.web.entryClient as string)
}

return rwPaths.web.html
}
2 changes: 1 addition & 1 deletion packages/vite/src/rsc/rscBuildClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { build as viteBuild } from 'vite'
import { getWebSideDefaultBabelConfig } from '@redwoodjs/babel-config'
import { getPaths } from '@redwoodjs/project-config'

import { getEnvVarDefinitions } from '../envVarDefinitions'
import { getEnvVarDefinitions } from '../lib/envVarDefinitions'
import { onWarn } from '../lib/onWarn'
import { ensureProcessDirWeb } from '../utils'

Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/rsc/rscBuildForServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { build as viteBuild } from 'vite'
import { getWebSideDefaultBabelConfig } from '@redwoodjs/babel-config'
import { getPaths } from '@redwoodjs/project-config'

import { getEnvVarDefinitions } from '../envVarDefinitions'
import { getEnvVarDefinitions } from '../lib/envVarDefinitions'
import { onWarn } from '../lib/onWarn'

import { rscTransformPlugin } from './rscVitePlugins'
Expand Down

0 comments on commit 4c8151e

Please sign in to comment.