Skip to content

Commit

Permalink
refactor(builder): replace babel config with @rsbuild/babel-preset (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan authored Oct 12, 2023
1 parent 1563e63 commit db59437
Show file tree
Hide file tree
Showing 17 changed files with 2,193 additions and 2,697 deletions.
1 change: 0 additions & 1 deletion packages/builder/builder-webpack-provider/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const restrictedImportInSource = {
'lodash',
'ts-loader',
'typescript',
'@modern-js/utils',
...devDependencyPaths,
].map(withAllowTypeImports('name')),
patterns: [
Expand Down
5 changes: 3 additions & 2 deletions packages/builder/builder-webpack-provider/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,16 @@
"dependencies": {
"@babel/core": "^7.22.15",
"@babel/preset-react": "^7.22.15",
"@modern-js/babel-preset-app": "workspace:*",
"@modern-js/babel-preset-base": "workspace:*",
"@modern-js/builder-shared": "workspace:*",
"@modern-js/inspector-webpack-plugin": "1.0.6",
"@modern-js/server": "workspace:*",
"@modern-js/types": "workspace:*",
"@modern-js/utils": "workspace:*",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.10",
"@rsbuild/babel-preset": "0.0.6",
"@swc/helpers": "0.5.1",
"babel-plugin-import": "1.13.5",
"babel-plugin-styled-components": "1.13.3",
"caniuse-lite": "^1.0.30001520",
"html-webpack-plugin": "5.5.3",
"mini-css-extract-plugin": "2.7.6",
Expand Down
140 changes: 78 additions & 62 deletions packages/builder/builder-webpack-provider/src/plugins/babel.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import {
getBabelConfig,
createBabelChain,
type BabelOptions,
BabelChain,
} from '@modern-js/babel-preset-app';
import { getBabelConfigForWeb } from '@rsbuild/babel-preset/web';
import { getBabelConfigForNode } from '@rsbuild/babel-preset/node';
import type { BabelConfig } from '@rsbuild/babel-preset';
import {
JS_REGEX,
TS_REGEX,
Expand All @@ -20,6 +17,7 @@ import type {
NormalizedConfig,
TransformImport,
} from '../types';
import { getBabelUtils } from '@modern-js/utils';

export const getUseBuiltIns = (config: NormalizedConfig) => {
const { polyfill } = config.output;
Expand All @@ -44,9 +42,7 @@ export const builderPluginBabel = (): BuilderPlugin => ({
getCompiledPath,
},
) => {
const { lodash, applyOptionsChain, isUseSSRBundle } = await import(
'@modern-js/utils'
);
const { lodash, applyOptionsChain } = await import('@modern-js/utils');

const config = api.getNormalizedConfig();
const browserslist = await getBrowserslistWithDefault(
Expand All @@ -55,21 +51,8 @@ export const builderPluginBabel = (): BuilderPlugin => ({
target,
);

const getBabelOptions = (
appDirectory: string,
config: NormalizedConfig,
) => {
const getBabelOptions = (config: NormalizedConfig) => {
// 1. Get styled-components options
const styledComponentsOptions =
config.tools.styledComponents !== false
? applyOptionsChain(
getDefaultStyledComponentsConfig(
isProd,
isUseSSRBundle(config),
),
config.tools.styledComponents,
)
: false;

// 2. Create babel util function about include/exclude
const includes: Array<string | RegExp> = [];
Expand All @@ -92,49 +75,59 @@ export const builderPluginBabel = (): BuilderPlugin => ({
},
};

const chain = createBabelChain();
applyPluginImport(chain, config.source.transformImport);
applyPluginLodash(chain, config.performance.transformLodash);
const baseBabelConfig =
isServer || isServiceWorker
? getBabelConfigForNode()
: getBabelConfigForWeb({
presetEnv: {
targets: browserslist,
useBuiltIns: getUseBuiltIns(config),
},
pluginDecorators: {
version: config.output.enableLatestDecorators
? '2018-09'
: 'legacy',
},
});

applyPluginImport(baseBabelConfig, config.source.transformImport);
applyPluginLodash(
baseBabelConfig,
config.performance.transformLodash,
);
applyPluginStyledComponents(baseBabelConfig, config, isProd);

const babelConfig = applyOptionsChain(
baseBabelConfig,
config.tools.babel,
{
...getBabelUtils(baseBabelConfig),
babelUtils,
},
);

// 3. Compute final babel config by @modern-js/babel-preset-app
const babelOptions: BabelOptions = {
// 3. Compute final babel config
const finalOptions: BabelConfig = {
babelrc: false,
configFile: false,
compact: isProd,
...getBabelConfig({
target: isServer || isServiceWorker ? 'server' : 'client',
appDirectory,
useLegacyDecorators: !config.output.enableLatestDecorators,
useBuiltIns:
isServer || isServiceWorker ? false : getUseBuiltIns(config),
chain,
styledComponents: styledComponentsOptions,
userBabelConfig: config.tools.babel,
userBabelConfigUtils: babelUtils,
overrideBrowserslist: browserslist,
importAntd: false,
disableReactPreset: true,
}),
...babelConfig,
};

if (config.output.charset === 'utf8') {
babelOptions.generatorOpts = {
finalOptions.generatorOpts = {
jsescOption: { minimal: true },
};
}

return {
babelOptions,
babelOptions: finalOptions,
includes,
excludes,
};
};

const { rootPath } = api.context;
const { babelOptions, includes, excludes } = getBabelOptions(
rootPath,
config,
);
const { babelOptions, includes, excludes } = getBabelOptions(config);
const useTsLoader = Boolean(config.tools.tsLoader);
const rule = chain.module.rule(CHAIN_ID.RULE.JS);

Expand Down Expand Up @@ -176,16 +169,42 @@ export const builderPluginBabel = (): BuilderPlugin => ({
},
});

function applyPluginLodash(chain: BabelChain, transformLodash?: boolean) {
function applyPluginLodash(config: BabelConfig, transformLodash?: boolean) {
if (transformLodash) {
chain
.plugin('babel-plugin-lodash')
.use(getCompiledPath('babel-plugin-lodash'), [{}]);
config.plugins?.push([getCompiledPath('babel-plugin-lodash'), {}]);
}
}

async function applyPluginStyledComponents(
babelConfig: BabelConfig,
builderConfig: NormalizedConfig,
isProd: boolean,
) {
const { applyOptionsChain, isUseSSRBundle } = await import(
'@modern-js/utils'
);

const styledComponentsOptions =
builderConfig.tools.styledComponents !== false
? applyOptionsChain(
getDefaultStyledComponentsConfig(
isProd,
isUseSSRBundle(builderConfig),
),
builderConfig.tools.styledComponents,
)
: false;

if (styledComponentsOptions) {
babelConfig.plugins?.push([
require.resolve('babel-plugin-styled-components'),
styledComponentsOptions,
]);
}
}

function applyPluginImport(
chain: BabelChain,
config: BabelConfig,
pluginImport?: false | TransformImport[],
) {
if (pluginImport !== false && pluginImport) {
Expand All @@ -207,14 +226,11 @@ function applyPluginImport(
delete option.camelToDashComponentName;
}

chain
.plugin(`plugin-import-${name}`)
.use(
require.resolve(
'@modern-js/babel-preset-base/compiled/babel-plugin-import',
),
[option, name],
);
config.plugins?.push([
require.resolve('babel-plugin-import'),
option,
name,
]);
}
}
}
136 changes: 73 additions & 63 deletions packages/builder/builder-webpack-provider/src/plugins/tsLoader.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,94 @@
import {
TS_REGEX,
resolvePackage,
applyScriptCondition,
getBrowserslistWithDefault,
} from '@modern-js/builder-shared';
import _ from '@modern-js/utils/lodash';
import { getBabelConfigForWeb } from '@rsbuild/babel-preset/web';
import { BuilderPlugin } from '../types';
import { getUseBuiltIns } from './babel';

export const builderPluginTsLoader = (): BuilderPlugin => {
return {
name: 'builder-plugin-ts-loader',
setup(api) {
api.modifyWebpackChain(async (chain, { CHAIN_ID, getCompiledPath }) => {
const config = api.getNormalizedConfig();
if (!config.tools.tsLoader) {
return;
}
api.modifyWebpackChain(
async (chain, { target, CHAIN_ID, getCompiledPath }) => {
const config = api.getNormalizedConfig();
if (!config.tools.tsLoader) {
return;
}
const { getBabelUtils, applyOptionsChain } = await import(
'@modern-js/utils'
);

const { rootPath } = api.context;
const babelLoaderOptions = {
presets: [
[
resolvePackage('@modern-js/babel-preset-app', __dirname),
{
appDirectory: rootPath,
target: 'client',
useTsLoader: true,
useBuiltIns: getUseBuiltIns(config),
userBabelConfig: config.tools.babel,
disableReactPreset: true,
},
],
],
};
const { rootPath } = api.context;
const browserslist = await getBrowserslistWithDefault(
rootPath,
config,
target,
);

const baseBabelConfig = getBabelConfigForWeb({
presetEnv: {
targets: browserslist,
useBuiltIns: getUseBuiltIns(config),
},
});

const babelUtils = getBabelUtils(baseBabelConfig);

const includes: Array<string | RegExp> = [];
const excludes: Array<string | RegExp> = [];
const babelLoaderOptions = applyOptionsChain(
baseBabelConfig,
config.tools.babel,
babelUtils,
);

const tsLoaderUtils = {
addIncludes(items: string | RegExp | (string | RegExp)[]) {
includes.push(..._.castArray(items));
},
addExcludes(items: string | RegExp | (string | RegExp)[]) {
excludes.push(..._.castArray(items));
},
};
const { applyOptionsChain } = await import('@modern-js/utils');
// @ts-expect-error ts-loader has incorrect types for compilerOptions
const tsLoaderOptions = applyOptionsChain(
{
compilerOptions: {
target: 'esnext',
module: 'esnext',
const includes: Array<string | RegExp> = [];
const excludes: Array<string | RegExp> = [];

const tsLoaderUtils = {
addIncludes(items: string | RegExp | (string | RegExp)[]) {
includes.push(..._.castArray(items));
},
addExcludes(items: string | RegExp | (string | RegExp)[]) {
excludes.push(..._.castArray(items));
},
};
// @ts-expect-error ts-loader has incorrect types for compilerOptions
const tsLoaderOptions = applyOptionsChain(
{
compilerOptions: {
target: 'esnext',
module: 'esnext',
},
transpileOnly: true,
allowTsInNodeModules: true,
},
transpileOnly: true,
allowTsInNodeModules: true,
},
config.tools.tsLoader,
tsLoaderUtils,
);
const rule = chain.module.rule(CHAIN_ID.RULE.TS);
config.tools.tsLoader,
tsLoaderUtils,
);
const rule = chain.module.rule(CHAIN_ID.RULE.TS);

applyScriptCondition({
rule,
config,
context: api.context,
includes,
excludes,
});
applyScriptCondition({
rule,
config,
context: api.context,
includes,
excludes,
});

rule
.test(TS_REGEX)
.use(CHAIN_ID.USE.BABEL)
.loader(getCompiledPath('babel-loader'))
.options(babelLoaderOptions)
.end()
.use(CHAIN_ID.USE.TS)
.loader(require.resolve('ts-loader'))
.options(tsLoaderOptions);
});
rule
.test(TS_REGEX)
.use(CHAIN_ID.USE.BABEL)
.loader(getCompiledPath('babel-loader'))
.options(babelLoaderOptions)
.end()
.use(CHAIN_ID.USE.TS)
.loader(require.resolve('ts-loader'))
.options(tsLoaderOptions);
},
);
},
};
};
Loading

0 comments on commit db59437

Please sign in to comment.