From b3a0d8b74db1a1d77a8875101457b79f6fe835f2 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Wed, 19 Jun 2024 12:14:35 +0800 Subject: [PATCH 1/4] feat: normalize environment config --- packages/core/src/createContext.ts | 18 +++ packages/core/src/helpers.ts | 3 + packages/core/src/initPlugins.ts | 24 +++- packages/core/src/mergeConfig.ts | 10 +- packages/core/src/provider/initConfigs.ts | 40 +++++- packages/core/src/types.ts | 3 + .../__snapshots__/environments.test.ts.snap | 122 ++++++++++++++++++ packages/core/tests/environments.test.ts | 37 ++++++ packages/shared/src/types/config/index.ts | 13 +- packages/shared/src/types/context.ts | 9 ++ packages/shared/src/types/plugin.ts | 8 +- 11 files changed, 272 insertions(+), 15 deletions(-) diff --git a/packages/core/src/createContext.ts b/packages/core/src/createContext.ts index 2a7ff6d011..19799a104e 100644 --- a/packages/core/src/createContext.ts +++ b/packages/core/src/createContext.ts @@ -1,6 +1,7 @@ import { isAbsolute, join } from 'node:path'; import type { BundlerType, + EnvironmentConfig, RsbuildContext, RsbuildTarget, } from '@rsbuild/shared'; @@ -46,6 +47,7 @@ async function createContextByConfig( entry: getEntryObject(config, 'web'), targets: config.output?.targets || [], version: RSBUILD_VERSION, + environments: [], rootPath, distPath, cachePath, @@ -56,6 +58,22 @@ async function createContextByConfig( }; } +export function updateEnvironmentContext( + context: RsbuildContext, + configs: EnvironmentConfig[], +) { + context.environments = configs.map((config) => ({ + name: config.name, + // TODO: replace output.targets with output.target + target: config.output.targets[0], + distPath: getAbsoluteDistPath(context.rootPath, config), + entry: getEntryObject(config, config.output.targets[0]), + tsconfigPath: config.source.tsconfigPath + ? getAbsolutePath(context.rootPath, config.source.tsconfigPath) + : undefined, + })); +} + export function updateContextByNormalizedConfig( context: RsbuildContext, config: NormalizedConfig, diff --git a/packages/core/src/helpers.ts b/packages/core/src/helpers.ts index ed3438b3e9..4886dcf9d0 100644 --- a/packages/core/src/helpers.ts +++ b/packages/core/src/helpers.ts @@ -516,3 +516,6 @@ export function pick(obj: T, keys: ReadonlyArray) { {} as Pick, ); } + +export const camelCase = (input: string): string => + input.replace(/[-_](\w)/g, (_, c) => c.toUpperCase()); diff --git a/packages/core/src/initPlugins.ts b/packages/core/src/initPlugins.ts index 56e332be08..a69138ebe5 100644 --- a/packages/core/src/initPlugins.ts +++ b/packages/core/src/initPlugins.ts @@ -1,5 +1,6 @@ import { join } from 'node:path'; import type { + EnvironmentConfig, GetRsbuildConfig, PluginManager, RsbuildPluginAPI, @@ -60,14 +61,31 @@ export function getPluginAPI({ const { hooks } = context; const publicContext = createPublicContext(context); - const getNormalizedConfig = () => { - if (context.normalizedConfig) { + function getNormalizedConfig(): NormalizedConfig; + function getNormalizedConfig(options: { + environment: string; + }): EnvironmentConfig; + function getNormalizedConfig(options?: { environment: string }) { + if (options?.environment) { + if (context.environmentConfigs) { + const config = context.environmentConfigs?.find( + (e) => e.name === options.environment, + ); + + if (!config) { + throw new Error( + `Cannot find normalized config by environment: ${options.environment}.`, + ); + } + return config; + } + } else if (context.normalizedConfig) { return context.normalizedConfig; } throw new Error( 'Cannot access normalized config until modifyRsbuildConfig is called.', ); - }; + } const getRsbuildConfig = ((type = 'current') => { switch (type) { diff --git a/packages/core/src/mergeConfig.ts b/packages/core/src/mergeConfig.ts index 2e554b22b5..9e54a40a8f 100644 --- a/packages/core/src/mergeConfig.ts +++ b/packages/core/src/mergeConfig.ts @@ -64,11 +64,9 @@ const merge = (x: unknown, y: unknown, path = '') => { return merged; }; -export const mergeRsbuildConfig = ( - ...configs: RsbuildConfig[] -): RsbuildConfig => { +export const mergeRsbuildConfig = (...configs: T[]): T => { if (configs.length === 2) { - return merge(configs[0], configs[1]) as RsbuildConfig; + return merge(configs[0], configs[1]) as T; } if (configs.length < 2) { @@ -76,7 +74,7 @@ export const mergeRsbuildConfig = ( } return configs.reduce( - (result, config) => merge(result, config) as RsbuildConfig, - {}, + (result, config) => merge(result, config) as T, + {} as T, ); }; diff --git a/packages/core/src/provider/initConfigs.ts b/packages/core/src/provider/initConfigs.ts index 6cfc92a30f..0b5bf41efc 100644 --- a/packages/core/src/provider/initConfigs.ts +++ b/packages/core/src/provider/initConfigs.ts @@ -1,10 +1,15 @@ import type { + EnvironmentConfig, InspectConfigOptions, PluginManager, RspackConfig, } from '@rsbuild/shared'; import { normalizeConfig } from '../config'; -import { updateContextByNormalizedConfig } from '../createContext'; +import { + updateContextByNormalizedConfig, + updateEnvironmentContext, +} from '../createContext'; +import { camelCase } from '../helpers'; import { isDebug, logger } from '../logger'; import { mergeRsbuildConfig } from '../mergeConfig'; import { initPlugins } from '../pluginManager'; @@ -33,6 +38,33 @@ export type InitConfigsOptions = { rsbuildOptions: Required; }; +const getEnvironmentsConfig = ( + normalizedConfig: NormalizedConfig, +): EnvironmentConfig[] => { + const { environments, dev, server, ...rsbuildSharedConfig } = + normalizedConfig; + if (environments) { + return Object.entries(environments).map(([name, config]) => ({ + ...mergeRsbuildConfig( + rsbuildSharedConfig, + config as unknown as EnvironmentConfig, + ), + dev, + server, + name, + })); + } + return [ + { + ...rsbuildSharedConfig, + dev, + server, + // TODO: replace output.targets with output.target + name: camelCase(rsbuildSharedConfig.output.targets[0]), + } as EnvironmentConfig, + ]; +}; + export async function initRsbuildConfig({ context, pluginManager, @@ -54,6 +86,12 @@ export async function initRsbuildConfig({ context.normalizedConfig = normalizeConfig(context.config); updateContextByNormalizedConfig(context, context.normalizedConfig); + const environments = getEnvironmentsConfig(context.normalizedConfig); + + context.environmentConfigs = environments; + + updateEnvironmentContext(context, environments); + return context.normalizedConfig; } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 4f2a8f9e9c..40c2445f9f 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -3,6 +3,7 @@ import type { Bundler, CreateCompiler, CreateDevServerOptions, + EnvironmentConfig, InspectConfigOptions, InspectConfigResult, NormalizedConfig, @@ -50,6 +51,8 @@ export type InternalContext = RsbuildContext & { originalConfig: Readonly; /** The normalized Rsbuild config. */ normalizedConfig?: NormalizedConfig; + /** The normalized Rsbuild environment configs. */ + environmentConfigs?: EnvironmentConfig[]; /** The plugin API. */ pluginAPI?: RsbuildPluginAPI; }; diff --git a/packages/core/tests/__snapshots__/environments.test.ts.snap b/packages/core/tests/__snapshots__/environments.test.ts.snap index 71412f61ce..03f5c05338 100644 --- a/packages/core/tests/__snapshots__/environments.test.ts.snap +++ b/packages/core/tests/__snapshots__/environments.test.ts.snap @@ -1,5 +1,127 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`environment config > should normalized environment config correctly 1`] = ` +{ + "dev": { + "assetPrefix": "/", + "client": { + "overlay": true, + }, + "hmr": true, + "liveReload": true, + "startUrl": false, + }, + "html": { + "crossorigin": false, + "inject": "head", + "meta": { + "charset": { + "charset": "UTF-8", + }, + "viewport": "width=device-width, initial-scale=1.0", + }, + "mountId": "root", + "outputStructure": "flat", + "scriptLoading": "defer", + "title": "Rsbuild App", + }, + "name": "web", + "output": { + "assetPrefix": "/", + "charset": "ascii", + "cssModules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "namedExport": false, + }, + "dataUriLimit": { + "font": 4096, + "image": 4096, + "media": 4096, + "svg": 4096, + }, + "distPath": { + "css": "static/css", + "font": "static/font", + "html": "/", + "image": "static/image", + "js": "static/js", + "media": "static/media", + "root": "dist", + "server": "server", + "svg": "static/svg", + "wasm": "static/wasm", + "worker": "worker", + }, + "emitAssets": [Function], + "filename": {}, + "filenameHash": true, + "injectStyles": false, + "inlineScripts": false, + "inlineStyles": false, + "legalComments": "linked", + "manifest": false, + "minify": true, + "polyfill": "usage", + "sourceMap": { + "css": false, + "js": undefined, + }, + "targets": [ + "web", + ], + }, + "performance": { + "buildCache": true, + "chunkSplit": { + "strategy": "split-by-experience", + }, + "printFileSize": true, + "profile": false, + "removeConsole": false, + "removeMomentLocale": false, + }, + "security": { + "nonce": "", + "sri": { + "enable": false, + }, + }, + "server": { + "compress": true, + "host": "0.0.0.0", + "htmlFallback": "index", + "open": false, + "port": 3000, + "printUrls": true, + "strictPort": false, + }, + "source": { + "alias": { + "@common": "src/common", + }, + "aliasStrategy": "prefer-tsconfig", + "decorators": { + "version": "legacy", + }, + "define": {}, + "entry": { + "index": "src/index.client.js", + }, + "preEntry": [], + }, + "tools": { + "cssExtract": { + "loaderOptions": {}, + "pluginOptions": { + "ignoreOrder": true, + }, + }, + }, +} +`; + exports[`environment config > should print environment config when inspect config 1`] = ` { "ssr": { diff --git a/packages/core/tests/environments.test.ts b/packages/core/tests/environments.test.ts index 0e5c969034..2ae393409b 100644 --- a/packages/core/tests/environments.test.ts +++ b/packages/core/tests/environments.test.ts @@ -64,6 +64,43 @@ describe('environment config', () => { expect(rsbuildConfig.environments).toMatchSnapshot(); }); + it('should normalized environment config correctly', async () => { + process.env.NODE_ENV = 'development'; + const rsbuild = await createRsbuild({ + rsbuildConfig: { + source: { + alias: { + '@common': './src/common', + }, + }, + environments: { + web: { + source: { + entry: { + index: './src/index.client.js', + }, + }, + }, + ssr: { + source: { + entry: { + index: './src/index.server.js', + }, + }, + }, + }, + }, + }); + + await rsbuild.initConfigs(); + + const environmentConfig = rsbuild.getNormalizedConfig({ + environment: 'web', + }); + + expect(environmentConfig).toMatchSnapshot(); + }); + it('should print environment config when inspect config', async () => { process.env.NODE_ENV = 'development'; const rsbuild = await createRsbuild({ diff --git a/packages/shared/src/types/config/index.ts b/packages/shared/src/types/config/index.ts index 3d77f79b4e..dd8d77028a 100644 --- a/packages/shared/src/types/config/index.ts +++ b/packages/shared/src/types/config/index.ts @@ -29,7 +29,7 @@ export type RsbuildConfigMeta = { /** * The Rsbuild config to run in the specified environment. * */ -export interface EnvironmentConfig { +export interface EnvironmentOption { /** * Options for HTML generation. */ @@ -63,7 +63,7 @@ export interface EnvironmentConfig { /** * The Rsbuild config. * */ -export interface RsbuildConfig extends EnvironmentConfig { +export interface RsbuildConfig extends EnvironmentOption { /** * Options for local development. */ @@ -81,7 +81,7 @@ export interface RsbuildConfig extends EnvironmentConfig { * Configure rsbuild config by environment. */ environments?: { - [name: string]: EnvironmentConfig; + [name: string]: EnvironmentOption; }; /** * Used to switch the bundler type. @@ -107,10 +107,15 @@ export type NormalizedConfig = DeepReadonly<{ provider?: unknown; _privateMeta?: RsbuildConfigMeta; environments?: { - [name: string]: EnvironmentConfig; + [name: string]: DeepReadonly; }; }>; +/** The normalized Rsbuild environment config. */ +export type EnvironmentConfig = Omit & { + name: string; +}; + export * from './dev'; export * from './html'; export * from './tools'; diff --git a/packages/shared/src/types/context.ts b/packages/shared/src/types/context.ts index 47fe1bacb1..1df3e1a5b2 100644 --- a/packages/shared/src/types/context.ts +++ b/packages/shared/src/types/context.ts @@ -2,6 +2,14 @@ import type { RsbuildEntry, RsbuildTarget } from './rsbuild'; export type BundlerType = 'rspack' | 'webpack'; +type EnvironmentContext = { + name: string; + target: RsbuildTarget; + entry: RsbuildEntry; + distPath: string; + tsconfigPath?: string; +}; + /** The public context */ export type RsbuildContext = { /** The Rsbuild core version. */ @@ -10,6 +18,7 @@ export type RsbuildContext = { entry: RsbuildEntry; /** The build targets type. */ targets: RsbuildTarget[]; + environments: EnvironmentContext[]; /** The root path of current project. */ rootPath: string; /** Absolute path of output files. */ diff --git a/packages/shared/src/types/plugin.ts b/packages/shared/src/types/plugin.ts index 76610fc190..bc4da32f96 100644 --- a/packages/shared/src/types/plugin.ts +++ b/packages/shared/src/types/plugin.ts @@ -8,6 +8,7 @@ import type { import type { ChainIdentifier } from '../chain'; import type { RspackChain } from '../chain'; import type { + EnvironmentConfig, ModifyRspackConfigUtils, NormalizedConfig, RsbuildConfig, @@ -223,6 +224,11 @@ export type TransformFn = ( handler: TransformHandler, ) => void; +declare function getNormalizedConfig(): NormalizedConfig; +declare function getNormalizedConfig(options: { + environment: string; +}): EnvironmentConfig; + /** * Define a generic Rsbuild plugin API that provider can extend as needed. */ @@ -258,7 +264,7 @@ export type RsbuildPluginAPI = Readonly<{ */ getHTMLPaths: () => Record; getRsbuildConfig: GetRsbuildConfig; - getNormalizedConfig: () => NormalizedConfig; + getNormalizedConfig: typeof getNormalizedConfig; /** * For plugin communication From 985dd4f73cd2ba43349dcbd6968106ea5c4a27ae Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Wed, 19 Jun 2024 12:15:02 +0800 Subject: [PATCH 2/4] fix: update test case --- packages/core/tests/__snapshots__/environments.test.ts.snap | 2 +- packages/core/tests/environments.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/tests/__snapshots__/environments.test.ts.snap b/packages/core/tests/__snapshots__/environments.test.ts.snap index 03f5c05338..25d63f2bc2 100644 --- a/packages/core/tests/__snapshots__/environments.test.ts.snap +++ b/packages/core/tests/__snapshots__/environments.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`environment config > should normalized environment config correctly 1`] = ` +exports[`environment config > should normalize environment config correctly 1`] = ` { "dev": { "assetPrefix": "/", diff --git a/packages/core/tests/environments.test.ts b/packages/core/tests/environments.test.ts index 2ae393409b..12287b0889 100644 --- a/packages/core/tests/environments.test.ts +++ b/packages/core/tests/environments.test.ts @@ -64,7 +64,7 @@ describe('environment config', () => { expect(rsbuildConfig.environments).toMatchSnapshot(); }); - it('should normalized environment config correctly', async () => { + it('should normalize environment config correctly', async () => { process.env.NODE_ENV = 'development'; const rsbuild = await createRsbuild({ rsbuildConfig: { From a3b0d0316cd20ad36bf583502227a58f7b7e0452 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Wed, 19 Jun 2024 14:45:25 +0800 Subject: [PATCH 3/4] chore: normalizedEnvironmentConfig --- packages/core/src/config.ts | 6 +- packages/core/src/createContext.ts | 32 +- packages/core/src/initPlugins.ts | 17 +- packages/core/src/plugins/entry.ts | 3 +- packages/core/src/provider/initConfigs.ts | 54 +- packages/core/src/types.ts | 3 - .../__snapshots__/environments.test.ts.snap | 553 +++++++++++++++++- packages/shared/src/types/config/index.ts | 21 +- packages/shared/src/types/context.ts | 3 +- packages/shared/src/types/plugin.ts | 4 +- 10 files changed, 629 insertions(+), 67 deletions(-) diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 5b9d4570ae..aa27a9e734 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -171,6 +171,7 @@ const createDefaultConfig = (): RsbuildConfig => ({ tools: getDefaultToolsConfig(), security: getDefaultSecurityConfig(), performance: getDefaultPerformanceConfig(), + environments: {}, }); function getDefaultEntry(root: string): RsbuildEntry { @@ -225,7 +226,10 @@ export const withDefaultConfig = async ( * 3. Meaningful and can be filled by constant value. */ export const normalizeConfig = (config: RsbuildConfig): NormalizedConfig => - mergeRsbuildConfig(createDefaultConfig(), config) as NormalizedConfig; + mergeRsbuildConfig( + createDefaultConfig(), + config, + ) as unknown as NormalizedConfig; export type ConfigParams = { env: string; diff --git a/packages/core/src/createContext.ts b/packages/core/src/createContext.ts index 19799a104e..1488a9c46d 100644 --- a/packages/core/src/createContext.ts +++ b/packages/core/src/createContext.ts @@ -1,7 +1,7 @@ import { isAbsolute, join } from 'node:path'; import type { BundlerType, - EnvironmentConfig, + NormalizedEnvironmentConfig, RsbuildContext, RsbuildTarget, } from '@rsbuild/shared'; @@ -23,7 +23,7 @@ function getAbsolutePath(root: string, filepath: string) { function getAbsoluteDistPath( cwd: string, - config: RsbuildConfig | NormalizedConfig, + config: RsbuildConfig | NormalizedConfig | NormalizedEnvironmentConfig, ) { const dirRoot = config.output?.distPath?.root ?? ROOT_DIST_DIR; return getAbsolutePath(cwd, dirRoot); @@ -47,7 +47,7 @@ async function createContextByConfig( entry: getEntryObject(config, 'web'), targets: config.output?.targets || [], version: RSBUILD_VERSION, - environments: [], + environments: {}, rootPath, distPath, cachePath, @@ -60,18 +60,22 @@ async function createContextByConfig( export function updateEnvironmentContext( context: RsbuildContext, - configs: EnvironmentConfig[], + configs: Record, ) { - context.environments = configs.map((config) => ({ - name: config.name, - // TODO: replace output.targets with output.target - target: config.output.targets[0], - distPath: getAbsoluteDistPath(context.rootPath, config), - entry: getEntryObject(config, config.output.targets[0]), - tsconfigPath: config.source.tsconfigPath - ? getAbsolutePath(context.rootPath, config.source.tsconfigPath) - : undefined, - })); + context.environments = Object.fromEntries( + Object.entries(configs).map(([name, config]) => [ + name, + { + // TODO: replace output.targets with output.target + target: config.output.targets[0], + distPath: getAbsoluteDistPath(context.rootPath, config), + entry: getEntryObject(config, config.output.targets[0]), + tsconfigPath: config.source.tsconfigPath + ? getAbsolutePath(context.rootPath, config.source.tsconfigPath) + : undefined, + }, + ]), + ); } export function updateContextByNormalizedConfig( diff --git a/packages/core/src/initPlugins.ts b/packages/core/src/initPlugins.ts index a69138ebe5..0a8ef975da 100644 --- a/packages/core/src/initPlugins.ts +++ b/packages/core/src/initPlugins.ts @@ -1,6 +1,6 @@ import { join } from 'node:path'; import type { - EnvironmentConfig, + NormalizedEnvironmentConfig, GetRsbuildConfig, PluginManager, RsbuildPluginAPI, @@ -64,13 +64,12 @@ export function getPluginAPI({ function getNormalizedConfig(): NormalizedConfig; function getNormalizedConfig(options: { environment: string; - }): EnvironmentConfig; + }): NormalizedEnvironmentConfig; function getNormalizedConfig(options?: { environment: string }) { - if (options?.environment) { - if (context.environmentConfigs) { - const config = context.environmentConfigs?.find( - (e) => e.name === options.environment, - ); + if (context.normalizedConfig) { + if (options?.environment) { + const config = + context.normalizedConfig.environments[options.environment]; if (!config) { throw new Error( @@ -78,9 +77,9 @@ export function getPluginAPI({ ); } return config; + } else { + return context.normalizedConfig; } - } else if (context.normalizedConfig) { - return context.normalizedConfig; } throw new Error( 'Cannot access normalized config until modifyRsbuildConfig is called.', diff --git a/packages/core/src/plugins/entry.ts b/packages/core/src/plugins/entry.ts index df9fabe79c..39aa0d2ad7 100644 --- a/packages/core/src/plugins/entry.ts +++ b/packages/core/src/plugins/entry.ts @@ -4,13 +4,14 @@ import { castArray, color, reduceConfigsMergeContext, + type NormalizedEnvironmentConfig, } from '@rsbuild/shared'; import type { EntryDescription } from '@rspack/core'; import { createVirtualModule } from '../helpers'; import type { NormalizedConfig, RsbuildConfig, RsbuildPlugin } from '../types'; export function getEntryObject( - config: RsbuildConfig | NormalizedConfig, + config: RsbuildConfig | NormalizedConfig | NormalizedEnvironmentConfig, target: RsbuildTarget, ): RsbuildEntry { if (!config.source?.entry) { diff --git a/packages/core/src/provider/initConfigs.ts b/packages/core/src/provider/initConfigs.ts index 0b5bf41efc..34264684f5 100644 --- a/packages/core/src/provider/initConfigs.ts +++ b/packages/core/src/provider/initConfigs.ts @@ -1,5 +1,5 @@ import type { - EnvironmentConfig, + NormalizedEnvironmentConfig, InspectConfigOptions, PluginManager, RspackConfig, @@ -38,31 +38,35 @@ export type InitConfigsOptions = { rsbuildOptions: Required; }; -const getEnvironmentsConfig = ( +const normalizeEnvironmentsConfigs = ( normalizedConfig: NormalizedConfig, -): EnvironmentConfig[] => { - const { environments, dev, server, ...rsbuildSharedConfig } = +): Record => { + const { environments, dev, server, provider, ...rsbuildSharedConfig } = normalizedConfig; if (environments) { - return Object.entries(environments).map(([name, config]) => ({ - ...mergeRsbuildConfig( - rsbuildSharedConfig, - config as unknown as EnvironmentConfig, - ), - dev, - server, - name, - })); + return Object.fromEntries( + Object.entries(environments).map(([name, config]) => [ + name, + { + ...mergeRsbuildConfig( + rsbuildSharedConfig, + config as unknown as NormalizedEnvironmentConfig, + ), + dev, + server, + }, + ]), + ); } - return [ - { + + return { + // TODO: replace output.targets with output.target + [camelCase(rsbuildSharedConfig.output.targets[0])]: { ...rsbuildSharedConfig, dev, server, - // TODO: replace output.targets with output.target - name: camelCase(rsbuildSharedConfig.output.targets[0]), - } as EnvironmentConfig, - ]; + }, + }; }; export async function initRsbuildConfig({ @@ -83,12 +87,16 @@ export async function initRsbuildConfig({ }); await modifyRsbuildConfig(context); - context.normalizedConfig = normalizeConfig(context.config); - updateContextByNormalizedConfig(context, context.normalizedConfig); + const normalizeBaseConfig = normalizeConfig(context.config); + + const environments = normalizeEnvironmentsConfigs(normalizeBaseConfig); - const environments = getEnvironmentsConfig(context.normalizedConfig); + context.normalizedConfig = { + ...normalizeBaseConfig, + environments, + }; - context.environmentConfigs = environments; + updateContextByNormalizedConfig(context, context.normalizedConfig); updateEnvironmentContext(context, environments); diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 40c2445f9f..4f2a8f9e9c 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -3,7 +3,6 @@ import type { Bundler, CreateCompiler, CreateDevServerOptions, - EnvironmentConfig, InspectConfigOptions, InspectConfigResult, NormalizedConfig, @@ -51,8 +50,6 @@ export type InternalContext = RsbuildContext & { originalConfig: Readonly; /** The normalized Rsbuild config. */ normalizedConfig?: NormalizedConfig; - /** The normalized Rsbuild environment configs. */ - environmentConfigs?: EnvironmentConfig[]; /** The plugin API. */ pluginAPI?: RsbuildPluginAPI; }; diff --git a/packages/core/tests/__snapshots__/environments.test.ts.snap b/packages/core/tests/__snapshots__/environments.test.ts.snap index 25d63f2bc2..4f2a145db9 100644 --- a/packages/core/tests/__snapshots__/environments.test.ts.snap +++ b/packages/core/tests/__snapshots__/environments.test.ts.snap @@ -25,7 +25,6 @@ exports[`environment config > should normalize environment config correctly 1`] "scriptLoading": "defer", "title": "Rsbuild App", }, - "name": "web", "output": { "assetPrefix": "/", "charset": "ascii", @@ -125,17 +124,239 @@ exports[`environment config > should normalize environment config correctly 1`] exports[`environment config > should print environment config when inspect config 1`] = ` { "ssr": { + "dev": { + "assetPrefix": "/", + "client": { + "overlay": true, + }, + "hmr": true, + "liveReload": true, + "startUrl": false, + }, + "html": { + "crossorigin": false, + "inject": "head", + "meta": { + "charset": { + "charset": "UTF-8", + }, + "viewport": "width=device-width, initial-scale=1.0", + }, + "mountId": "root", + "outputStructure": "flat", + "scriptLoading": "defer", + "title": "Rsbuild App", + }, + "output": { + "assetPrefix": "/", + "charset": "ascii", + "cssModules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "namedExport": false, + }, + "dataUriLimit": { + "font": 4096, + "image": 4096, + "media": 4096, + "svg": 4096, + }, + "distPath": { + "css": "static/css", + "font": "static/font", + "html": "/", + "image": "static/image", + "js": "static/js", + "media": "static/media", + "root": "dist", + "server": "server", + "svg": "static/svg", + "wasm": "static/wasm", + "worker": "worker", + }, + "emitAssets": [Function], + "filename": {}, + "filenameHash": true, + "injectStyles": false, + "inlineScripts": false, + "inlineStyles": false, + "legalComments": "linked", + "manifest": false, + "minify": true, + "polyfill": "usage", + "sourceMap": { + "css": false, + "js": undefined, + }, + "targets": [ + "web", + ], + }, + "performance": { + "buildCache": true, + "chunkSplit": { + "strategy": "split-by-experience", + }, + "printFileSize": true, + "profile": false, + "removeConsole": false, + "removeMomentLocale": false, + }, + "security": { + "nonce": "", + "sri": { + "enable": false, + }, + }, + "server": { + "compress": true, + "host": "0.0.0.0", + "htmlFallback": "index", + "open": false, + "port": 3000, + "printUrls": true, + "strictPort": false, + }, "source": { + "alias": { + "@common": "src/common", + }, + "aliasStrategy": "prefer-tsconfig", + "decorators": { + "version": "legacy", + }, + "define": {}, "entry": { "index": "src/index.server.js", }, + "preEntry": [], + }, + "tools": { + "cssExtract": { + "loaderOptions": {}, + "pluginOptions": { + "ignoreOrder": true, + }, + }, }, }, "web": { + "dev": { + "assetPrefix": "/", + "client": { + "overlay": true, + }, + "hmr": true, + "liveReload": true, + "startUrl": false, + }, + "html": { + "crossorigin": false, + "inject": "head", + "meta": { + "charset": { + "charset": "UTF-8", + }, + "viewport": "width=device-width, initial-scale=1.0", + }, + "mountId": "root", + "outputStructure": "flat", + "scriptLoading": "defer", + "title": "Rsbuild App", + }, + "output": { + "assetPrefix": "/", + "charset": "ascii", + "cssModules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "namedExport": false, + }, + "dataUriLimit": { + "font": 4096, + "image": 4096, + "media": 4096, + "svg": 4096, + }, + "distPath": { + "css": "static/css", + "font": "static/font", + "html": "/", + "image": "static/image", + "js": "static/js", + "media": "static/media", + "root": "dist", + "server": "server", + "svg": "static/svg", + "wasm": "static/wasm", + "worker": "worker", + }, + "emitAssets": [Function], + "filename": {}, + "filenameHash": true, + "injectStyles": false, + "inlineScripts": false, + "inlineStyles": false, + "legalComments": "linked", + "manifest": false, + "minify": true, + "polyfill": "usage", + "sourceMap": { + "css": false, + "js": undefined, + }, + "targets": [ + "web", + ], + }, + "performance": { + "buildCache": true, + "chunkSplit": { + "strategy": "split-by-experience", + }, + "printFileSize": true, + "profile": false, + "removeConsole": false, + "removeMomentLocale": false, + }, + "security": { + "nonce": "", + "sri": { + "enable": false, + }, + }, + "server": { + "compress": true, + "host": "0.0.0.0", + "htmlFallback": "index", + "open": false, + "port": 3000, + "printUrls": true, + "strictPort": false, + }, "source": { + "alias": { + "@common": "src/common", + }, + "aliasStrategy": "prefer-tsconfig", + "decorators": { + "version": "legacy", + }, + "define": {}, "entry": { "index": "src/index.client.js", }, + "preEntry": [], + }, + "tools": { + "cssExtract": { + "loaderOptions": {}, + "pluginOptions": { + "ignoreOrder": true, + }, + }, }, }, } @@ -144,27 +365,357 @@ exports[`environment config > should print environment config when inspect confi exports[`environment config > should support modify environment config by api.modifyRsbuildConfig 1`] = ` { "ssr": { + "dev": { + "assetPrefix": "/", + "client": { + "overlay": true, + }, + "hmr": true, + "liveReload": true, + "startUrl": false, + }, + "html": { + "crossorigin": false, + "inject": "head", + "meta": { + "charset": { + "charset": "UTF-8", + }, + "viewport": "width=device-width, initial-scale=1.0", + }, + "mountId": "root", + "outputStructure": "flat", + "scriptLoading": "defer", + "title": "Rsbuild App", + }, + "output": { + "assetPrefix": "/", + "charset": "ascii", + "cssModules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "namedExport": false, + }, + "dataUriLimit": { + "font": 4096, + "image": 4096, + "media": 4096, + "svg": 4096, + }, + "distPath": { + "css": "static/css", + "font": "static/font", + "html": "/", + "image": "static/image", + "js": "static/js", + "media": "static/media", + "root": "dist", + "server": "server", + "svg": "static/svg", + "wasm": "static/wasm", + "worker": "worker", + }, + "emitAssets": [Function], + "filename": {}, + "filenameHash": true, + "injectStyles": false, + "inlineScripts": false, + "inlineStyles": false, + "legalComments": "linked", + "manifest": false, + "minify": true, + "polyfill": "usage", + "sourceMap": { + "css": false, + "js": undefined, + }, + "targets": [ + "web", + ], + }, + "performance": { + "buildCache": true, + "chunkSplit": { + "strategy": "split-by-experience", + }, + "printFileSize": true, + "profile": false, + "removeConsole": false, + "removeMomentLocale": false, + }, + "security": { + "nonce": "", + "sri": { + "enable": false, + }, + }, + "server": { + "compress": true, + "host": "0.0.0.0", + "htmlFallback": "index", + "open": false, + "port": 3000, + "printUrls": true, + "strictPort": false, + }, "source": { + "alias": { + "@common": "src/common", + }, + "aliasStrategy": "prefer-tsconfig", + "decorators": { + "version": "legacy", + }, + "define": {}, "entry": { "index": "src/index.server.js", }, + "preEntry": [], + }, + "tools": { + "cssExtract": { + "loaderOptions": {}, + "pluginOptions": { + "ignoreOrder": true, + }, + }, }, }, "web": { + "dev": { + "assetPrefix": "/", + "client": { + "overlay": true, + }, + "hmr": true, + "liveReload": true, + "startUrl": false, + }, + "html": { + "crossorigin": false, + "inject": "head", + "meta": { + "charset": { + "charset": "UTF-8", + }, + "viewport": "width=device-width, initial-scale=1.0", + }, + "mountId": "root", + "outputStructure": "flat", + "scriptLoading": "defer", + "title": "Rsbuild App", + }, + "output": { + "assetPrefix": "/", + "charset": "ascii", + "cssModules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "namedExport": false, + }, + "dataUriLimit": { + "font": 4096, + "image": 4096, + "media": 4096, + "svg": 4096, + }, + "distPath": { + "css": "static/css", + "font": "static/font", + "html": "/", + "image": "static/image", + "js": "static/js", + "media": "static/media", + "root": "dist", + "server": "server", + "svg": "static/svg", + "wasm": "static/wasm", + "worker": "worker", + }, + "emitAssets": [Function], + "filename": {}, + "filenameHash": true, + "injectStyles": false, + "inlineScripts": false, + "inlineStyles": false, + "legalComments": "linked", + "manifest": false, + "minify": true, + "polyfill": "usage", + "sourceMap": { + "css": false, + "js": undefined, + }, + "targets": [ + "web", + ], + }, + "performance": { + "buildCache": true, + "chunkSplit": { + "strategy": "split-by-experience", + }, + "printFileSize": true, + "profile": false, + "removeConsole": false, + "removeMomentLocale": false, + }, + "security": { + "nonce": "", + "sri": { + "enable": false, + }, + }, + "server": { + "compress": true, + "host": "0.0.0.0", + "htmlFallback": "index", + "open": false, + "port": 3000, + "printUrls": true, + "strictPort": false, + }, "source": { "alias": { + "@common": "src/common", "@common1": "src/common1", }, + "aliasStrategy": "prefer-tsconfig", + "decorators": { + "version": "legacy", + }, + "define": {}, "entry": { "index": "src/index.client.js", }, + "preEntry": [], + }, + "tools": { + "cssExtract": { + "loaderOptions": {}, + "pluginOptions": { + "ignoreOrder": true, + }, + }, }, }, "web1": { + "dev": { + "assetPrefix": "/", + "client": { + "overlay": true, + }, + "hmr": true, + "liveReload": true, + "startUrl": false, + }, + "html": { + "crossorigin": false, + "inject": "head", + "meta": { + "charset": { + "charset": "UTF-8", + }, + "viewport": "width=device-width, initial-scale=1.0", + }, + "mountId": "root", + "outputStructure": "flat", + "scriptLoading": "defer", + "title": "Rsbuild App", + }, + "output": { + "assetPrefix": "/", + "charset": "ascii", + "cssModules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "namedExport": false, + }, + "dataUriLimit": { + "font": 4096, + "image": 4096, + "media": 4096, + "svg": 4096, + }, + "distPath": { + "css": "static/css", + "font": "static/font", + "html": "/", + "image": "static/image", + "js": "static/js", + "media": "static/media", + "root": "dist", + "server": "server", + "svg": "static/svg", + "wasm": "static/wasm", + "worker": "worker", + }, + "emitAssets": [Function], + "filename": {}, + "filenameHash": true, + "injectStyles": false, + "inlineScripts": false, + "inlineStyles": false, + "legalComments": "linked", + "manifest": false, + "minify": true, + "polyfill": "usage", + "sourceMap": { + "css": false, + "js": undefined, + }, + "targets": [ + "web", + ], + }, + "performance": { + "buildCache": true, + "chunkSplit": { + "strategy": "split-by-experience", + }, + "printFileSize": true, + "profile": false, + "removeConsole": false, + "removeMomentLocale": false, + }, + "security": { + "nonce": "", + "sri": { + "enable": false, + }, + }, + "server": { + "compress": true, + "host": "0.0.0.0", + "htmlFallback": "index", + "open": false, + "port": 3000, + "printUrls": true, + "strictPort": false, + }, "source": { "alias": { + "@common": "src/common", "@common1": "src/common1", }, + "aliasStrategy": "prefer-tsconfig", + "decorators": { + "version": "legacy", + }, + "define": {}, + "entry": {}, + "preEntry": [], + }, + "tools": { + "cssExtract": { + "loaderOptions": {}, + "pluginOptions": { + "ignoreOrder": true, + }, + }, }, }, } diff --git a/packages/shared/src/types/config/index.ts b/packages/shared/src/types/config/index.ts index dd8d77028a..fb43558c07 100644 --- a/packages/shared/src/types/config/index.ts +++ b/packages/shared/src/types/config/index.ts @@ -29,7 +29,7 @@ export type RsbuildConfigMeta = { /** * The Rsbuild config to run in the specified environment. * */ -export interface EnvironmentOption { +export interface EnvironmentConfig { /** * Options for HTML generation. */ @@ -63,7 +63,7 @@ export interface EnvironmentOption { /** * The Rsbuild config. * */ -export interface RsbuildConfig extends EnvironmentOption { +export interface RsbuildConfig extends EnvironmentConfig { /** * Options for local development. */ @@ -81,7 +81,7 @@ export interface RsbuildConfig extends EnvironmentOption { * Configure rsbuild config by environment. */ environments?: { - [name: string]: EnvironmentOption; + [name: string]: EnvironmentConfig; }; /** * Used to switch the bundler type. @@ -93,7 +93,8 @@ export interface RsbuildConfig extends EnvironmentOption { _privateMeta?: RsbuildConfigMeta; } -export type NormalizedConfig = DeepReadonly<{ +/** The normalized Rsbuild environment config. */ +export type NormalizedEnvironmentConfig = DeepReadonly<{ dev: NormalizedDevConfig; html: NormalizedHtmlConfig; tools: NormalizedToolsConfig; @@ -104,16 +105,14 @@ export type NormalizedConfig = DeepReadonly<{ security: NormalizedSecurityConfig; performance: NormalizedPerformanceConfig; moduleFederation?: ModuleFederationConfig; - provider?: unknown; _privateMeta?: RsbuildConfigMeta; - environments?: { - [name: string]: DeepReadonly; - }; }>; -/** The normalized Rsbuild environment config. */ -export type EnvironmentConfig = Omit & { - name: string; +export type NormalizedConfig = NormalizedEnvironmentConfig & { + provider?: unknown; + environments: { + [name: string]: NormalizedEnvironmentConfig; + }; }; export * from './dev'; diff --git a/packages/shared/src/types/context.ts b/packages/shared/src/types/context.ts index 1df3e1a5b2..cd84f673fb 100644 --- a/packages/shared/src/types/context.ts +++ b/packages/shared/src/types/context.ts @@ -3,7 +3,6 @@ import type { RsbuildEntry, RsbuildTarget } from './rsbuild'; export type BundlerType = 'rspack' | 'webpack'; type EnvironmentContext = { - name: string; target: RsbuildTarget; entry: RsbuildEntry; distPath: string; @@ -18,7 +17,7 @@ export type RsbuildContext = { entry: RsbuildEntry; /** The build targets type. */ targets: RsbuildTarget[]; - environments: EnvironmentContext[]; + environments: Record; /** The root path of current project. */ rootPath: string; /** Absolute path of output files. */ diff --git a/packages/shared/src/types/plugin.ts b/packages/shared/src/types/plugin.ts index bc4da32f96..31b359ba1a 100644 --- a/packages/shared/src/types/plugin.ts +++ b/packages/shared/src/types/plugin.ts @@ -8,7 +8,7 @@ import type { import type { ChainIdentifier } from '../chain'; import type { RspackChain } from '../chain'; import type { - EnvironmentConfig, + NormalizedEnvironmentConfig, ModifyRspackConfigUtils, NormalizedConfig, RsbuildConfig, @@ -227,7 +227,7 @@ export type TransformFn = ( declare function getNormalizedConfig(): NormalizedConfig; declare function getNormalizedConfig(options: { environment: string; -}): EnvironmentConfig; +}): NormalizedEnvironmentConfig; /** * Define a generic Rsbuild plugin API that provider can extend as needed. From c0f5049b7cbc10404bd15ba591aef3a7739a2645 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Wed, 19 Jun 2024 14:48:14 +0800 Subject: [PATCH 4/4] fix: lint --- packages/core/src/initPlugins.ts | 5 ++--- packages/core/src/plugins/entry.ts | 2 +- packages/core/src/provider/initConfigs.ts | 2 +- packages/shared/src/types/plugin.ts | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/core/src/initPlugins.ts b/packages/core/src/initPlugins.ts index 0a8ef975da..fceb0978b4 100644 --- a/packages/core/src/initPlugins.ts +++ b/packages/core/src/initPlugins.ts @@ -1,7 +1,7 @@ import { join } from 'node:path'; import type { - NormalizedEnvironmentConfig, GetRsbuildConfig, + NormalizedEnvironmentConfig, PluginManager, RsbuildPluginAPI, RspackChain, @@ -77,9 +77,8 @@ export function getPluginAPI({ ); } return config; - } else { - return context.normalizedConfig; } + return context.normalizedConfig; } throw new Error( 'Cannot access normalized config until modifyRsbuildConfig is called.', diff --git a/packages/core/src/plugins/entry.ts b/packages/core/src/plugins/entry.ts index 41e03f5c15..dab08d8fc5 100644 --- a/packages/core/src/plugins/entry.ts +++ b/packages/core/src/plugins/entry.ts @@ -1,9 +1,9 @@ import { + type NormalizedEnvironmentConfig, type RsbuildEntry, type RsbuildTarget, castArray, color, - type NormalizedEnvironmentConfig, } from '@rsbuild/shared'; import type { EntryDescription } from '@rspack/core'; import { createVirtualModule } from '../helpers'; diff --git a/packages/core/src/provider/initConfigs.ts b/packages/core/src/provider/initConfigs.ts index 34264684f5..9ae4dbca9d 100644 --- a/packages/core/src/provider/initConfigs.ts +++ b/packages/core/src/provider/initConfigs.ts @@ -1,6 +1,6 @@ import type { - NormalizedEnvironmentConfig, InspectConfigOptions, + NormalizedEnvironmentConfig, PluginManager, RspackConfig, } from '@rsbuild/shared'; diff --git a/packages/shared/src/types/plugin.ts b/packages/shared/src/types/plugin.ts index 31b359ba1a..3086a64731 100644 --- a/packages/shared/src/types/plugin.ts +++ b/packages/shared/src/types/plugin.ts @@ -8,9 +8,9 @@ import type { import type { ChainIdentifier } from '../chain'; import type { RspackChain } from '../chain'; import type { - NormalizedEnvironmentConfig, ModifyRspackConfigUtils, NormalizedConfig, + NormalizedEnvironmentConfig, RsbuildConfig, } from './config'; import type { RsbuildContext } from './context';