Skip to content

Commit 114d316

Browse files
committed
feat: config + compiler option for rspack, vite with fallback to webpack
1 parent c5620bd commit 114d316

File tree

1 file changed

+73
-56
lines changed

1 file changed

+73
-56
lines changed

lib/services/webpack/webpack-compiler-service.ts

+73-56
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
IOptions,
1717
} from "../../declarations";
1818
import { IPlatformData } from "../../definitions/platform";
19-
import { IProjectData } from "../../definitions/project";
19+
import { IProjectConfigService, IProjectData } from "../../definitions/project";
2020
import {
2121
IDictionary,
2222
IErrors,
@@ -64,15 +64,16 @@ export class WebpackCompilerService
6464
private $mobileHelper: Mobile.IMobileHelper,
6565
private $cleanupService: ICleanupService,
6666
private $packageManager: IPackageManager,
67-
private $packageInstallationManager: IPackageInstallationManager // private $sharedEventBus: ISharedEventBus
67+
private $packageInstallationManager: IPackageInstallationManager,
68+
private $projectConfigService: IProjectConfigService,
6869
) {
6970
super();
7071
}
7172

7273
public async compileWithWatch(
7374
platformData: IPlatformData,
7475
projectData: IProjectData,
75-
prepareData: IPrepareData
76+
prepareData: IPrepareData,
7677
): Promise<any> {
7778
return new Promise(async (resolve, reject) => {
7879
if (this.webpackProcesses[platformData.platformNameLowerCase]) {
@@ -86,7 +87,7 @@ export class WebpackCompilerService
8687
const childProcess = await this.startWebpackProcess(
8788
platformData,
8889
projectData,
89-
prepareData
90+
prepareData,
9091
);
9192

9293
childProcess.stdout.on("data", function (data) {
@@ -125,7 +126,7 @@ export class WebpackCompilerService
125126
message as IWebpackMessage<IWebpackCompilation>,
126127
platformData,
127128
projectData,
128-
prepareData
129+
prepareData,
129130
);
130131
}
131132

@@ -153,7 +154,7 @@ export class WebpackCompilerService
153154
message.emittedFiles,
154155
message.chunkFiles,
155156
message.hash,
156-
platformData.platformNameLowerCase
157+
platformData.platformNameLowerCase,
157158
);
158159
} else {
159160
result = {
@@ -166,21 +167,21 @@ export class WebpackCompilerService
166167
path.join(
167168
platformData.appDestinationDirectoryPath,
168169
this.$options.hostProjectModuleName,
169-
file
170-
)
170+
file,
171+
),
171172
);
172173
const fallbackFiles = result.fallbackFiles.map((file: string) =>
173174
path.join(
174175
platformData.appDestinationDirectoryPath,
175176
this.$options.hostProjectModuleName,
176-
file
177-
)
177+
file,
178+
),
178179
);
179180

180181
const data = {
181182
files,
182183
hasOnlyHotUpdateFiles: files.every(
183-
(f) => f.indexOf("hot-update") > -1
184+
(f) => f.indexOf("hot-update") > -1,
184185
),
185186
hmrData: {
186187
hash: result.hash,
@@ -204,23 +205,23 @@ export class WebpackCompilerService
204205

205206
childProcess.on("error", (err) => {
206207
this.$logger.trace(
207-
`Unable to start webpack process in watch mode. Error is: ${err}`
208+
`Unable to start webpack process in watch mode. Error is: ${err}`,
208209
);
209210
delete this.webpackProcesses[platformData.platformNameLowerCase];
210211
reject(err);
211212
});
212213

213214
childProcess.on("close", async (arg: any) => {
214215
await this.$cleanupService.removeKillProcess(
215-
childProcess.pid.toString()
216+
childProcess.pid.toString(),
216217
);
217218

218219
const exitCode = typeof arg === "number" ? arg : arg && arg.code;
219220
this.$logger.trace(
220-
`Webpack process exited with code ${exitCode} when we expected it to be long living with watch.`
221+
`Webpack process exited with code ${exitCode} when we expected it to be long living with watch.`,
221222
);
222223
const error: any = new Error(
223-
`Executing webpack failed with exit code ${exitCode}.`
224+
`Executing webpack failed with exit code ${exitCode}.`,
224225
);
225226
error.code = exitCode;
226227
delete this.webpackProcesses[platformData.platformNameLowerCase];
@@ -235,7 +236,7 @@ export class WebpackCompilerService
235236
public async compileWithoutWatch(
236237
platformData: IPlatformData,
237238
projectData: IProjectData,
238-
prepareData: IPrepareData
239+
prepareData: IPrepareData,
239240
): Promise<void> {
240241
return new Promise(async (resolve, reject) => {
241242
if (this.webpackProcesses[platformData.platformNameLowerCase]) {
@@ -247,20 +248,20 @@ export class WebpackCompilerService
247248
const childProcess = await this.startWebpackProcess(
248249
platformData,
249250
projectData,
250-
prepareData
251+
prepareData,
251252
);
252253

253254
childProcess.on("error", (err) => {
254255
this.$logger.trace(
255-
`Unable to start webpack process in non-watch mode. Error is: ${err}`
256+
`Unable to start webpack process in non-watch mode. Error is: ${err}`,
256257
);
257258
delete this.webpackProcesses[platformData.platformNameLowerCase];
258259
reject(err);
259260
});
260261

261262
childProcess.on("close", async (arg: any) => {
262263
await this.$cleanupService.removeKillProcess(
263-
childProcess.pid.toString()
264+
childProcess.pid.toString(),
264265
);
265266

266267
delete this.webpackProcesses[platformData.platformNameLowerCase];
@@ -269,7 +270,7 @@ export class WebpackCompilerService
269270
resolve();
270271
} else {
271272
const error: any = new Error(
272-
`Executing webpack failed with exit code ${exitCode}.`
273+
`Executing webpack failed with exit code ${exitCode}.`,
273274
);
274275
error.code = exitCode;
275276
reject(error);
@@ -307,24 +308,24 @@ export class WebpackCompilerService
307308
private async startWebpackProcess(
308309
platformData: IPlatformData,
309310
projectData: IProjectData,
310-
prepareData: IPrepareData
311+
prepareData: IPrepareData,
311312
): Promise<child_process.ChildProcess> {
312313
if (!this.$fs.exists(projectData.webpackConfigPath)) {
313314
this.$errors.fail(
314-
`The webpack configuration file ${projectData.webpackConfigPath} does not exist. Ensure the file exists, or update the path in ${CONFIG_FILE_NAME_DISPLAY}.`
315+
`The webpack configuration file ${projectData.webpackConfigPath} does not exist. Ensure the file exists, or update the path in ${CONFIG_FILE_NAME_DISPLAY}.`,
315316
);
316317
}
317318

318319
const envData = this.buildEnvData(
319320
platformData.platformNameLowerCase,
320321
projectData,
321-
prepareData
322+
prepareData,
322323
);
323324
const envParams = await this.buildEnvCommandLineParams(
324325
envData,
325326
platformData,
326327
projectData,
327-
prepareData
328+
prepareData,
328329
);
329330
const additionalNodeArgs =
330331
semver.major(process.version) <= 8 ? ["--harmony"] : [];
@@ -340,7 +341,7 @@ export class WebpackCompilerService
340341
const args = [
341342
...additionalNodeArgs,
342343
this.getWebpackExecutablePath(projectData),
343-
this.isWebpack5(projectData) ? `build` : null,
344+
this.isModernBundler(projectData) ? `build` : null,
344345
`--config=${projectData.webpackConfigPath}`,
345346
...envParams,
346347
].filter(Boolean);
@@ -372,7 +373,7 @@ export class WebpackCompilerService
372373
const childProcess = this.$childProcess.spawn(
373374
process.execPath,
374375
args,
375-
options
376+
options,
376377
);
377378

378379
this.webpackProcesses[platformData.platformNameLowerCase] = childProcess;
@@ -384,7 +385,7 @@ export class WebpackCompilerService
384385
private buildEnvData(
385386
platform: string,
386387
projectData: IProjectData,
387-
prepareData: IPrepareData
388+
prepareData: IPrepareData,
388389
) {
389390
const { env } = prepareData;
390391
const envData = Object.assign({}, env, { [platform.toLowerCase()]: true });
@@ -403,9 +404,9 @@ export class WebpackCompilerService
403404
__dirname,
404405
"..",
405406
"..",
406-
"nativescript-cli-lib.js"
407+
"nativescript-cli-lib.js",
407408
),
408-
}
409+
},
409410
);
410411

411412
envData.verbose = envData.verbose || this.$logger.isVerbose();
@@ -452,7 +453,7 @@ export class WebpackCompilerService
452453
envData: any,
453454
platformData: IPlatformData,
454455
projectData: IProjectData,
455-
prepareData: IPrepareData
456+
prepareData: IPrepareData,
456457
) {
457458
const envFlagNames = Object.keys(envData);
458459
const canSnapshot =
@@ -462,26 +463,26 @@ export class WebpackCompilerService
462463
if (!canSnapshot) {
463464
this.$logger.warn(
464465
"Stripping the snapshot flag. " +
465-
"Bear in mind that snapshot is only available in Android release builds."
466+
"Bear in mind that snapshot is only available in Android release builds.",
466467
);
467468
envFlagNames.splice(envFlagNames.indexOf("snapshot"), 1);
468469
} else if (this.$hostInfo.isWindows) {
469470
const minWebpackPluginWithWinSnapshotsVersion = "1.3.0";
470471
const installedWebpackPluginVersion =
471472
await this.$packageInstallationManager.getInstalledDependencyVersion(
472473
WEBPACK_PLUGIN_NAME,
473-
projectData.projectDir
474+
projectData.projectDir,
474475
);
475476
const hasWebpackPluginWithWinSnapshotsSupport =
476477
!!installedWebpackPluginVersion
477478
? semver.gte(
478479
semver.coerce(installedWebpackPluginVersion),
479-
minWebpackPluginWithWinSnapshotsVersion
480-
)
480+
minWebpackPluginWithWinSnapshotsVersion,
481+
)
481482
: true;
482483
if (!hasWebpackPluginWithWinSnapshotsSupport) {
483484
this.$errors.fail(
484-
`In order to generate Snapshots on Windows, please upgrade your Webpack plugin version (npm i ${WEBPACK_PLUGIN_NAME}@latest).`
485+
`In order to generate Snapshots on Windows, please upgrade your Webpack plugin version (npm i ${WEBPACK_PLUGIN_NAME}@latest).`,
485486
);
486487
}
487488
}
@@ -513,7 +514,7 @@ export class WebpackCompilerService
513514
allEmittedFiles: string[],
514515
chunkFiles: string[],
515516
nextHash: string,
516-
platform: string
517+
platform: string,
517518
) {
518519
const currentHash = this.getCurrentHotUpdateHash(allEmittedFiles);
519520

@@ -535,7 +536,7 @@ export class WebpackCompilerService
535536
? _.difference(allEmittedFiles, chunkFiles)
536537
: allEmittedFiles;
537538
const fallbackFiles = chunkFiles.concat(
538-
emittedHotUpdatesAndAssets.filter((f) => f.indexOf("hot-update") === -1)
539+
emittedHotUpdatesAndAssets.filter((f) => f.indexOf("hot-update") === -1),
539540
);
540541

541542
return {
@@ -548,7 +549,7 @@ export class WebpackCompilerService
548549
private getCurrentHotUpdateHash(emittedFiles: string[]) {
549550
let hotHash;
550551
const hotUpdateScripts = emittedFiles.filter((x) =>
551-
x.endsWith(".hot-update.js")
552+
x.endsWith(".hot-update.js"),
552553
);
553554
if (hotUpdateScripts && hotUpdateScripts.length) {
554555
// the hash is the same for each hot update in the current compilation
@@ -575,7 +576,7 @@ export class WebpackCompilerService
575576
message: IWebpackMessage,
576577
platformData: IPlatformData,
577578
projectData: IProjectData,
578-
prepareData: IPrepareData
579+
prepareData: IPrepareData,
579580
) {
580581
// handle new webpack hmr packets
581582
this.$logger.trace("Received message from webpack process:", message);
@@ -590,21 +591,21 @@ export class WebpackCompilerService
590591
path.join(
591592
platformData.appDestinationDirectoryPath,
592593
this.$options.hostProjectModuleName,
593-
asset
594-
)
594+
asset,
595+
),
595596
);
596597
const staleFiles = message.data.staleAssets.map((asset: string) =>
597598
path.join(
598599
platformData.appDestinationDirectoryPath,
599600
this.$options.hostProjectModuleName,
600-
asset
601-
)
601+
asset,
602+
),
602603
);
603604

604605
// extract last hash from emitted filenames
605606
const lastHash = (() => {
606607
const absoluteFileNameWithLastHash = files.find((fileName: string) =>
607-
fileName.endsWith("hot-update.js")
608+
fileName.endsWith("hot-update.js"),
608609
);
609610

610611
if (!absoluteFileNameWithLastHash) {
@@ -636,8 +637,10 @@ export class WebpackCompilerService
636637
}
637638

638639
private getWebpackExecutablePath(projectData: IProjectData): string {
639-
if (this.isWebpack5(projectData)) {
640-
const packagePath = resolvePackagePath("@nativescript/webpack", {
640+
const bundler = this.getBundler();
641+
642+
if (this.isModernBundler(projectData)) {
643+
const packagePath = resolvePackagePath(`@nativescript/${bundler}`, {
641644
paths: [projectData.projectDir],
642645
});
643646

@@ -657,22 +660,36 @@ export class WebpackCompilerService
657660
return path.resolve(packagePath, "bin", "webpack.js");
658661
}
659662

660-
private isWebpack5(projectData: IProjectData): boolean {
661-
const packageJSONPath = resolvePackageJSONPath("@nativescript/webpack", {
662-
paths: [projectData.projectDir],
663-
});
663+
private isModernBundler(projectData: IProjectData): boolean {
664+
const bundler = this.getBundler();
665+
switch (bundler) {
666+
case "rspack":
667+
return true;
668+
default:
669+
const packageJSONPath = resolvePackageJSONPath(
670+
"@nativescript/webpack",
671+
{
672+
paths: [projectData.projectDir],
673+
},
674+
);
664675

665-
if (packageJSONPath) {
666-
const packageData = this.$fs.readJson(packageJSONPath);
667-
const ver = semver.coerce(packageData.version);
676+
if (packageJSONPath) {
677+
const packageData = this.$fs.readJson(packageJSONPath);
678+
const ver = semver.coerce(packageData.version);
668679

669-
if (semver.satisfies(ver, ">= 5.0.0")) {
670-
return true;
671-
}
680+
if (semver.satisfies(ver, ">= 5.0.0")) {
681+
return true;
682+
}
683+
}
684+
break;
672685
}
673686

674687
return false;
675688
}
689+
690+
public getBundler(): "webpack" | "rspack" | "vite" {
691+
return this.$projectConfigService.getValue(`bundler`, "webpack");
692+
}
676693
}
677694

678695
injector.register("webpackCompilerService", WebpackCompilerService);

0 commit comments

Comments
 (0)