Skip to content

Commit

Permalink
feat: add syntax placeholder, supersede platform with target (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework authored Jul 9, 2024
1 parent ec80e4d commit 1e4dd8d
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 42 deletions.
4 changes: 2 additions & 2 deletions e2e/cases/externals/node/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { generateBundleCjsConfig, generateBundleEsmConfig } from '#shared';

export default defineConfig({
lib: [
generateBundleEsmConfig(__dirname, { platform: 'node' }),
generateBundleCjsConfig(__dirname, { platform: 'node' }),
generateBundleEsmConfig(__dirname, { output: { target: 'node' } }),
generateBundleCjsConfig(__dirname, { output: { target: 'node' } }),
],
source: {
entry: {
Expand Down
93 changes: 55 additions & 38 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import { DEFAULT_CONFIG_NAME, DEFAULT_EXTENSIONS } from './constant';
import type {
Format,
LibConfig,
Platform,
RslibConfig,
RslibConfigAsyncFn,
RslibConfigExport,
RslibConfigSyncFn,
Syntax,
} from './types/config';
import { getDefaultExtension } from './utils/extension';
import { color } from './utils/helper';
Expand Down Expand Up @@ -155,27 +155,6 @@ const getDefaultFormatConfig = (format: Format): RsbuildConfig => {
}
};

const getDefaultPlatformConfig = (platform: Platform): RsbuildConfig => {
switch (platform) {
case 'browser':
return {};
case 'node':
return {
output: {
// When output.target is 'node', Node.js's built-in will be treated as externals of type `node-commonjs`.
// Simply override the built-in modules to make them external.
// https://github.com/webpack/webpack/blob/dd44b206a9c50f4b4cb4d134e1a0bd0387b159a3/lib/node/NodeTargetPlugin.js#L81
externals: nodeBuiltInModules,
target: 'node',
},
};
case 'neutral':
return {};
default:
throw new Error(`Unsupported platform: ${platform}`);
}
};

const getDefaultAutoExtensionConfig = (
format: Format,
root: string,
Expand All @@ -196,33 +175,61 @@ const getDefaultAutoExtensionConfig = (
};
};

const getDefaultSyntax = (_syntax?: Syntax): RsbuildConfig => {
return {};
};

export function convertLibConfigToRsbuildConfig(
libConfig: LibConfig,
rsbuildConfig: RsbuildConfig,
configPath: string,
): RsbuildConfig {
const { format, platform = 'browser', autoExtension = false } = libConfig;
const { format, autoExtension = false } = libConfig;

const formatConfig = getDefaultFormatConfig(format!);
const platformConfig = getDefaultPlatformConfig(platform);
const autoExtensionConfig = getDefaultAutoExtensionConfig(
format!,
dirname(rsbuildConfig._privateMeta?.configFilePath ?? process.cwd()),
dirname(configPath),
autoExtension,
);
const syntaxConfig = getDefaultSyntax(libConfig.output?.syntax);

return mergeRsbuildConfig(formatConfig, autoExtensionConfig, syntaxConfig);
}

return mergeRsbuildConfig(
rsbuildConfig,
formatConfig,
platformConfig,
autoExtensionConfig,
function postUpdateRsbuildConfig(rsbuildConfig: RsbuildConfig) {
const defaultTargetConfig = getDefaultTargetConfig(
rsbuildConfig.output?.target ?? 'web',
);

return mergeRsbuildConfig(defaultTargetConfig);
}

const getDefaultTargetConfig = (target: string): RsbuildConfig => {
switch (target) {
case 'web':
return {};
case 'node':
return {
output: {
// When output.target is 'node', Node.js's built-in will be treated as externals of type `node-commonjs`.
// Simply override the built-in modules to make them external.
// https://github.com/webpack/webpack/blob/dd44b206a9c50f4b4cb4d134e1a0bd0387b159a3/lib/node/NodeTargetPlugin.js#L81
externals: nodeBuiltInModules,
target: 'node',
},
};
case 'neutral':
return {};
default:
throw new Error(`Unsupported platform: ${target}`);
}
};

export async function composeCreateRsbuildConfig(
rslibConfig: RslibConfig,
): Promise<Partial<Record<Format, RsbuildConfig>>> {
const internalRsbuildConfig = await createInternalRsbuildConfig();

const configPath = rslibConfig._privateMeta?.configFilePath ?? process.cwd();
const { lib: libConfigsArray, ...sharedRsbuildConfig } = rslibConfig;

if (!libConfigsArray) {
Expand All @@ -234,19 +241,29 @@ export async function composeCreateRsbuildConfig(
const composedRsbuildConfig: Partial<Record<Format, RsbuildConfig>> = {};

for (const libConfig of libConfigsArray) {
const { format, platform, ...overrideRsbuildConfig } = libConfig;
const { format, ...overrideRsbuildConfig } = libConfig;

const libConvertedRsbuildConfig = convertLibConfigToRsbuildConfig(
libConfig,
configPath,
);

// Merge order matters, keep `internalRsbuildConfig` at the last position
// to ensure that the internal config is not overridden by the user's config.
const mergedRsbuildConfig = mergeRsbuildConfig(
sharedRsbuildConfig,
overrideRsbuildConfig,
internalRsbuildConfig,
libConvertedRsbuildConfig,
);

composedRsbuildConfig[format!] = convertLibConfigToRsbuildConfig(
libConfig,
// Some configurations can be defined both in the shared config and the lib config.
// So we need to do the post process after lib config is converted and merged.
const postUpdatedConfig = postUpdateRsbuildConfig(mergedRsbuildConfig);

composedRsbuildConfig[format!] = mergeRsbuildConfig(
mergedRsbuildConfig,
postUpdatedConfig,
// Merge order matters, keep `internalRsbuildConfig` at the last position
// to ensure that the internal config is not overridden by user's config.
internalRsbuildConfig,
);
}

Expand Down
30 changes: 28 additions & 2 deletions packages/core/src/types/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,38 @@
import type { RsbuildConfig } from '@rsbuild/core';

export type Format = 'esm' | 'cjs' | 'umd';
export type Platform = 'node' | 'browser' | 'neutral';

export type EcmaScriptVersion =
| 'esnext'
| 'es5'
| 'es6'
| 'es2015'
| 'es2016'
| 'es2017'
| 'es2018'
| 'es2019'
| 'es2020'
| 'es2021'
| 'es2022'
| 'es2023'
| 'es2024';

export type Syntax =
// Use browserslist config file
| 'browserslist'
// ECMAScript versions as an common used addition to browserslist query
| EcmaScriptVersion
| EcmaScriptVersion[]
// Support inline browserslist query, like defined in package.json
| string[];

export interface LibConfig extends RsbuildConfig {
format?: Format;
platform?: Platform;
autoExtension?: boolean;
output?: RsbuildConfig['output'] & {
/** Support esX and browserslist query */
syntax?: Syntax;
};
}

export interface RslibConfig extends RsbuildConfig {
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/utils/browserslist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { EcmaScriptVersion } from '../types/config';

export const esVersionToBrowserList = (
_esVersion: EcmaScriptVersion,
): string[] => {
// TODO: transform esX to browserslist
return [];
};

0 comments on commit 1e4dd8d

Please sign in to comment.