@jpp-toolkit/rspack-config 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +48 -12
- package/dist/index.mjs +331 -120
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -2
- package/src/constants.ts +4 -0
- package/src/create-rspack-config.ts +136 -0
- package/src/index.ts +2 -1
- package/src/presets/base-preset.ts +114 -0
- package/src/presets/fivem-script-preset.ts +27 -0
- package/src/presets/fivem-ui-preset.ts +41 -0
- package/src/presets/index.ts +5 -0
- package/src/presets/node-preset.ts +65 -0
- package/src/presets/react-preset.ts +139 -0
- package/src/types/index.ts +3 -0
- package/src/types/preset.ts +13 -0
- package/src/types/rspack-env.ts +6 -0
- package/src/types/run-context.ts +8 -0
- package/src/utils/find-first-existing-file.ts +7 -0
- package/src/utils/merge-config.ts +14 -0
- package/src/create-fivem-rspack-config.ts +0 -166
- package/src/enums/environment.ts +0 -5
- package/src/enums/fivem-entry-type.ts +0 -7
- package/src/enums/index.ts +0 -2
- package/src/utils/find-first-existing-path.ts +0 -6
package/src/constants.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { RspackOptions } from '@rspack/core';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
basePreset,
|
|
5
|
+
fivemScriptPreset,
|
|
6
|
+
fivemUiPreset,
|
|
7
|
+
getFivemScriptPresetDefaultOptions,
|
|
8
|
+
getFivemUiPresetDefaultOptions,
|
|
9
|
+
getNodePresetDefaultOptions,
|
|
10
|
+
getReactPresetDefaultOptions,
|
|
11
|
+
nodePreset,
|
|
12
|
+
reactPreset,
|
|
13
|
+
} from './presets';
|
|
14
|
+
import type {
|
|
15
|
+
FivemScriptPresetOptions,
|
|
16
|
+
FivemUiPresetOptions,
|
|
17
|
+
NodePresetOptions,
|
|
18
|
+
ReactPresetOptions,
|
|
19
|
+
} from './presets';
|
|
20
|
+
import type { RspackEnv, RunContext } from './types';
|
|
21
|
+
import { findFirstExistingFile } from './utils/find-first-existing-file';
|
|
22
|
+
import { mergeConfig } from './utils/merge-config';
|
|
23
|
+
|
|
24
|
+
function createConfigBuilder<TOptions, TReturn extends RspackOptions | RspackOptions[]>(
|
|
25
|
+
func: (options: Partial<TOptions>, context: RunContext) => TReturn,
|
|
26
|
+
) {
|
|
27
|
+
return function (options: Partial<TOptions> = {}, context: Partial<RunContext> = {}) {
|
|
28
|
+
return function (env: RspackEnv): TReturn {
|
|
29
|
+
return func(options, {
|
|
30
|
+
cwd: process.cwd(),
|
|
31
|
+
isProduction: process.env.NODE_ENV === 'production',
|
|
32
|
+
isBuildMode: Boolean(env.RSPACK_BUILD),
|
|
33
|
+
isBundleMode: Boolean(env.RSPACK_BUNDLE),
|
|
34
|
+
isWatchMode: Boolean(env.RSPACK_WATCH),
|
|
35
|
+
isServeMode: Boolean(env.RSPACK_SERVE),
|
|
36
|
+
...context,
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const createNodeRspackConfig = createConfigBuilder<NodePresetOptions, RspackOptions>(
|
|
43
|
+
(options, context) => {
|
|
44
|
+
const presetOptions = getNodePresetDefaultOptions(options, context);
|
|
45
|
+
|
|
46
|
+
return mergeConfig(basePreset(presetOptions, context), nodePreset(presetOptions, context));
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
export const createReactRspackConfig = createConfigBuilder<ReactPresetOptions, RspackOptions>(
|
|
51
|
+
(options, context) => {
|
|
52
|
+
const presetOptions = getReactPresetDefaultOptions(options, context);
|
|
53
|
+
|
|
54
|
+
return mergeConfig(basePreset(presetOptions, context), reactPreset(presetOptions, context));
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
export const createFivemScriptRspackConfig = createConfigBuilder<
|
|
59
|
+
Omit<FivemScriptPresetOptions, 'entryFile' | 'outDir'>,
|
|
60
|
+
RspackOptions[]
|
|
61
|
+
>((options, context) => {
|
|
62
|
+
const createBuildPreset = (type: 'client' | 'server' | 'shared') => {
|
|
63
|
+
const entryFile = findFirstExistingFile(
|
|
64
|
+
[`src/${type}/index.ts`, `src/${type}.ts`, `src/${type}/index.js`, `src/${type}.js`],
|
|
65
|
+
context.cwd,
|
|
66
|
+
);
|
|
67
|
+
if (!entryFile) return null;
|
|
68
|
+
|
|
69
|
+
const presetOptions = getFivemScriptPresetDefaultOptions(
|
|
70
|
+
{
|
|
71
|
+
...options,
|
|
72
|
+
entryFile,
|
|
73
|
+
outDir: `dist/${type}`,
|
|
74
|
+
},
|
|
75
|
+
context,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return mergeConfig(
|
|
79
|
+
basePreset(presetOptions, context),
|
|
80
|
+
nodePreset(presetOptions, context),
|
|
81
|
+
fivemScriptPreset(presetOptions, context),
|
|
82
|
+
{ name: `fivem-${type}` },
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const configs: (RspackOptions | null)[] = [];
|
|
87
|
+
|
|
88
|
+
configs.push(createBuildPreset('client'));
|
|
89
|
+
configs.push(createBuildPreset('server'));
|
|
90
|
+
configs.push(createBuildPreset('shared'));
|
|
91
|
+
|
|
92
|
+
return configs.filter(Boolean) as RspackOptions[];
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
export const createFivemUiRspackConfig = createConfigBuilder<
|
|
96
|
+
Omit<FivemUiPresetOptions, 'entryFile' | 'outDir' | 'htmlTemplateFile'>,
|
|
97
|
+
RspackOptions
|
|
98
|
+
>((options, context) => {
|
|
99
|
+
const entryFile = findFirstExistingFile(
|
|
100
|
+
[
|
|
101
|
+
'src/ui/index.tsx',
|
|
102
|
+
'src/ui.tsx',
|
|
103
|
+
'src/ui/index.ts',
|
|
104
|
+
'src/ui.ts',
|
|
105
|
+
'src/ui/index.jsx',
|
|
106
|
+
'src/ui.jsx',
|
|
107
|
+
'src/ui/index.js',
|
|
108
|
+
'src/ui.js',
|
|
109
|
+
],
|
|
110
|
+
context.cwd,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const htmlTemplateFile = findFirstExistingFile(
|
|
114
|
+
['src/ui/index.html', 'src/ui.html', 'src/index.html'],
|
|
115
|
+
context.cwd,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
if (!entryFile || !htmlTemplateFile) return {};
|
|
119
|
+
|
|
120
|
+
const presetOptions = getFivemUiPresetDefaultOptions(
|
|
121
|
+
{
|
|
122
|
+
...options,
|
|
123
|
+
entryFile,
|
|
124
|
+
htmlTemplateFile,
|
|
125
|
+
outDir: 'dist/ui',
|
|
126
|
+
},
|
|
127
|
+
context,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return mergeConfig(
|
|
131
|
+
basePreset(presetOptions, context),
|
|
132
|
+
reactPreset(presetOptions, context),
|
|
133
|
+
fivemUiPreset(presetOptions, context),
|
|
134
|
+
{ name: 'fivem-ui' },
|
|
135
|
+
);
|
|
136
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type { RspackEnv, RunContext } from './types';
|
|
2
|
+
export * from './create-rspack-config';
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { rspack } from '@rspack/core';
|
|
4
|
+
import type { SwcLoaderOptions } from '@rspack/core';
|
|
5
|
+
|
|
6
|
+
import { TS_RULE_TEST } from '~/constants';
|
|
7
|
+
import type { GetPresetDefaultOptions, Preset } from '~/types';
|
|
8
|
+
|
|
9
|
+
export type BasePresetOptions = {
|
|
10
|
+
readonly entryFile: string;
|
|
11
|
+
readonly tsconfigFile: string;
|
|
12
|
+
readonly outDir: string;
|
|
13
|
+
readonly envVariables: Record<string, string | undefined>;
|
|
14
|
+
readonly useDecorators: boolean;
|
|
15
|
+
readonly watchIgnored: string[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const getBasePresetDefaultOptions: GetPresetDefaultOptions<BasePresetOptions> = (
|
|
19
|
+
options,
|
|
20
|
+
) => ({
|
|
21
|
+
entryFile: options.entryFile ?? 'src/index.js',
|
|
22
|
+
tsconfigFile: options.tsconfigFile ?? 'tsconfig.json',
|
|
23
|
+
outDir: options.outDir ?? 'dist',
|
|
24
|
+
envVariables: options.envVariables ?? {},
|
|
25
|
+
useDecorators: options.useDecorators ?? false,
|
|
26
|
+
watchIgnored: options.watchIgnored ?? [
|
|
27
|
+
'**/.git',
|
|
28
|
+
'**/.turbo',
|
|
29
|
+
'**/coverage',
|
|
30
|
+
'**/dist',
|
|
31
|
+
'**/generated',
|
|
32
|
+
'**/old',
|
|
33
|
+
'**/tmp',
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export const basePreset: Preset<BasePresetOptions> = (options, context) => ({
|
|
38
|
+
name: 'base-preset',
|
|
39
|
+
|
|
40
|
+
context: context.cwd,
|
|
41
|
+
mode: context.isProduction ? 'production' : 'development',
|
|
42
|
+
cache: !context.isProduction,
|
|
43
|
+
|
|
44
|
+
entry: { main: options.entryFile },
|
|
45
|
+
|
|
46
|
+
output: {
|
|
47
|
+
clean: true,
|
|
48
|
+
path: path.resolve(context.cwd, options.outDir),
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
resolve: {
|
|
52
|
+
tsConfig: path.resolve(context.cwd, options.tsconfigFile),
|
|
53
|
+
extensions: ['.ts', '...'],
|
|
54
|
+
extensionAlias: {
|
|
55
|
+
'.js': ['.ts', '.js'],
|
|
56
|
+
'.cts': ['.cts', '.js'],
|
|
57
|
+
'.mjs': ['.mts', '.mjs'],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
optimization: { minimize: context.isProduction },
|
|
62
|
+
|
|
63
|
+
module: {
|
|
64
|
+
rules: [
|
|
65
|
+
{
|
|
66
|
+
test: TS_RULE_TEST,
|
|
67
|
+
type: 'javascript/auto',
|
|
68
|
+
loader: 'builtin:swc-loader',
|
|
69
|
+
exclude: [/dist\//u, /node_modules\//u],
|
|
70
|
+
options: {
|
|
71
|
+
jsc: {
|
|
72
|
+
externalHelpers: false,
|
|
73
|
+
keepClassNames: true,
|
|
74
|
+
parser: {
|
|
75
|
+
syntax: 'typescript',
|
|
76
|
+
decorators: options.useDecorators,
|
|
77
|
+
},
|
|
78
|
+
transform: {
|
|
79
|
+
useDefineForClassFields: true,
|
|
80
|
+
legacyDecorator: options.useDecorators,
|
|
81
|
+
decoratorMetadata: options.useDecorators,
|
|
82
|
+
},
|
|
83
|
+
experimental: {
|
|
84
|
+
cacheRoot: path.resolve(context.cwd, 'node_modules/.cache/swc'),
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
} satisfies SwcLoaderOptions,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
experiments: {
|
|
93
|
+
cache: {
|
|
94
|
+
type: 'persistent',
|
|
95
|
+
storage: {
|
|
96
|
+
type: 'filesystem',
|
|
97
|
+
directory: path.resolve(context.cwd, 'node_modules/.cache/rspack'),
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
stats: {
|
|
103
|
+
preset: 'normal',
|
|
104
|
+
errorDetails: true,
|
|
105
|
+
colors: true,
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
watchOptions: {
|
|
109
|
+
aggregateTimeout: 200,
|
|
110
|
+
ignored: options.watchIgnored,
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
plugins: [new rspack.EnvironmentPlugin(options.envVariables)],
|
|
114
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import rspack from '@rspack/core';
|
|
2
|
+
|
|
3
|
+
import type { GetPresetDefaultOptions, Preset } from '~/types';
|
|
4
|
+
|
|
5
|
+
import { getNodePresetDefaultOptions } from './node-preset';
|
|
6
|
+
import type { NodePresetOptions } from './node-preset';
|
|
7
|
+
|
|
8
|
+
export type FivemScriptPresetOptions = NodePresetOptions;
|
|
9
|
+
|
|
10
|
+
export const getFivemScriptPresetDefaultOptions: GetPresetDefaultOptions<
|
|
11
|
+
FivemScriptPresetOptions
|
|
12
|
+
> = (options, context) => ({
|
|
13
|
+
...getNodePresetDefaultOptions(options, context),
|
|
14
|
+
nodeVersion: options.nodeVersion ?? 16,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const fivemScriptPreset: Preset<FivemScriptPresetOptions> = (options, context) => ({
|
|
18
|
+
name: 'fivem-script-preset',
|
|
19
|
+
|
|
20
|
+
devtool: false,
|
|
21
|
+
|
|
22
|
+
externals: [],
|
|
23
|
+
|
|
24
|
+
optimization: { minimize: context.isProduction },
|
|
25
|
+
|
|
26
|
+
plugins: [new rspack.EnvironmentPlugin(options.envVariables)],
|
|
27
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import type { GetPresetDefaultOptions, Preset } from '~/types';
|
|
4
|
+
|
|
5
|
+
import type { ReactPresetOptions } from './react-preset';
|
|
6
|
+
import { getReactPresetDefaultOptions } from './react-preset';
|
|
7
|
+
|
|
8
|
+
export type FivemUiPresetOptions = ReactPresetOptions & {
|
|
9
|
+
readonly resourceName: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const getFivemUiPresetDefaultOptions: GetPresetDefaultOptions<FivemUiPresetOptions> = (
|
|
13
|
+
options,
|
|
14
|
+
context,
|
|
15
|
+
) => {
|
|
16
|
+
const resourceName = options.resourceName ?? path.basename(context.cwd);
|
|
17
|
+
const reactPresetOptions = getReactPresetDefaultOptions(options, context);
|
|
18
|
+
return {
|
|
19
|
+
...reactPresetOptions,
|
|
20
|
+
resourceName,
|
|
21
|
+
publicUrl:
|
|
22
|
+
options.publicUrl
|
|
23
|
+
?? (context.isServeMode ? 'http://localhost:8080/' : (
|
|
24
|
+
`https://cfx-nui-${resourceName}/${reactPresetOptions.outDir}/`
|
|
25
|
+
)),
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const fivemUiPreset: Preset<FivemUiPresetOptions> = (_options, context) => ({
|
|
30
|
+
name: 'fivem-ui-preset',
|
|
31
|
+
|
|
32
|
+
...(context.isProduction ? { devtool: false } : {}),
|
|
33
|
+
|
|
34
|
+
output: { filename: '[name].js' },
|
|
35
|
+
|
|
36
|
+
devServer: {
|
|
37
|
+
devMiddleware: {
|
|
38
|
+
writeToDisk: true,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { rspack } from '@rspack/core';
|
|
2
|
+
import type { ExternalItem, SwcLoaderOptions } from '@rspack/core';
|
|
3
|
+
import { RunScriptWebpackPlugin } from 'run-script-webpack-plugin';
|
|
4
|
+
import nodeExternals from 'webpack-node-externals';
|
|
5
|
+
|
|
6
|
+
import { TS_RULE_TEST } from '~/constants';
|
|
7
|
+
import type { GetPresetDefaultOptions, Preset } from '~/types';
|
|
8
|
+
|
|
9
|
+
import { getBasePresetDefaultOptions } from './base-preset';
|
|
10
|
+
import type { BasePresetOptions } from './base-preset';
|
|
11
|
+
|
|
12
|
+
export type NodePresetOptions = BasePresetOptions & {
|
|
13
|
+
readonly nodeVersion: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const getNodePresetDefaultOptions: GetPresetDefaultOptions<NodePresetOptions> = (
|
|
17
|
+
options,
|
|
18
|
+
context,
|
|
19
|
+
) => ({
|
|
20
|
+
...getBasePresetDefaultOptions(options, context),
|
|
21
|
+
nodeVersion: options.nodeVersion ?? 24,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const nodePreset: Preset<NodePresetOptions> = (options, context) => ({
|
|
25
|
+
name: 'node-preset',
|
|
26
|
+
|
|
27
|
+
target: `node${options.nodeVersion}`,
|
|
28
|
+
|
|
29
|
+
entry: {
|
|
30
|
+
main: [...(context.isServeMode ? ['@rspack/core/hot/poll?100'] : []), options.entryFile],
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
externalsPresets: { node: true },
|
|
34
|
+
externalsType: 'commonjs',
|
|
35
|
+
externals: [
|
|
36
|
+
nodeExternals(
|
|
37
|
+
context.isServeMode ? { allowlist: ['@rspack/core/hot/poll?100'] } : undefined,
|
|
38
|
+
) as ExternalItem,
|
|
39
|
+
],
|
|
40
|
+
|
|
41
|
+
optimization: { minimize: false },
|
|
42
|
+
|
|
43
|
+
module: {
|
|
44
|
+
rules: [
|
|
45
|
+
{
|
|
46
|
+
test: TS_RULE_TEST,
|
|
47
|
+
loader: 'builtin:swc-loader',
|
|
48
|
+
options: {
|
|
49
|
+
env: { targets: `node ${options.nodeVersion}` },
|
|
50
|
+
} satisfies SwcLoaderOptions,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
devServer: {
|
|
56
|
+
devMiddleware: {
|
|
57
|
+
writeToDisk: true,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
plugins: [
|
|
62
|
+
new rspack.EnvironmentPlugin(options.envVariables),
|
|
63
|
+
context.isServeMode && new RunScriptWebpackPlugin({ name: 'main.js', autoRestart: false }),
|
|
64
|
+
],
|
|
65
|
+
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { rspack } from '@rspack/core';
|
|
5
|
+
import type { SwcLoaderOptions } from '@rspack/core';
|
|
6
|
+
import ReactRefreshPlugin from '@rspack/plugin-react-refresh';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
ASSET_RULE_TEST,
|
|
10
|
+
CSS_RULE_TEST,
|
|
11
|
+
HASHED_JS_FILENAME_PATTERN,
|
|
12
|
+
TS_RULE_TEST,
|
|
13
|
+
} from '~/constants';
|
|
14
|
+
import type { GetPresetDefaultOptions, Preset } from '~/types';
|
|
15
|
+
|
|
16
|
+
import { getBasePresetDefaultOptions } from './base-preset';
|
|
17
|
+
import type { BasePresetOptions } from './base-preset';
|
|
18
|
+
|
|
19
|
+
const require = createRequire(import.meta.url);
|
|
20
|
+
|
|
21
|
+
export type ReactPresetOptions = BasePresetOptions & {
|
|
22
|
+
readonly htmlTemplateFile: string;
|
|
23
|
+
readonly browserlist: string;
|
|
24
|
+
readonly publicUrl: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const getReactPresetDefaultOptions: GetPresetDefaultOptions<ReactPresetOptions> = (
|
|
28
|
+
options,
|
|
29
|
+
context,
|
|
30
|
+
) => ({
|
|
31
|
+
...getBasePresetDefaultOptions(options, context),
|
|
32
|
+
htmlTemplateFile: options.htmlTemplateFile ?? 'src/index.html',
|
|
33
|
+
browserlist: options.browserlist ?? 'defaults',
|
|
34
|
+
publicUrl: options.publicUrl ?? 'http://localhost:8080/',
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export const reactPreset: Preset<ReactPresetOptions> = (options, context) => {
|
|
38
|
+
const publicUrl = new URL(options.publicUrl);
|
|
39
|
+
if (!publicUrl.pathname.endsWith('/')) publicUrl.pathname += '/';
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
name: 'react-preset',
|
|
43
|
+
|
|
44
|
+
target: `browserslist:${options.browserlist}`,
|
|
45
|
+
|
|
46
|
+
output: {
|
|
47
|
+
filename: context.isProduction ? HASHED_JS_FILENAME_PATTERN : '[name].js',
|
|
48
|
+
publicPath: publicUrl.toString(),
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
resolve: {
|
|
52
|
+
extensions: ['.tsx', '.ts', '.jsx', '...'],
|
|
53
|
+
extensionAlias: {
|
|
54
|
+
'.js': ['.tsx', '.ts', '.jsx', '.js'],
|
|
55
|
+
'.cts': ['.ctsx', '.cts', '.cjsx', '.js'],
|
|
56
|
+
'.mjs': ['.mtsx', '.mts', '.mjsx', '.mjs'],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
externalsPresets: { web: true },
|
|
61
|
+
|
|
62
|
+
module: {
|
|
63
|
+
rules: [
|
|
64
|
+
{
|
|
65
|
+
test: TS_RULE_TEST,
|
|
66
|
+
loader: 'builtin:swc-loader',
|
|
67
|
+
options: {
|
|
68
|
+
env: { targets: options.browserlist },
|
|
69
|
+
jsc: {
|
|
70
|
+
parser: {
|
|
71
|
+
syntax: 'typescript',
|
|
72
|
+
tsx: true,
|
|
73
|
+
},
|
|
74
|
+
transform: {
|
|
75
|
+
react: {
|
|
76
|
+
runtime: 'automatic',
|
|
77
|
+
throwIfNamespace: true,
|
|
78
|
+
useBuiltins: false,
|
|
79
|
+
development: !context.isProduction,
|
|
80
|
+
refresh: context.isServeMode,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
} satisfies SwcLoaderOptions,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
test: ASSET_RULE_TEST,
|
|
88
|
+
type: 'asset/resource',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
test: CSS_RULE_TEST,
|
|
92
|
+
type: 'css',
|
|
93
|
+
use: [
|
|
94
|
+
{
|
|
95
|
+
loader: require.resolve('postcss-loader'),
|
|
96
|
+
options: {
|
|
97
|
+
implementation: require.resolve('postcss'),
|
|
98
|
+
postcssOptions: {
|
|
99
|
+
plugins: [
|
|
100
|
+
[
|
|
101
|
+
require.resolve('@tailwindcss/postcss'),
|
|
102
|
+
{ optimize: context.isProduction },
|
|
103
|
+
],
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
devServer: {
|
|
114
|
+
host: publicUrl.hostname || undefined,
|
|
115
|
+
port: publicUrl.port || undefined,
|
|
116
|
+
historyApiFallback: true,
|
|
117
|
+
hot: 'only',
|
|
118
|
+
headers: {
|
|
119
|
+
'Access-Control-Allow-Origin': '*',
|
|
120
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
|
121
|
+
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
experiments: { css: true },
|
|
126
|
+
|
|
127
|
+
plugins: [
|
|
128
|
+
new rspack.EnvironmentPlugin({
|
|
129
|
+
...options.envVariables,
|
|
130
|
+
PUBLIC_URL: publicUrl.toString(),
|
|
131
|
+
}),
|
|
132
|
+
new rspack.HtmlRspackPlugin({
|
|
133
|
+
template: path.resolve(context.cwd, options.htmlTemplateFile),
|
|
134
|
+
minify: context.isProduction,
|
|
135
|
+
}),
|
|
136
|
+
context.isServeMode && new ReactRefreshPlugin({ forceEnable: true }),
|
|
137
|
+
],
|
|
138
|
+
};
|
|
139
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RspackOptions } from '@rspack/core';
|
|
2
|
+
|
|
3
|
+
import type { RunContext } from './run-context';
|
|
4
|
+
|
|
5
|
+
export type GetPresetDefaultOptions<TPresetOptions> = (
|
|
6
|
+
options: Partial<TPresetOptions>,
|
|
7
|
+
context: RunContext,
|
|
8
|
+
) => TPresetOptions;
|
|
9
|
+
|
|
10
|
+
export type Preset<TPresetOptions> = (
|
|
11
|
+
presetOptions: TPresetOptions,
|
|
12
|
+
runContext: RunContext,
|
|
13
|
+
) => RspackOptions;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RspackOptions } from '@rspack/core';
|
|
2
|
+
import { mergeWithRules } from 'webpack-merge';
|
|
3
|
+
|
|
4
|
+
export const mergeConfig = mergeWithRules({
|
|
5
|
+
entry: 'replace',
|
|
6
|
+
externals: 'replace',
|
|
7
|
+
module: {
|
|
8
|
+
rules: {
|
|
9
|
+
test: 'match',
|
|
10
|
+
options: 'merge',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
plugins: 'replace',
|
|
14
|
+
}) as (...configs: RspackOptions[]) => RspackOptions;
|