@@ -1398,6 +1398,8 @@ export interface ViteBuilder {
13981398}
13991399
14001400export interface BuilderOptions {
1401+ sharedConfigBuild ?: boolean
1402+ sharedPlugins ?: boolean
14011403 buildApp ?: ( builder : ViteBuilder ) => Promise < void >
14021404}
14031405
@@ -1411,6 +1413,8 @@ export function resolveBuilderOptions(
14111413 options : BuilderOptions = { } ,
14121414) : ResolvedBuilderOptions {
14131415 return {
1416+ sharedConfigBuild : options . sharedConfigBuild ?? false ,
1417+ sharedPlugins : options . sharedPlugins ?? false ,
14141418 buildApp : options . buildApp ?? defaultBuildApp ,
14151419 }
14161420}
@@ -1420,42 +1424,32 @@ export type ResolvedBuilderOptions = Required<BuilderOptions>
14201424export async function createBuilder (
14211425 inlineConfig : InlineConfig = { } ,
14221426) : Promise < ViteBuilder > {
1423- // Plugins passed to the Builder inline config needs to be created
1424- // from a factory to ensure each build has their own instances
1425- const resolveConfig = (
1426- environmentOptions ?: EnvironmentOptions ,
1427- ) : Promise < ResolvedConfig > => {
1428- const environmentInlineConfig = environmentOptions
1429- ? mergeConfig ( inlineConfig , environmentOptions )
1430- : inlineConfig
1431-
1432- // We resolve the whole config including plugins here but later on we
1433- // need to refactor resolveConfig to only resolve the environments config
1434- return resolveConfigToBuild ( environmentInlineConfig )
1435- }
1436-
1437- const defaultConfig = await resolveConfig ( )
1427+ const config = await resolveConfigToBuild ( inlineConfig )
14381428
14391429 const environments : Record < string , BuildEnvironment > = { }
14401430
14411431 const builder : ViteBuilder = {
14421432 environments,
1443- config : defaultConfig ,
1433+ config,
14441434 async buildApp ( ) {
1445- if ( defaultConfig . build . watch ) {
1435+ if ( config . build . watch ) {
14461436 throw new Error (
14471437 'Watch mode is not yet supported in viteBuilder.buildApp()' ,
14481438 )
14491439 }
1450- return defaultConfig . builder . buildApp ( builder )
1440+ return config . builder . buildApp ( builder )
14511441 } ,
14521442 async build ( environment : BuildEnvironment ) {
14531443 return buildEnvironment ( environment . config , environment )
14541444 } ,
14551445 }
14561446
1457- for ( const name of Object . keys ( defaultConfig . environments ) ) {
1458- const environmentOptions = defaultConfig . environments [ name ]
1447+ const allSharedPlugins =
1448+ config . builder . sharedPlugins ||
1449+ config . plugins . every ( ( plugin ) => plugin . sharedDuringBuild === true )
1450+
1451+ for ( const name of Object . keys ( config . environments ) ) {
1452+ const environmentOptions = config . environments [ name ]
14591453 const createEnvironment =
14601454 environmentOptions . build ?. createEnvironment ??
14611455 ( ( name : string , config : ResolvedConfig ) =>
@@ -1466,7 +1460,44 @@ export async function createBuilder(
14661460 // expects plugins to be run for the same environment once they are created
14671461 // and to process a single bundle at a time (contrary to dev mode where
14681462 // plugins are built to handle multiple environments concurrently).
1469- const environmentConfig = await resolveConfig ( environmentOptions )
1463+ const environmentConfig =
1464+ allSharedPlugins && config . builder . sharedConfigBuild
1465+ ? config
1466+ : await resolveConfigToBuild (
1467+ mergeConfig ( inlineConfig , environmentOptions ) ,
1468+ )
1469+ if ( environmentConfig !== config ) {
1470+ // Force opt-in shared plugins
1471+ const plugins = [ ...environmentConfig . plugins ]
1472+ let validPlugins = true
1473+ for ( let i = 0 ; i < plugins . length ; i ++ ) {
1474+ const environmentPlugin = plugins [ i ]
1475+ const sharedPlugin = config . plugins [ i ]
1476+ if ( environmentPlugin . sharedDuringBuild ) {
1477+ if ( environmentPlugin . name !== sharedPlugin . name ) {
1478+ validPlugins = false
1479+ break
1480+ }
1481+ plugins [ i ] = sharedPlugin
1482+ }
1483+ }
1484+ if ( validPlugins ) {
1485+ ; ( environmentConfig . plugins as Plugin [ ] ) = plugins
1486+ }
1487+ }
1488+ /*
1489+ // TODO: This is implementing by merging environmentOptions into inlineConfig before resolving
1490+ // We should be instead doing the patching as the commented code below but we need to understand
1491+ // why some tests are failing first.
1492+ //
1493+ // Until the ecosystem updates to use `environment.options.build` instead of `config.build`,
1494+ // we need to make override `config.build` for the current environment.
1495+ // We can deprecate `config.build` in ResolvedConfig and push everyone to upgrade, and later
1496+ // remove the default values that shouldn't be used at all once the config is resolved
1497+ if (!config.builder.sharedConfigBuild) {
1498+ ;(environmentConfig.build as ResolvedBuildOptions) = { ...environmentConfig.environments[name].build, lib: false }
1499+ }
1500+ */
14701501
14711502 const environment = await createEnvironment ( name , environmentConfig )
14721503 environments [ name ] = environment
0 commit comments