Skip to content

Commit

Permalink
feat: configureDevEnvironments + configureBuildEnvironments
Browse files Browse the repository at this point in the history
  • Loading branch information
patak-dev committed Mar 12, 2024
1 parent f927702 commit 88fea3b
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 20 deletions.
85 changes: 85 additions & 0 deletions packages/vite/src/node/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import { completeSystemWrapPlugin } from './plugins/completeSystemWrap'
import { mergeConfig } from './publicUtils'
import { webWorkerPostPlugin } from './plugins/worker'
import { getHookHandler } from './plugins'
import { Environment } from './environment'

export interface BuildOptions {
/**
Expand Down Expand Up @@ -468,6 +469,10 @@ export async function build(
'production',
'production',
)
return buildEnvironment(config)
}

async function buildEnvironment(config: ResolvedConfig) {
const options = config.build
const ssr = !!options.ssr
const libOptions = options.lib
Expand Down Expand Up @@ -1245,3 +1250,83 @@ function areSeparateFolders(a: string, b: string) {
!nb.startsWith(withTrailingSlash(na))
)
}

export class BuildEnvironment extends Environment {
mode = 'build' as const
config: BuildOptions
constructor(id: string, options: { type: string; config?: BuildOptions }) {
super(id, options)
this.config = options.config ?? {}
}
}

export interface ViteBuilder {
environments: Map<string, BuildEnvironment>
build(): Promise<void>
}

export async function createViteBuilder(
inlineConfig: InlineConfig = {},
): Promise<ViteBuilder> {
const config = await resolveConfig(
inlineConfig,
'build',
'production',
'production',
)

if (config.build.lib) {
throw new Error('Library mode is not supported in ViteBuilder')
}
if (config.build.watch) {
throw new Error('Watch mode is not yet supported in ViteBuilder')
}

const environments = new Map<string, BuildEnvironment>()

const browserEnvironment = new BuildEnvironment('browser', {
type: 'browser',
config: { ssr: false },
})
environments.set('browser', browserEnvironment)

if (config.build.ssr) {
const ssrEnvironment = new BuildEnvironment('ssr', { type: 'node' })
environments.set('ssr', ssrEnvironment)
}

function resolveEnvironmentBuildOptions(environment: BuildEnvironment) {
return resolveBuildOptions(
{ ...config.build, ...environment.config },
config.logger,
config.root,
)
}

const builder: ViteBuilder = {
environments,
async build() {
for (const environment of environments.values()) {
const environmentConfig = {
...config,
build: {
...config.build,
...resolveEnvironmentBuildOptions(environment),
},
}
await buildEnvironment(environmentConfig)

config.logger.info('')
}
},
}

// call configureBuildEnvironments hooks
for (const hook of config.getSortedPluginHooks(
'configureBuildEnvironments',
)) {
await hook(environments, config)
}

return builder
}
30 changes: 20 additions & 10 deletions packages/vite/src/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ interface GlobalCLIOptions {
m?: string
mode?: string
force?: boolean
all?: boolean
}

let profileSession = global.__vite_profile_session
Expand Down Expand Up @@ -263,21 +264,30 @@ cli
`[boolean] force empty outDir when it's outside of root`,
)
.option('-w, --watch', `[boolean] rebuilds when modules have changed on disk`)
.option('--all', `[boolean] build all environments`)
.action(async (root: string, options: BuildOptions & GlobalCLIOptions) => {
filterDuplicateOptions(options)
const { build } = await import('./build')
const { build, createViteBuilder } = await import('./build')
const buildOptions: BuildOptions = cleanOptions(options)

const config = {
root,
base: options.base,
mode: options.mode,
configFile: options.config,
logLevel: options.logLevel,
clearScreen: options.clearScreen,
build: buildOptions,
}

try {
await build({
root,
base: options.base,
mode: options.mode,
configFile: options.config,
logLevel: options.logLevel,
clearScreen: options.clearScreen,
build: buildOptions,
})
if (options.all) {
// Build all environments
const builder = await createViteBuilder(config)
await builder.build()
} else {
await build(config)
}
} catch (e) {
createLogger(options.logLevel).error(
colors.red(`error during build:\n${e.stack}`),
Expand Down
7 changes: 0 additions & 7 deletions packages/vite/src/node/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,3 @@ export class Environment {
this.type = options.type
}
}

export class BuildEnvironment extends Environment {
mode = 'build' as const
constructor(id: string, options: { type: string }) {
super(id, options)
}
}
31 changes: 29 additions & 2 deletions packages/vite/src/node/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import type {
} from 'rollup'
export type { PluginContext } from 'rollup'
import type { ConfigEnv, ResolvedConfig, UserConfig } from './config'
import type { ServerHook } from './server'
import type { ServerHook , ViteDevServer } from './server'
import type { IndexHtmlTransform } from './plugins/html'
import type { EnvironmentModuleNode, ModuleNode } from './server/moduleGraph'
import type { HmrContext, HotUpdateContext } from './server/hmr'
import type { PreviewServerHook } from './preview'
import type { ModuleExecutionEnvironment } from './server/environment'
import type { BuildEnvironment } from './environment'
import type { BuildEnvironment } from './build'

/**
* Vite plugins extends the Rollup plugin interface with a few extra
Expand Down Expand Up @@ -95,6 +95,33 @@ export interface Plugin<A = any> extends RollupPlugin<A> {
* are applied. Hook can be async functions and will be called in series.
*/
configureServer?: ObjectHook<ServerHook>
/**
* Configure dev environments. The hook receives a map of current environments,
* the resolved config, and the vite server instance {@link ViteDevServer}.
* By default, Vite creates a browser environment and a node environment.
* New environments can be added to the map using their id as key.
*/
configureDevEnvironments?: ObjectHook<
(
this: void,
environments: Map<string, ModuleExecutionEnvironment>,
config: ResolvedConfig,
server: ViteDevServer,
) => void | Promise<void>
>
/**
* Configure build environments. The hook receives a map of current environments,
* By default, Vite creates a browser environment and a node environment if
* build.ssr is configured.
* New environments can be added to the map using their id as key.
*/
configureBuildEnvironments?: ObjectHook<
(
this: void,
environments: Map<string, BuildEnvironment>,
config: ResolvedConfig,
) => void | Promise<void>
>
/**
* Configure the preview server. The hook receives the {@link PreviewServer}
* instance. This can also be used to store a reference to the server
Expand Down
5 changes: 5 additions & 0 deletions packages/vite/src/node/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,11 @@ export async function _createServer(
// error handler
middlewares.use(errorMiddleware(server, middlewareMode))

// call configureDevEnvironments hooks
for (const hook of config.getSortedPluginHooks('configureDevEnvironments')) {
await hook(environments, config, server)
}

// httpServer.listen can be called multiple times
// when port when using next port number
// this code is to avoid calling buildStart multiple times
Expand Down
3 changes: 2 additions & 1 deletion playground/ssr-noexternal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"dev": "node server",
"build": "vite build --ssr src/entry-server.js",
"serve": "NODE_ENV=production node server",
"debug": "node --inspect-brk server"
"debug": "node --inspect-brk server",
"build-all": "vite build --all"
},
"dependencies": {
"@vitejs/test-external-cjs": "file:./external-cjs",
Expand Down
1 change: 1 addition & 0 deletions playground/ssr-noexternal/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export default defineConfig({
rollupOptions: {
external: ['@vitejs/test-external-cjs'],
},
ssr: 'src/entry-server.js', // for 'all'
},
})

0 comments on commit 88fea3b

Please sign in to comment.