Skip to content

feat: bundler config #5837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,8 @@ injector.require(
injector.requirePublic("cleanupService", "./services/cleanup-service");

injector.require(
"webpackCompilerService",
"./services/webpack/webpack-compiler-service",
"bundlerCompilerService",
"./services/bundler/bundler-compiler-service",
);

injector.require(
Expand Down
3 changes: 3 additions & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const SCOPED_TNS_CORE_MODULES = "@nativescript/core";
export const TNS_CORE_THEME_NAME = "nativescript-theme-core";
export const SCOPED_TNS_CORE_THEME_NAME = "@nativescript/theme";
export const WEBPACK_PLUGIN_NAME = "@nativescript/webpack";
export const RSPACK_PLUGIN_NAME = "@nativescript/rspack";
export const TNS_CORE_MODULES_WIDGETS_NAME = "tns-core-modules-widgets";
export const UI_MOBILE_BASE_NAME = "@nativescript/ui-mobile-base";
export const TNS_ANDROID_RUNTIME_NAME = "tns-android";
Expand All @@ -36,6 +37,7 @@ export const XML_FILE_EXTENSION = ".xml";
export const PLATFORMS_DIR_NAME = "platforms";
export const HOOKS_DIR_NAME = "hooks";
export const WEBPACK_CONFIG_NAME = "webpack.config.js";
export const RSPACK_CONFIG_NAME = "rspack.config.js";
export const TSCCONFIG_TNS_JSON_NAME = "tsconfig.tns.json";
export const KARMA_CONFIG_NAME = "karma.conf.js";
export const LIB_DIR_NAME = "lib";
Expand Down Expand Up @@ -223,6 +225,7 @@ export const FILES_CHANGE_EVENT_NAME = "filesChangeEvent";
export const INITIAL_SYNC_EVENT_NAME = "initialSyncEvent";
export const PREPARE_READY_EVENT_NAME = "prepareReadyEvent";
export const WEBPACK_COMPILATION_COMPLETE = "webpackCompilationComplete";
export const BUNDLER_COMPILATION_COMPLETE = "bundlerCompilationComplete";

export class DebugCommandErrors {
public static UNABLE_TO_USE_FOR_DEVICE_AND_EMULATOR =
Expand Down
16 changes: 8 additions & 8 deletions lib/controllers/prepare-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class PrepareController extends EventEmitter {
private $prepareNativePlatformService: IPrepareNativePlatformService,
private $projectChangesService: IProjectChangesService,
private $projectDataService: IProjectDataService,
private $webpackCompilerService: IWebpackCompilerService,
private $bundlerCompilerService: IBundlerCompilerService,
private $watchIgnoreListService: IWatchIgnoreListService,
private $analyticsService: IAnalyticsService,
private $markingModeService: IMarkingModeService,
Expand Down Expand Up @@ -117,8 +117,8 @@ export class PrepareController extends EventEmitter {
this.watchersData[projectDir][platformLowerCase] &&
this.watchersData[projectDir][platformLowerCase].hasWebpackCompilerProcess
) {
await this.$webpackCompilerService.stopWebpackCompiler(platformLowerCase);
this.$webpackCompilerService.removeListener(
await this.$bundlerCompilerService.stopBundlerCompiler(platformLowerCase);
this.$bundlerCompilerService.removeListener(
WEBPACK_COMPILATION_COMPLETE,
this.webpackCompilerHandler,
);
Expand Down Expand Up @@ -177,7 +177,7 @@ export class PrepareController extends EventEmitter {
prepareData,
);
} else {
await this.$webpackCompilerService.compileWithoutWatch(
await this.$bundlerCompilerService.compileWithoutWatch(
platformData,
projectData,
prepareData,
Expand Down Expand Up @@ -296,15 +296,15 @@ export class PrepareController extends EventEmitter {
};

this.webpackCompilerHandler = handler.bind(this);
this.$webpackCompilerService.on(
this.$bundlerCompilerService.on(
WEBPACK_COMPILATION_COMPLETE,
this.webpackCompilerHandler,
);

this.watchersData[projectData.projectDir][
platformData.platformNameLowerCase
].hasWebpackCompilerProcess = true;
await this.$webpackCompilerService.compileWithWatch(
await this.$bundlerCompilerService.compileWithWatch(
platformData,
projectData,
prepareData,
Expand Down Expand Up @@ -560,7 +560,7 @@ export class PrepareController extends EventEmitter {
if (this.pausedFileWatch) {
for (const watcher of watchers) {
for (const platform in watcher) {
await this.$webpackCompilerService.stopWebpackCompiler(platform);
await this.$bundlerCompilerService.stopBundlerCompiler(platform);
watcher[platform].hasWebpackCompilerProcess = false;
}
}
Expand All @@ -569,7 +569,7 @@ export class PrepareController extends EventEmitter {
for (const platform in watcher) {
const args = watcher[platform].prepareArguments;
watcher[platform].hasWebpackCompilerProcess = true;
await this.$webpackCompilerService.compileWithWatch(
await this.$bundlerCompilerService.compileWithWatch(
args.platformData,
args.projectData,
args.prepareData,
Expand Down
20 changes: 19 additions & 1 deletion lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export interface IOSLocalSPMPackage extends IOSSPMPackageBase {
}

export type IOSSPMPackage = IOSRemoteSPMPackage | IOSLocalSPMPackage;
export type BundlerType = "webpack" | "rspack" | "vite";

interface INsConfigIOS extends INsConfigPlaform {
discardUncaughtJsExceptions?: boolean;
Expand Down Expand Up @@ -182,6 +183,8 @@ interface INsConfig {
shared?: boolean;
overridePods?: string;
webpackConfigPath?: string;
bundlerConfigPath?: string;
bundler?: BundlerType;
ios?: INsConfigIOS;
android?: INsConfigAndroid;
visionos?: INSConfigVisionOS;
Expand Down Expand Up @@ -215,13 +218,28 @@ interface IProjectData extends ICreateProjectData {
* Value is true when project has nativescript.config and it has `shared: true` in it.
*/
isShared: boolean;

/**
* Specifies the bundler used to build the application.
*
* - `"webpack"`: Uses Webpack for traditional bundling.
* - `"rspack"`: Uses Rspack for fast bundling.
* - `"vite"`: Uses Vite for fast bundling.
*
* @default "webpack"
*/
bundler: BundlerType;
/**
* @deprecated Use bundlerConfigPath
* Defines the path to the configuration file passed to webpack process.
* By default this is the webpack.config.js at the root of the application.
* The value can be changed by setting `webpackConfigPath` in nativescript.config.
*/
webpackConfigPath: string;
/**
* Defines the path to the bundler configuration file passed to the compiler.
* The value can be changed by setting `bundlerConfigPath` in nativescript.config.
*/
bundlerConfigPath: string;
projectName: string;

/**
Expand Down
48 changes: 29 additions & 19 deletions lib/project-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { parseJson } from "./common/helpers";
import { EOL } from "os";
import { cache } from "./common/decorators";
import {
BundlerType,
INsConfig,
IProjectConfigService,
IProjectData,
Expand Down Expand Up @@ -99,6 +100,8 @@ export class ProjectData implements IProjectData {
public podfilePath: string;
public isShared: boolean;
public webpackConfigPath: string;
public bundlerConfigPath: string;
public bundler: BundlerType;
public initialized: boolean;

constructor(
Expand All @@ -110,7 +113,7 @@ export class ProjectData implements IProjectData {
private $logger: ILogger,
private $injector: IInjector,
private $androidResourcesMigrationService: IAndroidResourcesMigrationService,
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
) {}

get projectConfig(): IProjectConfigService {
Expand Down Expand Up @@ -142,7 +145,7 @@ export class ProjectData implements IProjectData {

public initializeProjectDataFromContent(
packageJsonContent: string,
projectDir?: string
projectDir?: string,
): void {
projectDir = projectDir || this.$projectHelper.projectDir || "";
this.projectDir = projectDir;
Expand All @@ -157,7 +160,7 @@ export class ProjectData implements IProjectData {
this.$errors.fail(
`The project file ${this.projectFilePath} is corrupted. ${EOL}` +
`Consider restoring an earlier version from your source control or backup.${EOL}` +
`Additional technical info: ${err.toString()}`
`Additional technical info: ${err.toString()}`,
);
}

Expand All @@ -178,36 +181,43 @@ export class ProjectData implements IProjectData {
this.appDirectoryPath = this.getAppDirectoryPath();
this.appResourcesDirectoryPath = this.getAppResourcesDirectoryPath();
this.androidManifestPath = this.getPathToAndroidManifest(
this.appResourcesDirectoryPath
this.appResourcesDirectoryPath,
);
this.gradleFilesDirectoryPath = path.join(
this.appResourcesDirectoryPath,
this.$devicePlatformsConstants.Android
this.$devicePlatformsConstants.Android,
);
this.appGradlePath = path.join(
this.gradleFilesDirectoryPath,
constants.APP_GRADLE_FILE_NAME
constants.APP_GRADLE_FILE_NAME,
);
this.infoPlistPath = path.join(
this.appResourcesDirectoryPath,
this.$devicePlatformsConstants.iOS,
constants.INFO_PLIST_FILE_NAME
constants.INFO_PLIST_FILE_NAME,
);
this.buildXcconfigPath = path.join(
this.appResourcesDirectoryPath,
this.$devicePlatformsConstants.iOS,
constants.BUILD_XCCONFIG_FILE_NAME
constants.BUILD_XCCONFIG_FILE_NAME,
);
this.podfilePath = path.join(
this.appResourcesDirectoryPath,
this.$devicePlatformsConstants.iOS,
constants.PODFILE_NAME
constants.PODFILE_NAME,
);
this.isShared = !!(this.nsConfig && this.nsConfig.shared);
this.webpackConfigPath =

const webpackConfigPath =
this.nsConfig && this.nsConfig.webpackConfigPath
? path.resolve(this.projectDir, this.nsConfig.webpackConfigPath)
: path.join(this.projectDir, "webpack.config.js");
this.webpackConfigPath = webpackConfigPath;
this.bundlerConfigPath =
this.nsConfig && this.nsConfig.bundlerConfigPath
? path.resolve(this.projectDir, this.nsConfig.bundlerConfigPath)
: webpackConfigPath;
this.bundler = this?.nsConfig?.bundler ?? "webpack";
return;
}

Expand All @@ -217,7 +227,7 @@ export class ProjectData implements IProjectData {
private getPathToAndroidManifest(appResourcesDir: string): string {
const androidDirPath = path.join(
appResourcesDir,
this.$devicePlatformsConstants.Android
this.$devicePlatformsConstants.Android,
);
const androidManifestDir =
this.$androidResourcesMigrationService.hasMigrated(appResourcesDir)
Expand All @@ -230,13 +240,13 @@ export class ProjectData implements IProjectData {
private errorInvalidProject(projectDir: string): void {
const currentDir = path.resolve(".");
this.$logger.trace(
`Unable to find project. projectDir: ${projectDir}, options.path: ${this.$options.path}, ${currentDir}`
`Unable to find project. projectDir: ${projectDir}, options.path: ${this.$options.path}, ${currentDir}`,
);

// This is the case when no project file found
this.$errors.fail(
"No project found at or above '%s' and neither was a --path specified.",
projectDir || this.$options.path || currentDir
projectDir || this.$options.path || currentDir,
);
}

Expand Down Expand Up @@ -291,7 +301,7 @@ export class ProjectData implements IProjectData {

private resolveToProjectDir(
pathToResolve: string,
projectDir?: string
projectDir?: string,
): string {
if (!projectDir) {
projectDir = this.projectDir;
Expand All @@ -306,7 +316,7 @@ export class ProjectData implements IProjectData {

@cache()
private initializeProjectIdentifiers(
config: INsConfig
config: INsConfig,
): Mobile.IProjectIdentifier {
this.$logger.trace(`Initializing project identifiers. Config: `, config);

Expand Down Expand Up @@ -341,18 +351,18 @@ export class ProjectData implements IProjectData {
private getProjectType(): string {
let detectedProjectType = _.find(
ProjectData.PROJECT_TYPES,
(projectType) => projectType.isDefaultProjectType
(projectType) => projectType.isDefaultProjectType,
).type;

const deps: string[] = _.keys(this.dependencies).concat(
_.keys(this.devDependencies)
_.keys(this.devDependencies),
);

_.each(ProjectData.PROJECT_TYPES, (projectType) => {
if (
_.some(
projectType.requiredDependencies,
(requiredDependency) => deps.indexOf(requiredDependency) !== -1
(requiredDependency) => deps.indexOf(requiredDependency) !== -1,
)
) {
detectedProjectType = projectType.type;
Expand All @@ -366,7 +376,7 @@ export class ProjectData implements IProjectData {
@cache()
private warnProjectId(): void {
this.$logger.warn(
"[WARNING]: IProjectData.projectId is deprecated. Please use IProjectData.projectIdentifiers[platform]."
"[WARNING]: IProjectData.projectId is deprecated. Please use IProjectData.projectIdentifiers[platform].",
);
}
}
Expand Down
Loading