Skip to content

Commit 70f4ba2

Browse files
authored
feat(angular-rspack,angular-rsbuild): add root option and improve tsConfig handling (#33)
1 parent c5dbe32 commit 70f4ba2

13 files changed

+106
-55
lines changed

e2e/fixtures/rspack-csr-css/rspack.config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
module.exports = () => {
22
if (global.NX_GRAPH_CREATION === undefined) {
3-
const { join } = require('path');
43
const { createConfig } = require('@nx/angular-rspack');
54
return createConfig(
65
{
76
options: {
7+
root: __dirname,
88
name: 'rspack-csr-css',
99
index: './src/index.html',
1010
assets: [{ glob: '**/*', input: 'public' }],
@@ -20,7 +20,7 @@ module.exports = () => {
2020
styles: true,
2121
},
2222
outputHashing: 'none',
23-
tsConfig: join(__dirname, './tsconfig.app.json'),
23+
tsConfig: './tsconfig.app.json',
2424
skipTypeChecking: false,
2525
devServer: {
2626
port: 8080,

eslint.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ module.exports = tseslint.config(
4545
'**/__snapshots__/**',
4646
'**/dist',
4747
'**/*.md',
48-
'e2e/fixtures/**/build',
48+
'**/build',
49+
'!packages/build',
4950
],
5051
}
5152
);

packages/angular-rsbuild/src/lib/config/create-config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export async function _createConfig(
8989
}
9090
}
9191

92-
const root = process.cwd();
92+
const { root } = normalizedOptions;
9393
const rsbuildPluginAngularConfig = defineConfig({
9494
root,
9595
source: {

packages/angular-rsbuild/src/lib/models/normalize-options.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ export function resolveFileReplacements(
2626
}));
2727
}
2828

29-
export function getHasServer({
30-
server,
31-
ssr,
32-
}: Pick<PluginAngularOptions, 'server' | 'ssr'>): boolean {
33-
const root = process.cwd();
29+
export function getHasServer(
30+
root: string,
31+
server: string | undefined,
32+
ssr: PluginAngularOptions['ssr']
33+
): boolean {
3434
return !!(
3535
server &&
3636
ssr &&
@@ -114,7 +114,7 @@ export const DEFAULT_PLUGIN_ANGULAR_OPTIONS: PluginAngularOptions = {
114114
export function normalizeOptions(
115115
options: Partial<PluginAngularOptions> = {}
116116
): NormalizedPluginAngularOptions {
117-
const root = process.cwd();
117+
const root = options.root ?? process.cwd();
118118
const {
119119
fileReplacements = [],
120120
server,
@@ -139,6 +139,9 @@ export function normalizeOptions(
139139
const normalizedOptimization = optimization !== false; // @TODO: Add support for optimization options
140140
const aot = options.aot ?? true;
141141
const advancedOptimizations = aot && normalizedOptimization;
142+
const tsConfig = options.tsConfig
143+
? resolve(root, options.tsConfig)
144+
: join(root, 'tsconfig.app.json');
142145

143146
validateChunkOptions(options);
144147

@@ -155,8 +158,10 @@ export function normalizeOptions(
155158
outputHashing: options.outputHashing ?? 'all',
156159
namedChunks: options.namedChunks ?? false,
157160
fileReplacements: resolveFileReplacements(fileReplacements, root),
158-
hasServer: getHasServer({ server, ssr: normalizedSsr }),
161+
hasServer: getHasServer(root, server, normalizedSsr),
159162
devServer: normalizeDevServer(devServer),
163+
root,
164+
tsConfig,
160165
};
161166
}
162167

packages/angular-rsbuild/src/lib/models/normalize-options.unit.test.ts

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { MEMFS_VOLUME } from '@ng-rspack/testing-utils';
2+
import { vol } from 'memfs';
3+
import { join } from 'node:path';
14
import { describe, expect } from 'vitest';
25
import {
36
DEFAULT_PLUGIN_ANGULAR_OPTIONS,
@@ -6,9 +9,6 @@ import {
69
normalizeOutputPath,
710
resolveFileReplacements,
811
} from './normalize-options.ts';
9-
import { vol } from 'memfs';
10-
11-
import { MEMFS_VOLUME } from '@ng-rspack/testing-utils';
1212
import { PluginAngularOptions } from './plugin-options';
1313

1414
describe('resolveFileReplacements', () => {
@@ -60,58 +60,52 @@ describe('getHasServer', () => {
6060
});
6161

6262
it('should return true if both server and ssr.entry files exist', () => {
63-
const result = getHasServer({
64-
server: 'server.js',
65-
ssr: { entry: 'ssr-entry.js' },
63+
const result = getHasServer(process.cwd(), 'server.js', {
64+
entry: 'ssr-entry.js',
6665
});
6766

6867
expect(result).toBe(true);
6968
});
7069

7170
it('should return false if server file is not provides', () => {
72-
const result = getHasServer({
73-
ssr: { entry: 'ssr-entry.js' },
71+
const result = getHasServer(process.cwd(), undefined, {
72+
entry: 'ssr-entry.js',
7473
});
7574

7675
expect(result).toBe(false);
7776
});
7877

7978
it('should return false if ssr.entry file is not provides', () => {
80-
const result = getHasServer({
81-
server: 'server.js',
82-
});
79+
const result = getHasServer(process.cwd(), 'server.js', undefined);
8380

8481
expect(result).toBe(false);
8582
});
8683

8784
it('should return false if neither file are not provides', () => {
88-
const result = getHasServer({});
85+
const result = getHasServer(process.cwd(), undefined, undefined);
8986

9087
expect(result).toBe(false);
9188
});
9289

9390
it('should return false if server file does not exist', () => {
94-
const result = getHasServer({
95-
server: 'non-existing-server.js',
96-
ssr: { entry: 'ssr-entry.js' },
91+
const result = getHasServer(process.cwd(), 'non-existing-server.js', {
92+
entry: 'ssr-entry.js',
9793
});
9894

9995
expect(result).toBe(false);
10096
});
10197

10298
it('should return false if ssr.entry file does not exist', () => {
103-
const result = getHasServer({
104-
server: 'server.js',
105-
ssr: { entry: 'non-existing-ssr-entry.js' },
99+
const result = getHasServer(process.cwd(), 'server.js', {
100+
entry: 'non-existing-ssr-entry.js',
106101
});
107102

108103
expect(result).toBe(false);
109104
});
110105

111106
it('should return false if neither server nor ssr.entry exists', () => {
112-
const result = getHasServer({
113-
server: 'non-existing-server.js',
114-
ssr: { entry: 'non-existing-ssr-entry.js' },
107+
const result = getHasServer(process.cwd(), 'non-existing-server.js', {
108+
entry: 'non-existing-ssr-entry.js',
115109
});
116110

117111
expect(result).toBe(false);
@@ -140,6 +134,8 @@ describe('normalizeOptions', () => {
140134

141135
expect(result).toStrictEqual({
142136
...defaultOptions,
137+
root: process.cwd(),
138+
tsConfig: join(process.cwd(), 'tsconfig.app.json'),
143139
advancedOptimizations: true,
144140
});
145141
});
@@ -149,6 +145,8 @@ describe('normalizeOptions', () => {
149145

150146
expect(result).toStrictEqual({
151147
...defaultOptions,
148+
root: process.cwd(),
149+
tsConfig: join(process.cwd(), 'tsconfig.app.json'),
152150
advancedOptimizations: true,
153151
});
154152
});
@@ -158,6 +156,8 @@ describe('normalizeOptions', () => {
158156

159157
expect(result).toStrictEqual({
160158
...defaultOptions,
159+
root: process.cwd(),
160+
tsConfig: join(process.cwd(), 'tsconfig.app.json'),
161161
optimization: false,
162162
advancedOptimizations: false,
163163
});

packages/angular-rsbuild/src/lib/models/plugin-options.ts

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export interface PluginAngularOptions {
7070
vendorChunk?: boolean;
7171
stylePreprocessorOptions?: StylePreprocessorOptions;
7272
devServer?: DevServerOptions;
73+
root?: string;
7374
}
7475

7576
export interface NormalizedPluginAngularOptions extends PluginAngularOptions {
@@ -78,5 +79,6 @@ export interface NormalizedPluginAngularOptions extends PluginAngularOptions {
7879
optimization: boolean | OptimizationOptions;
7980
outputHashing: OutputHashing;
8081
outputPath: OutputPath;
82+
root: string;
8183
sourceMap: SourceMap;
8284
}

packages/angular-rsbuild/src/lib/plugin/plugin-hoisted-js-transformer.ts

+7-10
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,17 @@ import {
99
PartialMessage,
1010
} from '@nx/angular-rspack-compiler';
1111
import type { NormalizedPluginAngularOptions } from '../models/plugin-options';
12-
import { normalizeOptions } from '../models/normalize-options';
1312

1413
export const pluginHoistedJsTransformer = (
1514
options: NormalizedPluginAngularOptions
1615
): RsbuildPlugin => ({
1716
name: 'plugin-hoisted-js-transformer',
1817
post: ['plugin-angular'],
1918
setup(api) {
20-
const pluginOptions = normalizeOptions(options);
21-
const root = api.context.rootPath ?? process.cwd();
2219
const config = api.getRsbuildConfig();
2320
const typescriptFileCache = new Map<string, string | Uint8Array>();
2421
let watchMode = false;
25-
let isServer = pluginOptions.hasServer;
22+
let isServer = options.hasServer;
2623
const typeCheckResults: {
2724
errors: PartialMessage[] | undefined;
2825
warnings: PartialMessage[] | undefined;
@@ -34,13 +31,13 @@ export const pluginHoistedJsTransformer = (
3431
* where pluginOptions.sourcemap is set https://github.com/angular/angular-cli/blob/61d98fde122468978de9b17bd79761befdbf2fac/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts#L34
3532
*/
3633
sourcemap: !!(
37-
pluginOptions.sourceMap.scripts &&
38-
(pluginOptions.sourceMap.hidden ? 'external' : true)
34+
options.sourceMap.scripts &&
35+
(options.sourceMap.hidden ? 'external' : true)
3936
),
40-
thirdPartySourcemaps: pluginOptions.sourceMap.vendor,
37+
thirdPartySourcemaps: options.sourceMap.vendor,
4138
// @TODO: it should be `pluginOptions.advancedOptimizations` but it currently fails the build
4239
advancedOptimizations: false,
43-
jit: !pluginOptions.aot,
40+
jit: !options.aot,
4441
},
4542
maxWorkers()
4643
);
@@ -56,14 +53,14 @@ export const pluginHoistedJsTransformer = (
5653
api.onBeforeEnvironmentCompile(async () => {
5754
const parallelCompilation = await setupCompilationWithParallelCompilation(
5855
config,
59-
{ ...pluginOptions, root }
56+
{ ...options, root: options.root }
6057
);
6158
await buildAndAnalyzeWithParallelCompilation(
6259
parallelCompilation,
6360
typescriptFileCache,
6461
javascriptTransformer
6562
);
66-
if (!pluginOptions.skipTypeChecking) {
63+
if (!options.skipTypeChecking) {
6764
const { errors, warnings } = await parallelCompilation.diagnoseFiles(
6865
DiagnosticModes.All
6966
);

packages/angular-rspack/src/lib/config/create-config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export async function _createConfig(
8686
const normalizedOptions = normalizeOptions(options);
8787
const isProduction = process.env['NODE_ENV'] === 'production';
8888
const hashFormat = getOutputHashFormat(normalizedOptions.outputHashing);
89-
const root = process.cwd();
89+
const { root } = normalizedOptions;
9090

9191
const { sourceMapRules, sourceMapPlugins } = configureSourceMap(
9292
normalizedOptions.sourceMap

packages/angular-rspack/src/lib/config/create-config.unit.test.ts

+42-2
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,14 @@ describe('createConfig', () => {
8888
media: join(process.cwd(), 'dist', 'browser', 'media'),
8989
},
9090
index: expect.objectContaining({
91-
input: expect.stringMatching(/\/src\/index\.html$/),
91+
input: join(process.cwd(), 'src/index.html'),
9292
insertionOrder: [
9393
['polyfills', true],
9494
['main', true],
9595
],
9696
output: 'index.html',
9797
}),
98+
tsConfig: join(process.cwd(), 'tsconfig.base.json'),
9899
sourceMap: {
99100
scripts: true,
100101
styles: true,
@@ -117,6 +118,44 @@ describe('createConfig', () => {
117118
]);
118119
});
119120

121+
it('should create config from options with a custom root', async () => {
122+
const customRoot = join(process.cwd(), 'custom-root');
123+
124+
await expect(
125+
createConfig({
126+
options: { ...configBase, root: customRoot },
127+
})
128+
).resolves.toStrictEqual([
129+
expect.objectContaining({
130+
mode: 'development',
131+
devServer: expect.objectContaining({
132+
port: 4200,
133+
}),
134+
plugins: expect.arrayContaining([
135+
{
136+
pluginOptions: expect.objectContaining({
137+
outputPath: {
138+
base: join(customRoot, 'dist'),
139+
browser: join(customRoot, 'dist', 'browser'),
140+
server: join(customRoot, 'dist', 'server'),
141+
media: join(customRoot, 'dist', 'browser', 'media'),
142+
},
143+
index: expect.objectContaining({
144+
input: join(customRoot, 'src/index.html'),
145+
insertionOrder: [
146+
['polyfills', true],
147+
['main', true],
148+
],
149+
output: 'index.html',
150+
}),
151+
tsConfig: join(customRoot, 'tsconfig.base.json'),
152+
}),
153+
},
154+
]),
155+
}),
156+
]);
157+
});
158+
120159
it('should allow turning off optimizations', async () => {
121160
const { scripts, styles, ...rest } = configBase;
122161
await expect(
@@ -138,13 +177,14 @@ describe('createConfig', () => {
138177
media: join(process.cwd(), 'dist', 'browser', 'media'),
139178
},
140179
index: expect.objectContaining({
141-
input: expect.stringMatching(/\/src\/index\.html$/),
180+
input: join(process.cwd(), 'src/index.html'),
142181
insertionOrder: [
143182
['polyfills', true],
144183
['main', true],
145184
],
146185
output: 'index.html',
147186
}),
187+
tsConfig: join(process.cwd(), 'tsconfig.base.json'),
148188
sourceMap: {
149189
scripts: true,
150190
styles: true,

packages/angular-rspack/src/lib/models/angular-rspack-plugin-options.ts

+2
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export interface AngularRspackPluginOptions {
109109
commonChunk?: boolean;
110110
devServer?: DevServerOptions;
111111
extractLicenses?: boolean;
112+
root?: string;
112113
}
113114

114115
export interface NormalizedAngularRspackPluginOptions
@@ -126,5 +127,6 @@ export interface NormalizedAngularRspackPluginOptions
126127
optimization: boolean | OptimizationOptions;
127128
outputHashing: OutputHashing;
128129
outputPath: OutputPath;
130+
root: string;
129131
sourceMap: SourceMap;
130132
}

0 commit comments

Comments
 (0)