@jpp-toolkit/rspack-config 0.0.7 → 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 CHANGED
@@ -1,19 +1,55 @@
1
1
  import { RspackOptions } from "@rspack/core";
2
2
 
3
- //#region src/enums/environment.d.ts
4
- declare const Environment: {
5
- readonly DEVELOPMENT: "development";
6
- readonly PRODUCTION: "production";
3
+ //#region src/types/run-context.d.ts
4
+ type RunContext = {
5
+ readonly cwd: string;
6
+ readonly isProduction: boolean;
7
+ readonly isBuildMode: boolean;
8
+ readonly isBundleMode: boolean;
9
+ readonly isWatchMode: boolean;
10
+ readonly isServeMode: boolean;
7
11
  };
8
- type Environment = (typeof Environment)[keyof typeof Environment];
9
12
  //#endregion
10
- //#region src/create-fivem-rspack-config.d.ts
11
- type CreateFivemRspackConfigOptions = {
12
- readonly resourceName?: string | undefined;
13
- readonly environment?: Environment | undefined;
14
- readonly cwd?: string | undefined;
13
+ //#region src/types/rspack-env.d.ts
14
+ type RspackEnv = {
15
+ readonly RSPACK_WATCH?: boolean | undefined;
16
+ readonly RSPACK_BUILD?: boolean | undefined;
17
+ readonly RSPACK_BUNDLE?: boolean | undefined;
18
+ readonly RSPACK_SERVE?: boolean | undefined;
15
19
  };
16
- declare function createFivemRspackConfig(options?: CreateFivemRspackConfigOptions): RspackOptions[];
17
20
  //#endregion
18
- export { CreateFivemRspackConfigOptions, createFivemRspackConfig };
21
+ //#region src/presets/base-preset.d.ts
22
+ type BasePresetOptions = {
23
+ readonly entryFile: string;
24
+ readonly tsconfigFile: string;
25
+ readonly outDir: string;
26
+ readonly envVariables: Record<string, string | undefined>;
27
+ readonly useDecorators: boolean;
28
+ readonly watchIgnored: string[];
29
+ };
30
+ //#endregion
31
+ //#region src/presets/node-preset.d.ts
32
+ type NodePresetOptions = BasePresetOptions & {
33
+ readonly nodeVersion: number;
34
+ };
35
+ //#endregion
36
+ //#region src/presets/react-preset.d.ts
37
+ type ReactPresetOptions = BasePresetOptions & {
38
+ readonly htmlTemplateFile: string;
39
+ readonly browserlist: string;
40
+ readonly publicUrl: string;
41
+ };
42
+ //#endregion
43
+ //#region src/presets/fivem-ui-preset.d.ts
44
+ type FivemUiPresetOptions = ReactPresetOptions & {
45
+ readonly resourceName: string;
46
+ };
47
+ //#endregion
48
+ //#region src/create-rspack-config.d.ts
49
+ declare const createNodeRspackConfig: (options?: Partial<NodePresetOptions>, context?: Partial<RunContext>) => (env: RspackEnv) => RspackOptions;
50
+ declare const createReactRspackConfig: (options?: Partial<ReactPresetOptions>, context?: Partial<RunContext>) => (env: RspackEnv) => RspackOptions;
51
+ declare const createFivemScriptRspackConfig: (options?: Partial<Omit<NodePresetOptions, "entryFile" | "outDir">>, context?: Partial<RunContext>) => (env: RspackEnv) => RspackOptions[];
52
+ declare const createFivemUiRspackConfig: (options?: Partial<Omit<FivemUiPresetOptions, "entryFile" | "outDir" | "htmlTemplateFile">>, context?: Partial<RunContext>) => (env: RspackEnv) => RspackOptions;
53
+ //#endregion
54
+ export { type RspackEnv, type RunContext, createFivemScriptRspackConfig, createFivemUiRspackConfig, createNodeRspackConfig, createReactRspackConfig };
19
55
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,145 +1,356 @@
1
+ import { createRequire } from "node:module";
1
2
  import path from "node:path";
2
- import { rspack } from "@rspack/core";
3
- import { existsSync } from "node:fs";
3
+ import rspack, { rspack as rspack$1 } from "@rspack/core";
4
+ import { RunScriptWebpackPlugin } from "run-script-webpack-plugin";
5
+ import nodeExternals from "webpack-node-externals";
6
+ import ReactRefreshPlugin from "@rspack/plugin-react-refresh";
7
+ import fs from "node:fs";
8
+ import { mergeWithRules } from "webpack-merge";
4
9
 
5
- //#region src/enums/environment.ts
6
- const Environment = {
7
- DEVELOPMENT: "development",
8
- PRODUCTION: "production"
9
- };
10
+ //#region src/constants.ts
11
+ const TS_RULE_TEST = /\.(?:ts|tsx|cts|mts)$/iu;
12
+ const ASSET_RULE_TEST = /\.(?:jpe?g|png|gif|svg)$/iu;
13
+ const CSS_RULE_TEST = /\.css$/iu;
14
+ const HASHED_JS_FILENAME_PATTERN = "[name].[contenthash:8].js";
10
15
 
11
16
  //#endregion
12
- //#region src/enums/fivem-entry-type.ts
13
- const FivemEntryType = {
14
- CLIENT: "client",
15
- SERVER: "server",
16
- SHARED: "shared",
17
- UI: "ui"
18
- };
17
+ //#region src/presets/base-preset.ts
18
+ const getBasePresetDefaultOptions = (options) => ({
19
+ entryFile: options.entryFile ?? "src/index.js",
20
+ tsconfigFile: options.tsconfigFile ?? "tsconfig.json",
21
+ outDir: options.outDir ?? "dist",
22
+ envVariables: options.envVariables ?? {},
23
+ useDecorators: options.useDecorators ?? false,
24
+ watchIgnored: options.watchIgnored ?? [
25
+ "**/.git",
26
+ "**/.turbo",
27
+ "**/coverage",
28
+ "**/dist",
29
+ "**/generated",
30
+ "**/old",
31
+ "**/tmp"
32
+ ]
33
+ });
34
+ const basePreset = (options, context) => ({
35
+ name: "base-preset",
36
+ context: context.cwd,
37
+ mode: context.isProduction ? "production" : "development",
38
+ cache: !context.isProduction,
39
+ entry: { main: options.entryFile },
40
+ output: {
41
+ clean: true,
42
+ path: path.resolve(context.cwd, options.outDir)
43
+ },
44
+ resolve: {
45
+ tsConfig: path.resolve(context.cwd, options.tsconfigFile),
46
+ extensions: [".ts", "..."],
47
+ extensionAlias: {
48
+ ".js": [".ts", ".js"],
49
+ ".cts": [".cts", ".js"],
50
+ ".mjs": [".mts", ".mjs"]
51
+ }
52
+ },
53
+ optimization: { minimize: context.isProduction },
54
+ module: { rules: [{
55
+ test: TS_RULE_TEST,
56
+ type: "javascript/auto",
57
+ loader: "builtin:swc-loader",
58
+ exclude: [/dist\//u, /node_modules\//u],
59
+ options: { jsc: {
60
+ externalHelpers: false,
61
+ keepClassNames: true,
62
+ parser: {
63
+ syntax: "typescript",
64
+ decorators: options.useDecorators
65
+ },
66
+ transform: {
67
+ useDefineForClassFields: true,
68
+ legacyDecorator: options.useDecorators,
69
+ decoratorMetadata: options.useDecorators
70
+ },
71
+ experimental: { cacheRoot: path.resolve(context.cwd, "node_modules/.cache/swc") }
72
+ } }
73
+ }] },
74
+ experiments: { cache: {
75
+ type: "persistent",
76
+ storage: {
77
+ type: "filesystem",
78
+ directory: path.resolve(context.cwd, "node_modules/.cache/rspack")
79
+ }
80
+ } },
81
+ stats: {
82
+ preset: "normal",
83
+ errorDetails: true,
84
+ colors: true
85
+ },
86
+ watchOptions: {
87
+ aggregateTimeout: 200,
88
+ ignored: options.watchIgnored
89
+ },
90
+ plugins: [new rspack$1.EnvironmentPlugin(options.envVariables)]
91
+ });
19
92
 
20
93
  //#endregion
21
- //#region src/utils/find-first-existing-path.ts
22
- function findFirstExistingPath(possiblePaths) {
23
- for (const p of possiblePaths) if (existsSync(p)) return p;
24
- }
94
+ //#region src/presets/node-preset.ts
95
+ const getNodePresetDefaultOptions = (options, context) => ({
96
+ ...getBasePresetDefaultOptions(options, context),
97
+ nodeVersion: options.nodeVersion ?? 24
98
+ });
99
+ const nodePreset = (options, context) => ({
100
+ name: "node-preset",
101
+ target: `node${options.nodeVersion}`,
102
+ entry: { main: [...context.isServeMode ? ["@rspack/core/hot/poll?100"] : [], options.entryFile] },
103
+ externalsPresets: { node: true },
104
+ externalsType: "commonjs",
105
+ externals: [nodeExternals(context.isServeMode ? { allowlist: ["@rspack/core/hot/poll?100"] } : void 0)],
106
+ optimization: { minimize: false },
107
+ module: { rules: [{
108
+ test: TS_RULE_TEST,
109
+ loader: "builtin:swc-loader",
110
+ options: { env: { targets: `node ${options.nodeVersion}` } }
111
+ }] },
112
+ devServer: { devMiddleware: { writeToDisk: true } },
113
+ plugins: [new rspack$1.EnvironmentPlugin(options.envVariables), context.isServeMode && new RunScriptWebpackPlugin({
114
+ name: "main.js",
115
+ autoRestart: false
116
+ })]
117
+ });
25
118
 
26
119
  //#endregion
27
- //#region src/create-fivem-rspack-config.ts
28
- function buildConfig(options) {
29
- const { cwd, entry, entryType, resourceName, environment } = options;
30
- const htmlTemplateFile = findFirstExistingPath([path.resolve(cwd, `src/${entryType}/index.html`), path.resolve(cwd, `src/${entryType}.html`)]);
31
- const publicPath = `https://cfx-nui-${resourceName}/dist/${entryType}/`;
32
- const isProduction = environment === "production";
33
- const isUi = entryType === FivemEntryType.UI;
120
+ //#region src/presets/fivem-script-preset.ts
121
+ const getFivemScriptPresetDefaultOptions = (options, context) => ({
122
+ ...getNodePresetDefaultOptions(options, context),
123
+ nodeVersion: options.nodeVersion ?? 16
124
+ });
125
+ const fivemScriptPreset = (options, context) => ({
126
+ name: "fivem-script-preset",
127
+ devtool: false,
128
+ externals: [],
129
+ optimization: { minimize: context.isProduction },
130
+ plugins: [new rspack.EnvironmentPlugin(options.envVariables)]
131
+ });
132
+
133
+ //#endregion
134
+ //#region src/presets/react-preset.ts
135
+ const require = createRequire(import.meta.url);
136
+ const getReactPresetDefaultOptions = (options, context) => ({
137
+ ...getBasePresetDefaultOptions(options, context),
138
+ htmlTemplateFile: options.htmlTemplateFile ?? "src/index.html",
139
+ browserlist: options.browserlist ?? "defaults",
140
+ publicUrl: options.publicUrl ?? "http://localhost:8080/"
141
+ });
142
+ const reactPreset = (options, context) => {
143
+ const publicUrl = new URL(options.publicUrl);
144
+ if (!publicUrl.pathname.endsWith("/")) publicUrl.pathname += "/";
34
145
  return {
35
- name: `fivem-${entryType}`,
36
- context: cwd,
37
- target: isUi ? "web" : "node16",
38
- devtool: false,
39
- mode: environment,
40
- entry,
146
+ name: "react-preset",
147
+ target: `browserslist:${options.browserlist}`,
41
148
  output: {
42
- clean: true,
43
- path: path.resolve(cwd, "dist", entryType),
44
- ...isUi ? { publicPath } : {}
149
+ filename: context.isProduction ? HASHED_JS_FILENAME_PATTERN : "[name].js",
150
+ publicPath: publicUrl.toString()
45
151
  },
46
- optimization: { minimize: isProduction },
47
152
  resolve: {
48
153
  extensions: [
49
- ".js",
50
- ".jsx",
51
- ".ts",
52
154
  ".tsx",
53
- ".json",
54
- ".wasm"
155
+ ".ts",
156
+ ".jsx",
157
+ "..."
55
158
  ],
56
159
  extensionAlias: {
57
- ".js": [".ts", ".js"],
58
- ".cjs": [".cts", ".cjs"],
59
- ".mjs": [".mts", ".mjs"]
60
- },
61
- tsConfig: path.resolve(cwd, "tsconfig.json")
62
- },
63
- node: {
64
- global: isUi,
65
- __filename: isUi,
66
- __dirname: isUi
67
- },
68
- externalsPresets: {
69
- node: !isUi,
70
- web: isUi
160
+ ".js": [
161
+ ".tsx",
162
+ ".ts",
163
+ ".jsx",
164
+ ".js"
165
+ ],
166
+ ".cts": [
167
+ ".ctsx",
168
+ ".cts",
169
+ ".cjsx",
170
+ ".js"
171
+ ],
172
+ ".mjs": [
173
+ ".mtsx",
174
+ ".mts",
175
+ ".mjsx",
176
+ ".mjs"
177
+ ]
178
+ }
71
179
  },
72
- module: { rules: [{
73
- test: /\.(?:ts|tsx|cts|mts)$/iu,
74
- type: "javascript/auto",
75
- exclude: [/dist\//u, /node_modules\//u],
76
- loader: "builtin:swc-loader",
77
- options: {
78
- minify: isProduction,
79
- module: { type: "nodenext" },
80
- jsc: {
81
- target: isUi ? "es5" : "es2021",
82
- parser: {
83
- syntax: "typescript",
84
- tsx: true
85
- },
86
- transform: {
87
- react: { runtime: "automatic" },
88
- useDefineForClassFields: true
89
- },
90
- keepClassNames: true,
91
- externalHelpers: false
180
+ externalsPresets: { web: true },
181
+ module: { rules: [
182
+ {
183
+ test: TS_RULE_TEST,
184
+ loader: "builtin:swc-loader",
185
+ options: {
186
+ env: { targets: options.browserlist },
187
+ jsc: {
188
+ parser: {
189
+ syntax: "typescript",
190
+ tsx: true
191
+ },
192
+ transform: { react: {
193
+ runtime: "automatic",
194
+ throwIfNamespace: true,
195
+ useBuiltins: false,
196
+ development: !context.isProduction,
197
+ refresh: context.isServeMode
198
+ } }
199
+ }
92
200
  }
201
+ },
202
+ {
203
+ test: ASSET_RULE_TEST,
204
+ type: "asset/resource"
205
+ },
206
+ {
207
+ test: CSS_RULE_TEST,
208
+ type: "css",
209
+ use: [{
210
+ loader: require.resolve("postcss-loader"),
211
+ options: {
212
+ implementation: require.resolve("postcss"),
213
+ postcssOptions: { plugins: [[require.resolve("@tailwindcss/postcss"), { optimize: context.isProduction }]] }
214
+ }
215
+ }]
93
216
  }
94
- }, ...isUi ? [{
95
- test: /\.(?:jpe?g|png|gif|svg)$/iu,
96
- type: "asset/resource"
97
- }] : []] },
98
- ...isUi ? { experiments: { css: true } } : {},
99
- ...isUi && htmlTemplateFile ? { plugins: [new rspack.HtmlRspackPlugin({
100
- template: htmlTemplateFile,
101
- publicPath
102
- })] } : {},
103
- watchOptions: {
104
- aggregateTimeout: 200,
105
- ignored: [
106
- "**/.git",
107
- "**/.turbo",
108
- "**/coverage",
109
- "**/dist",
110
- "**/generated",
111
- "**/old",
112
- "**/tmp"
113
- ]
114
- }
217
+ ] },
218
+ devServer: {
219
+ host: publicUrl.hostname || void 0,
220
+ port: publicUrl.port || void 0,
221
+ historyApiFallback: true,
222
+ hot: "only",
223
+ headers: {
224
+ "Access-Control-Allow-Origin": "*",
225
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
226
+ "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
227
+ }
228
+ },
229
+ experiments: { css: true },
230
+ plugins: [
231
+ new rspack$1.EnvironmentPlugin({
232
+ ...options.envVariables,
233
+ PUBLIC_URL: publicUrl.toString()
234
+ }),
235
+ new rspack$1.HtmlRspackPlugin({
236
+ template: path.resolve(context.cwd, options.htmlTemplateFile),
237
+ minify: context.isProduction
238
+ }),
239
+ context.isServeMode && new ReactRefreshPlugin({ forceEnable: true })
240
+ ]
241
+ };
242
+ };
243
+
244
+ //#endregion
245
+ //#region src/presets/fivem-ui-preset.ts
246
+ const getFivemUiPresetDefaultOptions = (options, context) => {
247
+ const resourceName = options.resourceName ?? path.basename(context.cwd);
248
+ const reactPresetOptions = getReactPresetDefaultOptions(options, context);
249
+ return {
250
+ ...reactPresetOptions,
251
+ resourceName,
252
+ publicUrl: options.publicUrl ?? (context.isServeMode ? "http://localhost:8080/" : `https://cfx-nui-${resourceName}/${reactPresetOptions.outDir}/`)
115
253
  };
254
+ };
255
+ const fivemUiPreset = (_options, context) => ({
256
+ name: "fivem-ui-preset",
257
+ ...context.isProduction ? { devtool: false } : {},
258
+ output: { filename: "[name].js" },
259
+ devServer: { devMiddleware: { writeToDisk: true } }
260
+ });
261
+
262
+ //#endregion
263
+ //#region src/utils/find-first-existing-file.ts
264
+ function findFirstExistingFile(files, cwd) {
265
+ for (const file of files) if (fs.existsSync(path.resolve(cwd, file))) return file;
266
+ return null;
116
267
  }
117
- function createFivemRspackConfig(options = {}) {
118
- const environment = options.environment ?? (process.env.NODE_ENV === Environment.PRODUCTION ? Environment.PRODUCTION : Environment.DEVELOPMENT);
119
- const cwd = options.cwd ?? process.cwd();
120
- const resourceName = options.resourceName ?? path.basename(cwd);
121
- const configs = [];
122
- for (const entryType of Object.values(FivemEntryType)) {
123
- const entry = findFirstExistingPath([
124
- path.resolve(cwd, `src/${entryType}/index.tsx`),
125
- path.resolve(cwd, `src/${entryType}/index.ts`),
126
- path.resolve(cwd, `src/${entryType}.tsx`),
127
- path.resolve(cwd, `src/${entryType}.ts`)
128
- ]);
129
- if (!entry) continue;
130
- const config = buildConfig({
131
- cwd,
132
- entry,
133
- entryType,
134
- environment,
135
- resourceName
136
- });
137
- configs.push(config);
138
- }
139
- if (configs.length === 0) throw new Error("No valid FiveM resource entries found.");
140
- return configs;
268
+
269
+ //#endregion
270
+ //#region src/utils/merge-config.ts
271
+ const mergeConfig = mergeWithRules({
272
+ entry: "replace",
273
+ externals: "replace",
274
+ module: { rules: {
275
+ test: "match",
276
+ options: "merge"
277
+ } },
278
+ plugins: "replace"
279
+ });
280
+
281
+ //#endregion
282
+ //#region src/create-rspack-config.ts
283
+ function createConfigBuilder(func) {
284
+ return function(options = {}, context = {}) {
285
+ return function(env) {
286
+ return func(options, {
287
+ cwd: process.cwd(),
288
+ isProduction: process.env.NODE_ENV === "production",
289
+ isBuildMode: Boolean(env.RSPACK_BUILD),
290
+ isBundleMode: Boolean(env.RSPACK_BUNDLE),
291
+ isWatchMode: Boolean(env.RSPACK_WATCH),
292
+ isServeMode: Boolean(env.RSPACK_SERVE),
293
+ ...context
294
+ });
295
+ };
296
+ };
141
297
  }
298
+ const createNodeRspackConfig = createConfigBuilder((options, context) => {
299
+ const presetOptions = getNodePresetDefaultOptions(options, context);
300
+ return mergeConfig(basePreset(presetOptions, context), nodePreset(presetOptions, context));
301
+ });
302
+ const createReactRspackConfig = createConfigBuilder((options, context) => {
303
+ const presetOptions = getReactPresetDefaultOptions(options, context);
304
+ return mergeConfig(basePreset(presetOptions, context), reactPreset(presetOptions, context));
305
+ });
306
+ const createFivemScriptRspackConfig = createConfigBuilder((options, context) => {
307
+ const createBuildPreset = (type) => {
308
+ const entryFile = findFirstExistingFile([
309
+ `src/${type}/index.ts`,
310
+ `src/${type}.ts`,
311
+ `src/${type}/index.js`,
312
+ `src/${type}.js`
313
+ ], context.cwd);
314
+ if (!entryFile) return null;
315
+ const presetOptions = getFivemScriptPresetDefaultOptions({
316
+ ...options,
317
+ entryFile,
318
+ outDir: `dist/${type}`
319
+ }, context);
320
+ return mergeConfig(basePreset(presetOptions, context), nodePreset(presetOptions, context), fivemScriptPreset(presetOptions, context), { name: `fivem-${type}` });
321
+ };
322
+ const configs = [];
323
+ configs.push(createBuildPreset("client"));
324
+ configs.push(createBuildPreset("server"));
325
+ configs.push(createBuildPreset("shared"));
326
+ return configs.filter(Boolean);
327
+ });
328
+ const createFivemUiRspackConfig = createConfigBuilder((options, context) => {
329
+ const entryFile = findFirstExistingFile([
330
+ "src/ui/index.tsx",
331
+ "src/ui.tsx",
332
+ "src/ui/index.ts",
333
+ "src/ui.ts",
334
+ "src/ui/index.jsx",
335
+ "src/ui.jsx",
336
+ "src/ui/index.js",
337
+ "src/ui.js"
338
+ ], context.cwd);
339
+ const htmlTemplateFile = findFirstExistingFile([
340
+ "src/ui/index.html",
341
+ "src/ui.html",
342
+ "src/index.html"
343
+ ], context.cwd);
344
+ if (!entryFile || !htmlTemplateFile) return {};
345
+ const presetOptions = getFivemUiPresetDefaultOptions({
346
+ ...options,
347
+ entryFile,
348
+ htmlTemplateFile,
349
+ outDir: "dist/ui"
350
+ }, context);
351
+ return mergeConfig(basePreset(presetOptions, context), reactPreset(presetOptions, context), fivemUiPreset(presetOptions, context), { name: "fivem-ui" });
352
+ });
142
353
 
143
354
  //#endregion
144
- export { createFivemRspackConfig };
355
+ export { createFivemScriptRspackConfig, createFivemUiRspackConfig, createNodeRspackConfig, createReactRspackConfig };
145
356
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["configs: RspackOptions[]"],"sources":["../src/enums/environment.ts","../src/enums/fivem-entry-type.ts","../src/utils/find-first-existing-path.ts","../src/create-fivem-rspack-config.ts"],"sourcesContent":["export const Environment = {\n DEVELOPMENT: 'development',\n PRODUCTION: 'production',\n} as const;\nexport type Environment = (typeof Environment)[keyof typeof Environment];\n","export const FivemEntryType = {\n CLIENT: 'client',\n SERVER: 'server',\n SHARED: 'shared',\n UI: 'ui',\n} as const;\nexport type FivemEntryType = (typeof FivemEntryType)[keyof typeof FivemEntryType];\n","import { existsSync } from 'node:fs';\n\nexport function findFirstExistingPath(possiblePaths: string[]): string | undefined {\n for (const p of possiblePaths) if (existsSync(p)) return p;\n return undefined;\n}\n","import path from 'node:path';\n\nimport { rspack } from '@rspack/core';\nimport type { RspackOptions } from '@rspack/core';\n\nimport { Environment, FivemEntryType } from './enums';\nimport { findFirstExistingPath } from './utils/find-first-existing-path';\n\ntype BuildConfigOptions = {\n readonly cwd: string;\n readonly entry: string;\n readonly entryType: FivemEntryType;\n readonly resourceName: string;\n readonly environment: Environment;\n};\n\nfunction buildConfig(options: BuildConfigOptions): RspackOptions {\n const { cwd, entry, entryType, resourceName, environment } = options;\n\n const htmlTemplateFile = findFirstExistingPath([\n path.resolve(cwd, `src/${entryType}/index.html`),\n path.resolve(cwd, `src/${entryType}.html`),\n ]);\n const publicPath = `https://cfx-nui-${resourceName}/dist/${entryType}/`;\n\n const isProduction = environment === 'production';\n const isUi = entryType === FivemEntryType.UI;\n\n const config: RspackOptions = {\n name: `fivem-${entryType}`,\n\n context: cwd,\n\n target: isUi ? 'web' : 'node16',\n devtool: false,\n mode: environment,\n\n entry,\n\n output: {\n clean: true,\n path: path.resolve(cwd, 'dist', entryType),\n ...(isUi ? { publicPath } : {}),\n },\n\n optimization: {\n minimize: isProduction,\n },\n\n resolve: {\n extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.wasm'],\n extensionAlias: {\n '.js': ['.ts', '.js'],\n '.cjs': ['.cts', '.cjs'],\n '.mjs': ['.mts', '.mjs'],\n },\n tsConfig: path.resolve(cwd, 'tsconfig.json'),\n },\n\n node: {\n global: isUi,\n __filename: isUi,\n __dirname: isUi,\n },\n\n externalsPresets: {\n node: !isUi,\n web: isUi,\n },\n\n module: {\n rules: [\n {\n test: /\\.(?:ts|tsx|cts|mts)$/iu,\n type: 'javascript/auto',\n exclude: [/dist\\//u, /node_modules\\//u],\n loader: 'builtin:swc-loader',\n options: {\n minify: isProduction,\n module: { type: 'nodenext' },\n jsc: {\n target: isUi ? 'es5' : 'es2021',\n parser: {\n syntax: 'typescript',\n tsx: true,\n },\n transform: {\n react: { runtime: 'automatic' },\n useDefineForClassFields: true,\n },\n keepClassNames: true,\n externalHelpers: false,\n },\n },\n },\n ...(isUi ?\n [\n {\n test: /\\.(?:jpe?g|png|gif|svg)$/iu,\n type: 'asset/resource',\n },\n ]\n : []),\n ],\n },\n\n ...(isUi ? { experiments: { css: true } } : {}),\n\n ...(isUi && htmlTemplateFile ?\n { plugins: [new rspack.HtmlRspackPlugin({ template: htmlTemplateFile, publicPath })] }\n : {}),\n\n watchOptions: {\n aggregateTimeout: 200,\n ignored: [\n '**/.git',\n '**/.turbo',\n '**/coverage',\n '**/dist',\n '**/generated',\n '**/old',\n '**/tmp',\n ],\n },\n };\n\n return config;\n}\n\nexport type CreateFivemRspackConfigOptions = {\n readonly resourceName?: string | undefined;\n readonly environment?: Environment | undefined;\n readonly cwd?: string | undefined;\n};\n\nexport function createFivemRspackConfig(\n options: CreateFivemRspackConfigOptions = {},\n): RspackOptions[] {\n const environment =\n options.environment\n ?? (process.env.NODE_ENV === Environment.PRODUCTION ?\n Environment.PRODUCTION\n : Environment.DEVELOPMENT);\n const cwd = options.cwd ?? process.cwd();\n const resourceName = options.resourceName ?? path.basename(cwd);\n\n const configs: RspackOptions[] = [];\n\n for (const entryType of Object.values(FivemEntryType)) {\n const entry = findFirstExistingPath([\n path.resolve(cwd, `src/${entryType}/index.tsx`),\n path.resolve(cwd, `src/${entryType}/index.ts`),\n path.resolve(cwd, `src/${entryType}.tsx`),\n path.resolve(cwd, `src/${entryType}.ts`),\n ]);\n\n if (!entry) continue;\n\n const config = buildConfig({ cwd, entry, entryType, environment, resourceName });\n configs.push(config);\n }\n\n if (configs.length === 0) throw new Error('No valid FiveM resource entries found.');\n\n return configs;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["getBasePresetDefaultOptions: GetPresetDefaultOptions<BasePresetOptions>","basePreset: Preset<BasePresetOptions>","rspack","getNodePresetDefaultOptions: GetPresetDefaultOptions<NodePresetOptions>","nodePreset: Preset<NodePresetOptions>","rspack","getFivemScriptPresetDefaultOptions: GetPresetDefaultOptions<\n FivemScriptPresetOptions\n>","fivemScriptPreset: Preset<FivemScriptPresetOptions>","getReactPresetDefaultOptions: GetPresetDefaultOptions<ReactPresetOptions>","reactPreset: Preset<ReactPresetOptions>","rspack","getFivemUiPresetDefaultOptions: GetPresetDefaultOptions<FivemUiPresetOptions>","fivemUiPreset: Preset<FivemUiPresetOptions>","configs: (RspackOptions | null)[]"],"sources":["../src/constants.ts","../src/presets/base-preset.ts","../src/presets/node-preset.ts","../src/presets/fivem-script-preset.ts","../src/presets/react-preset.ts","../src/presets/fivem-ui-preset.ts","../src/utils/find-first-existing-file.ts","../src/utils/merge-config.ts","../src/create-rspack-config.ts"],"sourcesContent":["export const TS_RULE_TEST = /\\.(?:ts|tsx|cts|mts)$/iu;\nexport const ASSET_RULE_TEST = /\\.(?:jpe?g|png|gif|svg)$/iu;\nexport const CSS_RULE_TEST = /\\.css$/iu;\nexport const HASHED_JS_FILENAME_PATTERN = '[name].[contenthash:8].js';\n","import path from 'node:path';\n\nimport { rspack } from '@rspack/core';\nimport type { SwcLoaderOptions } from '@rspack/core';\n\nimport { TS_RULE_TEST } from '~/constants';\nimport type { GetPresetDefaultOptions, Preset } from '~/types';\n\nexport type BasePresetOptions = {\n readonly entryFile: string;\n readonly tsconfigFile: string;\n readonly outDir: string;\n readonly envVariables: Record<string, string | undefined>;\n readonly useDecorators: boolean;\n readonly watchIgnored: string[];\n};\n\nexport const getBasePresetDefaultOptions: GetPresetDefaultOptions<BasePresetOptions> = (\n options,\n) => ({\n entryFile: options.entryFile ?? 'src/index.js',\n tsconfigFile: options.tsconfigFile ?? 'tsconfig.json',\n outDir: options.outDir ?? 'dist',\n envVariables: options.envVariables ?? {},\n useDecorators: options.useDecorators ?? false,\n watchIgnored: options.watchIgnored ?? [\n '**/.git',\n '**/.turbo',\n '**/coverage',\n '**/dist',\n '**/generated',\n '**/old',\n '**/tmp',\n ],\n});\n\nexport const basePreset: Preset<BasePresetOptions> = (options, context) => ({\n name: 'base-preset',\n\n context: context.cwd,\n mode: context.isProduction ? 'production' : 'development',\n cache: !context.isProduction,\n\n entry: { main: options.entryFile },\n\n output: {\n clean: true,\n path: path.resolve(context.cwd, options.outDir),\n },\n\n resolve: {\n tsConfig: path.resolve(context.cwd, options.tsconfigFile),\n extensions: ['.ts', '...'],\n extensionAlias: {\n '.js': ['.ts', '.js'],\n '.cts': ['.cts', '.js'],\n '.mjs': ['.mts', '.mjs'],\n },\n },\n\n optimization: { minimize: context.isProduction },\n\n module: {\n rules: [\n {\n test: TS_RULE_TEST,\n type: 'javascript/auto',\n loader: 'builtin:swc-loader',\n exclude: [/dist\\//u, /node_modules\\//u],\n options: {\n jsc: {\n externalHelpers: false,\n keepClassNames: true,\n parser: {\n syntax: 'typescript',\n decorators: options.useDecorators,\n },\n transform: {\n useDefineForClassFields: true,\n legacyDecorator: options.useDecorators,\n decoratorMetadata: options.useDecorators,\n },\n experimental: {\n cacheRoot: path.resolve(context.cwd, 'node_modules/.cache/swc'),\n },\n },\n } satisfies SwcLoaderOptions,\n },\n ],\n },\n\n experiments: {\n cache: {\n type: 'persistent',\n storage: {\n type: 'filesystem',\n directory: path.resolve(context.cwd, 'node_modules/.cache/rspack'),\n },\n },\n },\n\n stats: {\n preset: 'normal',\n errorDetails: true,\n colors: true,\n },\n\n watchOptions: {\n aggregateTimeout: 200,\n ignored: options.watchIgnored,\n },\n\n plugins: [new rspack.EnvironmentPlugin(options.envVariables)],\n});\n","import { rspack } from '@rspack/core';\nimport type { ExternalItem, SwcLoaderOptions } from '@rspack/core';\nimport { RunScriptWebpackPlugin } from 'run-script-webpack-plugin';\nimport nodeExternals from 'webpack-node-externals';\n\nimport { TS_RULE_TEST } from '~/constants';\nimport type { GetPresetDefaultOptions, Preset } from '~/types';\n\nimport { getBasePresetDefaultOptions } from './base-preset';\nimport type { BasePresetOptions } from './base-preset';\n\nexport type NodePresetOptions = BasePresetOptions & {\n readonly nodeVersion: number;\n};\n\nexport const getNodePresetDefaultOptions: GetPresetDefaultOptions<NodePresetOptions> = (\n options,\n context,\n) => ({\n ...getBasePresetDefaultOptions(options, context),\n nodeVersion: options.nodeVersion ?? 24,\n});\n\nexport const nodePreset: Preset<NodePresetOptions> = (options, context) => ({\n name: 'node-preset',\n\n target: `node${options.nodeVersion}`,\n\n entry: {\n main: [...(context.isServeMode ? ['@rspack/core/hot/poll?100'] : []), options.entryFile],\n },\n\n externalsPresets: { node: true },\n externalsType: 'commonjs',\n externals: [\n nodeExternals(\n context.isServeMode ? { allowlist: ['@rspack/core/hot/poll?100'] } : undefined,\n ) as ExternalItem,\n ],\n\n optimization: { minimize: false },\n\n module: {\n rules: [\n {\n test: TS_RULE_TEST,\n loader: 'builtin:swc-loader',\n options: {\n env: { targets: `node ${options.nodeVersion}` },\n } satisfies SwcLoaderOptions,\n },\n ],\n },\n\n devServer: {\n devMiddleware: {\n writeToDisk: true,\n },\n },\n\n plugins: [\n new rspack.EnvironmentPlugin(options.envVariables),\n context.isServeMode && new RunScriptWebpackPlugin({ name: 'main.js', autoRestart: false }),\n ],\n});\n","import rspack from '@rspack/core';\n\nimport type { GetPresetDefaultOptions, Preset } from '~/types';\n\nimport { getNodePresetDefaultOptions } from './node-preset';\nimport type { NodePresetOptions } from './node-preset';\n\nexport type FivemScriptPresetOptions = NodePresetOptions;\n\nexport const getFivemScriptPresetDefaultOptions: GetPresetDefaultOptions<\n FivemScriptPresetOptions\n> = (options, context) => ({\n ...getNodePresetDefaultOptions(options, context),\n nodeVersion: options.nodeVersion ?? 16,\n});\n\nexport const fivemScriptPreset: Preset<FivemScriptPresetOptions> = (options, context) => ({\n name: 'fivem-script-preset',\n\n devtool: false,\n\n externals: [],\n\n optimization: { minimize: context.isProduction },\n\n plugins: [new rspack.EnvironmentPlugin(options.envVariables)],\n});\n","import { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport { rspack } from '@rspack/core';\nimport type { SwcLoaderOptions } from '@rspack/core';\nimport ReactRefreshPlugin from '@rspack/plugin-react-refresh';\n\nimport {\n ASSET_RULE_TEST,\n CSS_RULE_TEST,\n HASHED_JS_FILENAME_PATTERN,\n TS_RULE_TEST,\n} from '~/constants';\nimport type { GetPresetDefaultOptions, Preset } from '~/types';\n\nimport { getBasePresetDefaultOptions } from './base-preset';\nimport type { BasePresetOptions } from './base-preset';\n\nconst require = createRequire(import.meta.url);\n\nexport type ReactPresetOptions = BasePresetOptions & {\n readonly htmlTemplateFile: string;\n readonly browserlist: string;\n readonly publicUrl: string;\n};\n\nexport const getReactPresetDefaultOptions: GetPresetDefaultOptions<ReactPresetOptions> = (\n options,\n context,\n) => ({\n ...getBasePresetDefaultOptions(options, context),\n htmlTemplateFile: options.htmlTemplateFile ?? 'src/index.html',\n browserlist: options.browserlist ?? 'defaults',\n publicUrl: options.publicUrl ?? 'http://localhost:8080/',\n});\n\nexport const reactPreset: Preset<ReactPresetOptions> = (options, context) => {\n const publicUrl = new URL(options.publicUrl);\n if (!publicUrl.pathname.endsWith('/')) publicUrl.pathname += '/';\n\n return {\n name: 'react-preset',\n\n target: `browserslist:${options.browserlist}`,\n\n output: {\n filename: context.isProduction ? HASHED_JS_FILENAME_PATTERN : '[name].js',\n publicPath: publicUrl.toString(),\n },\n\n resolve: {\n extensions: ['.tsx', '.ts', '.jsx', '...'],\n extensionAlias: {\n '.js': ['.tsx', '.ts', '.jsx', '.js'],\n '.cts': ['.ctsx', '.cts', '.cjsx', '.js'],\n '.mjs': ['.mtsx', '.mts', '.mjsx', '.mjs'],\n },\n },\n\n externalsPresets: { web: true },\n\n module: {\n rules: [\n {\n test: TS_RULE_TEST,\n loader: 'builtin:swc-loader',\n options: {\n env: { targets: options.browserlist },\n jsc: {\n parser: {\n syntax: 'typescript',\n tsx: true,\n },\n transform: {\n react: {\n runtime: 'automatic',\n throwIfNamespace: true,\n useBuiltins: false,\n development: !context.isProduction,\n refresh: context.isServeMode,\n },\n },\n },\n } satisfies SwcLoaderOptions,\n },\n {\n test: ASSET_RULE_TEST,\n type: 'asset/resource',\n },\n {\n test: CSS_RULE_TEST,\n type: 'css',\n use: [\n {\n loader: require.resolve('postcss-loader'),\n options: {\n implementation: require.resolve('postcss'),\n postcssOptions: {\n plugins: [\n [\n require.resolve('@tailwindcss/postcss'),\n { optimize: context.isProduction },\n ],\n ],\n },\n },\n },\n ],\n },\n ],\n },\n\n devServer: {\n host: publicUrl.hostname || undefined,\n port: publicUrl.port || undefined,\n historyApiFallback: true,\n hot: 'only',\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',\n 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',\n },\n },\n\n experiments: { css: true },\n\n plugins: [\n new rspack.EnvironmentPlugin({\n ...options.envVariables,\n PUBLIC_URL: publicUrl.toString(),\n }),\n new rspack.HtmlRspackPlugin({\n template: path.resolve(context.cwd, options.htmlTemplateFile),\n minify: context.isProduction,\n }),\n context.isServeMode && new ReactRefreshPlugin({ forceEnable: true }),\n ],\n };\n};\n","import path from 'node:path';\n\nimport type { GetPresetDefaultOptions, Preset } from '~/types';\n\nimport type { ReactPresetOptions } from './react-preset';\nimport { getReactPresetDefaultOptions } from './react-preset';\n\nexport type FivemUiPresetOptions = ReactPresetOptions & {\n readonly resourceName: string;\n};\n\nexport const getFivemUiPresetDefaultOptions: GetPresetDefaultOptions<FivemUiPresetOptions> = (\n options,\n context,\n) => {\n const resourceName = options.resourceName ?? path.basename(context.cwd);\n const reactPresetOptions = getReactPresetDefaultOptions(options, context);\n return {\n ...reactPresetOptions,\n resourceName,\n publicUrl:\n options.publicUrl\n ?? (context.isServeMode ? 'http://localhost:8080/' : (\n `https://cfx-nui-${resourceName}/${reactPresetOptions.outDir}/`\n )),\n };\n};\n\nexport const fivemUiPreset: Preset<FivemUiPresetOptions> = (_options, context) => ({\n name: 'fivem-ui-preset',\n\n ...(context.isProduction ? { devtool: false } : {}),\n\n output: { filename: '[name].js' },\n\n devServer: {\n devMiddleware: {\n writeToDisk: true,\n },\n },\n});\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport function findFirstExistingFile(files: string[], cwd: string): string | null {\n for (const file of files) if (fs.existsSync(path.resolve(cwd, file))) return file;\n return null;\n}\n","import type { RspackOptions } from '@rspack/core';\nimport { mergeWithRules } from 'webpack-merge';\n\nexport const mergeConfig = mergeWithRules({\n entry: 'replace',\n externals: 'replace',\n module: {\n rules: {\n test: 'match',\n options: 'merge',\n },\n },\n plugins: 'replace',\n}) as (...configs: RspackOptions[]) => RspackOptions;\n","import type { RspackOptions } from '@rspack/core';\n\nimport {\n basePreset,\n fivemScriptPreset,\n fivemUiPreset,\n getFivemScriptPresetDefaultOptions,\n getFivemUiPresetDefaultOptions,\n getNodePresetDefaultOptions,\n getReactPresetDefaultOptions,\n nodePreset,\n reactPreset,\n} from './presets';\nimport type {\n FivemScriptPresetOptions,\n FivemUiPresetOptions,\n NodePresetOptions,\n ReactPresetOptions,\n} from './presets';\nimport type { RspackEnv, RunContext } from './types';\nimport { findFirstExistingFile } from './utils/find-first-existing-file';\nimport { mergeConfig } from './utils/merge-config';\n\nfunction createConfigBuilder<TOptions, TReturn extends RspackOptions | RspackOptions[]>(\n func: (options: Partial<TOptions>, context: RunContext) => TReturn,\n) {\n return function (options: Partial<TOptions> = {}, context: Partial<RunContext> = {}) {\n return function (env: RspackEnv): TReturn {\n return func(options, {\n cwd: process.cwd(),\n isProduction: process.env.NODE_ENV === 'production',\n isBuildMode: Boolean(env.RSPACK_BUILD),\n isBundleMode: Boolean(env.RSPACK_BUNDLE),\n isWatchMode: Boolean(env.RSPACK_WATCH),\n isServeMode: Boolean(env.RSPACK_SERVE),\n ...context,\n });\n };\n };\n}\n\nexport const createNodeRspackConfig = createConfigBuilder<NodePresetOptions, RspackOptions>(\n (options, context) => {\n const presetOptions = getNodePresetDefaultOptions(options, context);\n\n return mergeConfig(basePreset(presetOptions, context), nodePreset(presetOptions, context));\n },\n);\n\nexport const createReactRspackConfig = createConfigBuilder<ReactPresetOptions, RspackOptions>(\n (options, context) => {\n const presetOptions = getReactPresetDefaultOptions(options, context);\n\n return mergeConfig(basePreset(presetOptions, context), reactPreset(presetOptions, context));\n },\n);\n\nexport const createFivemScriptRspackConfig = createConfigBuilder<\n Omit<FivemScriptPresetOptions, 'entryFile' | 'outDir'>,\n RspackOptions[]\n>((options, context) => {\n const createBuildPreset = (type: 'client' | 'server' | 'shared') => {\n const entryFile = findFirstExistingFile(\n [`src/${type}/index.ts`, `src/${type}.ts`, `src/${type}/index.js`, `src/${type}.js`],\n context.cwd,\n );\n if (!entryFile) return null;\n\n const presetOptions = getFivemScriptPresetDefaultOptions(\n {\n ...options,\n entryFile,\n outDir: `dist/${type}`,\n },\n context,\n );\n\n return mergeConfig(\n basePreset(presetOptions, context),\n nodePreset(presetOptions, context),\n fivemScriptPreset(presetOptions, context),\n { name: `fivem-${type}` },\n );\n };\n\n const configs: (RspackOptions | null)[] = [];\n\n configs.push(createBuildPreset('client'));\n configs.push(createBuildPreset('server'));\n configs.push(createBuildPreset('shared'));\n\n return configs.filter(Boolean) as RspackOptions[];\n});\n\nexport const createFivemUiRspackConfig = createConfigBuilder<\n Omit<FivemUiPresetOptions, 'entryFile' | 'outDir' | 'htmlTemplateFile'>,\n RspackOptions\n>((options, context) => {\n const entryFile = findFirstExistingFile(\n [\n 'src/ui/index.tsx',\n 'src/ui.tsx',\n 'src/ui/index.ts',\n 'src/ui.ts',\n 'src/ui/index.jsx',\n 'src/ui.jsx',\n 'src/ui/index.js',\n 'src/ui.js',\n ],\n context.cwd,\n );\n\n const htmlTemplateFile = findFirstExistingFile(\n ['src/ui/index.html', 'src/ui.html', 'src/index.html'],\n context.cwd,\n );\n\n if (!entryFile || !htmlTemplateFile) return {};\n\n const presetOptions = getFivemUiPresetDefaultOptions(\n {\n ...options,\n entryFile,\n htmlTemplateFile,\n outDir: 'dist/ui',\n },\n context,\n );\n\n return mergeConfig(\n basePreset(presetOptions, context),\n reactPreset(presetOptions, context),\n fivemUiPreset(presetOptions, context),\n { name: 'fivem-ui' },\n );\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jpp-toolkit/rspack-config",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Rspack configurations for JS/TS projects.",
5
5
  "keywords": [
6
6
  "jpp",
@@ -31,7 +31,21 @@
31
31
  "src"
32
32
  ],
33
33
  "dependencies": {
34
- "@rspack/core": "1.6.8"
34
+ "@rspack/core": "1.6.8",
35
+ "@rspack/plugin-react-refresh": "1.5.3",
36
+ "@tailwindcss/postcss": "4.1.18",
37
+ "postcss": "8.5.6",
38
+ "postcss-loader": "8.2.0",
39
+ "react-refresh": "0.18.0",
40
+ "run-script-webpack-plugin": "0.2.3",
41
+ "tailwindcss": "4.1.18",
42
+ "webpack-merge": "6.0.1",
43
+ "webpack-node-externals": "3.0.0",
44
+ "@jpp-toolkit/logger": "0.0.16",
45
+ "@jpp-toolkit/utils": "0.0.16"
46
+ },
47
+ "devDependencies": {
48
+ "@types/webpack-node-externals": "3.0.4"
35
49
  },
36
50
  "engines": {
37
51
  "node": "24",