vite#ViteDevServer TypeScript Examples
The following examples show how to use
vite#ViteDevServer.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: server.ts From vite-ssr with MIT License | 6 votes |
export function printServerInfo(server: ViteDevServer) {
const info = server.config.logger.info
let ssrReadyMessage = '\n -- SSR mode'
if (Object.prototype.hasOwnProperty.call(server, 'printUrls')) {
info(
chalk.cyan(`\n vite v${require('vite/package.json').version}`) +
chalk.green(` dev server running at:\n`),
{ clear: !server.config.logger.hasWarned }
)
// @ts-ignore
server.printUrls()
// @ts-ignore
if (globalThis.__ssr_start_time) {
ssrReadyMessage += chalk.cyan(
` ready in ${Math.round(
// @ts-ignore
performance.now() - globalThis.__ssr_start_time
)}ms.`
)
}
}
info(ssrReadyMessage + '\n')
}
Example #2
Source File: handleError.ts From telefunc with MIT License | 6 votes |
function handleError(err: unknown, viteDevServer: ViteDevServer | null) {
// We ensure we print a string; Cloudflare Workers doesn't seem to properly stringify `Error` objects.
const errStr = (hasProp(err, 'stack') && String(err.stack)) || String(err)
if (viteAlreadyLoggedError(err, viteDevServer)) {
return
}
viteErrorCleanup(err, viteDevServer)
console.error(errStr)
}
Example #3
Source File: handleError.ts From telefunc with MIT License | 6 votes |
function viteErrorCleanup(err: unknown, viteDevServer: ViteDevServer | null) {
if (!viteDevServer) {
return false
}
if (hasProp(err, 'stack')) {
// Apply source maps
viteDevServer.ssrFixStacktrace(err as Error)
}
}
Example #4
Source File: loadTelefuncFiles.ts From telefunc with MIT License | 6 votes |
async function loadTelefuncFiles(runContext: {
root: string | null
viteDevServer: ViteDevServer | null
isProduction: boolean
telefuncFiles: string[] | null
}): Promise<TelefuncFiles | null> {
// Handles:
// - When the user provides the telefunc file paths with `telefuncConfig.telefuncFiles`
if (runContext.telefuncFiles) {
const telefuncFilesLoaded = loadTelefuncFilesFromConfig(runContext.telefuncFiles, runContext.root)
return telefuncFilesLoaded
}
// Handles:
// - Next.js
// - Nuxt
// - Vite with `importBuild.js`
{
const telefuncFilesLoaded = loadTelefuncFilesWithInternalMechanism()
if (telefuncFilesLoaded) {
assertUsage(Object.keys(telefuncFilesLoaded).length > 0, getErrMsg('webpack'))
return telefuncFilesLoaded
}
}
// Handles:
// - Vite
{
const { telefuncFilesLoaded, viteProvider } = await loadTelefuncFilesWithVite(runContext)
if (telefuncFilesLoaded) {
assertUsage(Object.keys(telefuncFilesLoaded).length > 0, getErrMsg(`Vite [\`${viteProvider}\`]`))
return telefuncFilesLoaded
}
}
assertUsage(false, "You don't seem to be using Telefunc with a supported stack. Reach out on GitHub or Discord.")
}
Example #5
Source File: loadTelefuncFilesWithVite.ts From telefunc with MIT License | 6 votes |
async function loadTelefuncFilesWithVite(runContext: {
root: string | null
viteDevServer: ViteDevServer | null
isProduction: boolean
}) {
const { notFound, moduleExports, provider } = await loadGlobImporter(runContext)
if (notFound) {
return { telefuncFilesLoaded: null }
}
// console.log('provider', provider)
assert(isObject(moduleExports), { moduleExports, provider })
assert(hasProp(moduleExports, 'telefuncFilesGlob'), { moduleExports, provider })
const telefuncFilesGlob = moduleExports.telefuncFilesGlob as GlobFiles
const telefuncFilesLoaded = await loadGlobFiles(telefuncFilesGlob)
assert(isObjectOfObjects(telefuncFilesLoaded))
return { telefuncFilesLoaded, viteProvider: provider }
}
Example #6
Source File: handleError.ts From telefunc with MIT License | 5 votes |
function viteAlreadyLoggedError(err: unknown, viteDevServer: ViteDevServer | null) {
if (!viteDevServer) {
return false
}
return viteDevServer.config.logger.hasErrorLogged(err as Error)
}
Example #7
Source File: telefuncConfig.ts From telefunc with MIT License | 5 votes |
configSpec = {
isProduction: {
validate(val: unknown) {
assertUsage(val === true || val === false, '`telefuncConfig.isProduction` should be `true` or `false`')
},
getDefault() {
// If server environment is not a Node.js server, then we assume a (Cloudflare) worker environment
if (typeof process == 'undefined' || !hasProp(process, 'env')) return true
return process.env.NODE_ENV === 'production'
}
},
root: {
validate(val: unknown) {
assertUsage(typeof val === 'string' && isAbsolute(val), '`telefuncConfig.root` should be an absolute path')
},
getDefault() {
if (typeof process == 'undefined' || !hasProp(process, 'cwd')) return null
return process.cwd()
}
},
viteDevServer: {
validate(val: unknown) {
assertInfo(
false,
'`telefuncConfig.viteDevServer` is not needed anymore. Remove your `telefuncConfig.viteDevServer` configuration to get rid of this message. (Telefunc now automatically retrieves the Vite dev server.)'
)
assertUsage(hasProp(val, 'ssrLoadModule'), '`telefuncConfig.ssrLoadModule` should be the Vite dev server')
assertUsage(
(val as any as ViteDevServer).config.plugins.find((plugin) => plugin.name.startsWith('telefunc')),
'Telefunc Vite plugin not installed. Make sure to add Telefunc to your `vite.config.js`.'
)
assert(val === globalContext.viteDevServer, '`viteDevServer` mismatch.')
},
getDefault() {
return null
}
},
telefuncUrl: {
validate(val: unknown) {
assertUsage(
typeof val === 'string' && val.startsWith('/'),
'`telefuncConfig.telefuncUrl` should be a string that starts with `/`'
)
},
getDefault() {
return '/_telefunc'
}
},
telefuncFiles: {
validate(val: unknown) {
assertWarning(false, '`telefuncConfig.telefuncFiles` is experimental', { onlyOnce: true })
assertUsage(
Array.isArray(val) && val.every((v) => typeof v === 'string' && isAbsolute(v)),
'`telefuncConfig.telefuncFiles` should be a list of absolute paths'
)
},
getDefault() {
return null
}
},
disableEtag: {
validate(_val: unknown) {
assertWarning(false, '`telefuncConfig.disableEtag` is experimental', { onlyOnce: true })
},
getDefault() {
return false
}
},
debug: {
validate(val: unknown) {
assertUsage(typeof val === 'boolean', '`telefuncConfig.debug` should be a boolean')
},
getDefault() {
if (typeof process == 'undefined' || !hasProp(process, 'env')) return false
return !!process.env.DEBUG
}
}
}
Example #8
Source File: loadTelefuncFilesWithVite.ts From telefunc with MIT License | 5 votes |
async function loadGlobImporter(runContext: {
root: string | null
viteDevServer: ViteDevServer | null
isProduction: boolean
}) {
if (runContext.viteDevServer) {
const devPath = telefuncFilesGlobFilePath
let moduleExports: unknown
try {
moduleExports = await runContext.viteDevServer.ssrLoadModule(devPath)
} catch (err: unknown) {
runContext.viteDevServer.ssrFixStacktrace(err as Error)
throw err
}
return { moduleExports, provider: 'DEV_SERVER' as const }
}
/*
{
let moduleExports: unknown | null = null
try {
moduleExports = await import('./telefuncFilesGlob')
} catch (_) {}
if (moduleExports !== null) {
assert(!hasProp(moduleExports, 'importGlobUnset'))
return { moduleExports, provider: 'DIRECT' as const }
}
}
*/
{
const moduleExports: unknown = await import('./telefuncFilesGlobFromDist')
if (!hasProp(moduleExports, 'distLinkUnset', 'true')) {
assert(hasProp(moduleExports, 'distLinkActivated', 'boolean'))
if (moduleExports.distLinkActivated === true) {
assertProd(runContext)
return { moduleExports, provider: 'DIST_LINK' as const }
}
}
}
if (runContext.root) {
const userDist = `${runContext.root}/dist`
const prodPath = `${userDist}/server/${telefuncFilesGlobFileNameBase}.js`
const prodPathResolved = resolve(prodPath)
if (moduleExists(prodPathResolved)) {
const moduleExports: unknown = nodeRequire(prodPathResolved)
assertProd(runContext)
return { moduleExports, provider: 'NODE_JS' as const }
}
}
return { notFound: true }
}
Example #9
Source File: createPageRenderer.ts From vite-plugin-ssr with MIT License | 4 votes |
function assertArguments(
ssrEnv: {
viteDevServer?: unknown
root?: unknown
outDir?: unknown
isProduction?: unknown
baseUrl?: unknown
baseAssets?: unknown
},
args: unknown[],
): asserts ssrEnv is SsrEnv {
const { viteDevServer, root, outDir, isProduction, baseUrl, baseAssets } = ssrEnv
assertUsage(
root === undefined || typeof root === 'string',
'`createPageRenderer({ root })`: argument `root` should be a string.',
)
assertUsage(typeof outDir === 'string', '`createPageRenderer({ outDir })`: argument `outDir` should be a string.')
assertUsage(typeof baseUrl === 'string', '`createPageRenderer({ base })`: argument `base` should be a string.')
assertUsage(
baseAssets === null || typeof baseAssets === 'string',
'`createPageRenderer({ baseAssets })`: argument `baseAssets` should be a string.',
)
assertUsageBaseUrl(baseUrl, '`createPageRenderer({ base })`: ')
assertUsage(
isProduction === true || isProduction === false || isProduction === undefined,
'`createPageRenderer({ isProduction })`: argument `isProduction` should be `true`, `false`, or `undefined`.',
)
if (importBuildWasLoaded()) {
assertUsage(
isProduction,
'`createPageRenderer({ isProduction })`: argument `isProduction` should be `true` if `dist/server/importBuild.js` is loaded. (You should load `dist/server/importBuild.js` only in production.)',
)
assertUsage(
root === undefined,
'`createPageRenderer({ root })`: argument `root` has no effect if `dist/server/importBuild.js` is loaded. Remove the `root` argument.',
)
}
if (isProduction === true) {
assertUsage(
viteDevServer === undefined,
'`createPageRenderer({ viteDevServer, isProduction })`: if `isProduction` is `true`, then `viteDevServer` should be `undefined`.',
)
assertUsage(
root || importBuildWasLoaded(),
"`createPageRenderer({ root })`: argument `root` is missing. (Alternatively, if `root` doesn't exist because you are bundling your server code into a single file, then load `dist/server/importBuild.js`.)",
)
} else {
assertUsage(root, '`createPageRenderer({ root })`: argument `root` is missing.')
assertUsage(
!!viteDevServer,
'`createPageRenderer({ viteDevServer, isProduction })`: if `isProduction` is not `true`, then `viteDevServer` cannot be `undefined`.',
)
const wrongViteDevServerValueError =
'`createPageRenderer({ viteDevServer, isProduction })`: if `isProduction` is not `true`, then `viteDevServer` should be `viteDevServer = await vite.createServer(/*...*/)`.'
assertUsage(
hasProp(viteDevServer, 'config') &&
hasProp(viteDevServer.config, 'root') &&
typeof viteDevServer.config.root === 'string',
wrongViteDevServerValueError,
)
{
const rootVite = resolve(viteDevServer.config.root)
const rootResolved = resolve(root)
assertUsage(
rootVite === rootResolved,
'`createPageRenderer({ viteDevServer, root })`: wrong `root` value, make sure it matches `viteDevServer.config.root`. ' +
`The \`root\` you provided resolves to \`'${rootResolved}'\` while \`viteDevServer.config.root\` resolves to \`${rootVite}\`.`,
)
}
assertUsage(
hasProp(viteDevServer, 'config', 'object') && hasProp(viteDevServer.config, 'plugins', 'array'),
wrongViteDevServerValueError,
)
assertUsage(
(viteDevServer as any as ViteDevServer).config.plugins.find((plugin) =>
plugin.name.startsWith('vite-plugin-ssr'),
),
"`vite-plugin-ssr`'s Vite plugin is not installed. Make sure to add it to your `vite.config.js`.",
)
}
assertUsage(args.length === 1, '`createPageRenderer()`: all arguments should be passed as a single argument object.')
assert(typeof args[0] === 'object' && args[0] !== null)
Object.keys(args[0]).forEach((argName) => {
assertUsage(
['viteDevServer', 'root', 'outDir', 'isProduction', 'base', 'baseAssets'].includes(argName),
'`createPageRenderer()`: Unknown argument `' + argName + '`.',
)
})
}
Example #10
Source File: vite.ts From farrow with MIT License | 4 votes |
vite = (options?: FarrowViteOptions): ViteRouterPipeline => {
const router = Router()
const config = {
...options,
}
let viteDevServers: ViteDevServer[] = []
router.useLazy(async () => {
const viteServer = await createViteServer({
server: {
...config.server,
middlewareMode: true,
},
...config,
})
const getHtmlPath = async (url: string): Promise<string> => {
const pathname = url.split('?')[0]
/**
* pathname.slice(1) is to remove the first '/'
* /dir/file.html => dir/file.html
* path.join('/root', 'dir/file.html') => /root/dir/file.html
*/
const filename = path.join(viteServer.config.root, pathname.slice(1))
if (filename.endsWith('.html')) {
return filename
}
const maybeHtmlPath = `${filename}/index.html`
try {
await fs.access(maybeHtmlPath, constants.R_OK)
return `${filename}/index.html`
} catch (error) {
// if subfolder has no index.html found, use the root folder's instead
return `${viteServer.config.root}/index.html`
}
}
const handler: CustomBodyHandler = ({ req, res }) => {
viteServer.middlewares(req, res, async () => {
try {
const url = req.url ?? '/'
const htmlPath = await getHtmlPath(url)
const fileContent = await fs.readFile(htmlPath, 'utf-8')
const html = await viteServer.transformIndexHtml(url, fileContent)
res.statusCode = 200
res.setHeader('Content-Type', 'text/html')
if (options?.onBeforeSendHtml) {
res.end(await options.onBeforeSendHtml(html))
} else {
res.end(html)
}
} catch (error: any) {
if (!res.headersSent) {
res.setHeader('Content-Type', 'text/plain')
}
const message = process.env.NODE_ENV === 'production' ? error.message : error.stack ?? error.message
res.statusCode = 500
res.end(message ?? '')
}
})
}
viteDevServers.push(viteServer)
return () => {
return Response.custom(handler)
}
})
return {
...router,
async close() {
const servers = [...viteDevServers]
viteDevServers = []
await Promise.all(servers.map((server) => server.close()))
},
}
}
Example #11
Source File: server.ts From vite-ssr with MIT License | 4 votes |
createSSRDevHandler = (
server: ViteDevServer,
options: SsrOptions = {}
) => {
options = {
...server.config.inlineConfig, // CLI flags
...options,
}
const pluginOptions = getPluginOptions(server.config)
const resolve = (p: string) => path.resolve(server.config.root, p)
async function getIndexTemplate(url: string) {
// Template should be fresh in every request
const indexHtml = await fs.readFile(
pluginOptions.input || resolve('index.html'),
'utf-8'
)
return await server.transformIndexHtml(url, indexHtml)
}
function writeHead(response: ServerResponse, params: WriteResponse = {}) {
if (params.status) {
response.statusCode = params.status
}
if (params.statusText) {
response.statusMessage = params.statusText
}
if (params.headers) {
for (const [key, value] of Object.entries(params.headers)) {
response.setHeader(key, value)
}
}
}
const handleSsrRequest: NextHandleFunction = async (
request,
response,
next
) => {
if (request.method !== 'GET' || request.originalUrl === '/favicon.ico') {
return next()
}
let template: string
try {
template = await getIndexTemplate(request.originalUrl as string)
} catch (error) {
server.ssrFixStacktrace(error as Error)
return next(error)
}
try {
const entryPoint =
options.ssr || (await getEntryPoint(server.config, template))
let resolvedEntryPoint = await server.ssrLoadModule(resolve(entryPoint))
resolvedEntryPoint = resolvedEntryPoint.default || resolvedEntryPoint
const render = resolvedEntryPoint.render || resolvedEntryPoint
const protocol =
// @ts-ignore
request.protocol ||
(request.headers.referer || '').split(':')[0] ||
'http'
const url = protocol + '://' + request.headers.host + request.originalUrl
// This context might contain initialState provided by other plugins
const context =
(options.getRenderContext &&
(await options.getRenderContext({
url,
request,
response,
resolvedEntryPoint,
}))) ||
{}
// This is used by Vitedge
writeHead(response, context)
if (isRedirect(context)) {
return response.end()
}
const result = await render(url, {
request,
response,
template,
...context,
})
writeHead(response, result)
if (isRedirect(result)) {
return response.end()
}
response.setHeader('Content-Type', 'text/html')
response.end(result.html)
} catch (error) {
// Send back template HTML to inject ViteErrorOverlay
response.setHeader('Content-Type', 'text/html')
response.end(template)
// Wait until browser injects ViteErrorOverlay
// custom element from the previous template
setTimeout(() => next(error), 250)
server.ssrFixStacktrace(error as Error)
}
}
return handleSsrRequest
}
Example #12
Source File: index.ts From vanilla-extract with MIT License | 4 votes |
export function vanillaExtractPlugin({ identifiers }: Options = {}): Plugin {
let config: ResolvedConfig;
let server: ViteDevServer;
let postCssConfig: PostCSSConfigResult | null;
const cssMap = new Map<string, string>();
let virtualExt: string;
let packageName: string;
return {
name: 'vanilla-extract',
enforce: 'pre',
configureServer(_server) {
server = _server;
},
config(_userConfig, env) {
const include =
env.command === 'serve' ? ['@vanilla-extract/css/injectStyles'] : [];
return {
optimizeDeps: { include },
ssr: {
external: [
'@vanilla-extract/css',
'@vanilla-extract/css/fileScope',
'@vanilla-extract/css/adapter',
],
},
};
},
async configResolved(resolvedConfig) {
config = resolvedConfig;
packageName = getPackageInfo(config.root).name;
if (config.command === 'serve') {
postCssConfig = await resolvePostcssConfig(config);
}
virtualExt = `.vanilla.${config.command === 'serve' ? 'js' : 'css'}`;
},
resolveId(id) {
if (!id.endsWith(virtualExt)) {
return;
}
const normalizedId = id.startsWith('/') ? id.slice(1) : id;
if (cssMap.has(normalizedId)) {
return normalizePath(path.join(config.root, normalizedId));
}
},
load(id) {
if (!id.endsWith(virtualExt)) {
return;
}
const cssFileId = id.slice(config.root.length + 1);
const css = cssMap.get(cssFileId);
if (typeof css !== 'string') {
return;
}
if (!server) {
return css;
}
return outdent`
import { injectStyles } from '@vanilla-extract/css/injectStyles';
const inject = (css) => injectStyles({
fileScope: ${JSON.stringify({ filePath: cssFileId })},
css
});
inject(${JSON.stringify(css)});
import.meta.hot.on('${styleUpdateEvent(cssFileId)}', (css) => {
inject(css);
});
`;
},
async transform(code, id, ssrParam) {
if (!cssFileFilter.test(id)) {
return null;
}
let ssr: boolean | undefined;
if (typeof ssrParam === 'boolean') {
ssr = ssrParam;
} else {
ssr = ssrParam?.ssr;
}
const index = id.indexOf('?');
const validId = index === -1 ? id : id.substring(0, index);
if (ssr) {
return addFileScope({
source: code,
filePath: normalizePath(validId),
rootPath: config.root,
packageName,
});
}
const { source, watchFiles } = await compile({
filePath: validId,
cwd: config.root,
});
for (const file of watchFiles) {
// In start mode, we need to prevent the file from rewatching itself.
// If it's a `build --watch`, it needs to watch everything.
if (config.command === 'build' || file !== id) {
this.addWatchFile(file);
}
}
const output = await processVanillaFile({
source,
filePath: validId,
identOption:
identifiers ?? (config.mode === 'production' ? 'short' : 'debug'),
serializeVirtualCssPath: async ({ fileScope, source }) => {
const id = `${fileScope.filePath}${virtualExt}`;
let cssSource = source;
if (postCssConfig) {
const postCssResult = await (await import('postcss'))
.default(postCssConfig.plugins)
.process(source, {
...postCssConfig.options,
from: undefined,
map: false,
});
cssSource = postCssResult.css;
}
if (server && cssMap.has(id) && cssMap.get(id) !== source) {
const { moduleGraph } = server;
const moduleId = normalizePath(path.join(config.root, id));
const module = moduleGraph.getModuleById(moduleId);
if (module) {
moduleGraph.invalidateModule(module);
}
server.ws.send({
type: 'custom',
event: styleUpdateEvent(id),
data: cssSource,
});
}
cssMap.set(id, cssSource);
return `import "${id}";`;
},
});
return {
code: output,
map: { mappings: '' },
};
},
};
}