Skip to content

Commit 748f753

Browse files
committed
Support for webpack
1 parent 57cb647 commit 748f753

File tree

7 files changed

+90
-43
lines changed

7 files changed

+90
-43
lines changed

lib/definitions/preview-app-livesync.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ declare global {
1414
qrCodeUrl: string;
1515
connectedDevices: Device[];
1616
initialize(): void;
17-
applyChanges(files: FilePayload[]): Promise<void>;
17+
applyChanges(files: FilePayload[], deviceId: string): Promise<void>;
1818
stop(): void;
1919
}
2020

lib/helpers/livesync-command-helper.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,13 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper {
3535
deviceId: this.$options.device,
3636
platform,
3737
emulator,
38-
skipDeviceDetectionInterval: true,
3938
skipInferPlatform: !platform,
4039
sdk: this.$options.sdk
4140
});
4241

4342
const devices = this.$devicesService.getDeviceInstances()
4443
.filter(d => !platform || d.deviceInfo.platform.toLowerCase() === platform.toLowerCase());
4544

46-
const devicesPlatforms = _(devices).map(d => d.deviceInfo.platform).uniq().value();
47-
if (this.$options.bundle && devicesPlatforms.length > 1) {
48-
this.$errors.failWithoutHelp("Bundling doesn't work with multiple platforms. Please specify platform to the run command.");
49-
}
50-
5145
await this.executeLiveSyncOperation(devices, platform, additionalOptions);
5246
}
5347

lib/services/livesync/livesync-service.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
332332
deviceDescriptorsForInitialSync = isAlreadyLiveSyncing ? _.differenceBy(deviceDescriptors, currentlyRunningDeviceDescriptors, deviceDescriptorPrimaryKey) : deviceDescriptors;
333333
}
334334

335-
this.setLiveSyncProcessInfo(liveSyncData.projectDir, deviceDescriptors);
335+
this.setLiveSyncProcessInfo(liveSyncData, deviceDescriptors);
336336

337337
const shouldStartWatcher = !liveSyncData.skipWatcher && (liveSyncData.syncToPreviewApp || this.liveSyncProcessesInfo[projectData.projectDir].deviceDescriptors.length);
338338
if (shouldStartWatcher) {
@@ -344,7 +344,8 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
344344
await this.initialSync(projectData, liveSyncData, deviceDescriptorsForInitialSync);
345345
}
346346

347-
private setLiveSyncProcessInfo(projectDir: string, deviceDescriptors: ILiveSyncDeviceInfo[]): void {
347+
private setLiveSyncProcessInfo(liveSyncData: ILiveSyncInfo, deviceDescriptors: ILiveSyncDeviceInfo[]): void {
348+
const { projectDir } = liveSyncData;
348349
this.liveSyncProcessesInfo[projectDir] = this.liveSyncProcessesInfo[projectDir] || Object.create(null);
349350
this.liveSyncProcessesInfo[projectDir].actionsChain = this.liveSyncProcessesInfo[projectDir].actionsChain || Promise.resolve();
350351
this.liveSyncProcessesInfo[projectDir].currentSyncAction = this.liveSyncProcessesInfo[projectDir].actionsChain;
@@ -575,11 +576,12 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
575576
currentWatcherInfo.watcher.close();
576577
}
577578

578-
const filesToSync: string[] = [];
579+
let filesToSync: string[] = [];
580+
const filesToSyncMap: IDictionary<string[]> = {};
579581
let filesToRemove: string[] = [];
580582
let timeoutTimer: NodeJS.Timer;
581583

582-
const startSyncFilesTimeout = () => {
584+
const startSyncFilesTimeout = (platform?: string) => {
583585
timeoutTimer = setTimeout(async () => {
584586
if (liveSyncData.syncToPreviewApp) {
585587
await this.addActionToChain(projectData.projectDir, async () => {
@@ -648,7 +650,7 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
648650
},
649651
(device: Mobile.IDevice) => {
650652
const liveSyncProcessInfo = this.liveSyncProcessesInfo[projectData.projectDir];
651-
return liveSyncProcessInfo && _.some(liveSyncProcessInfo.deviceDescriptors, deviceDescriptor => deviceDescriptor.identifier === device.deviceInfo.identifier);
653+
return (!platform || platform.toLowerCase() === device.deviceInfo.platform.toLowerCase()) && liveSyncProcessInfo && _.some(liveSyncProcessInfo.deviceDescriptors, deviceDescriptor => deviceDescriptor.identifier === device.deviceInfo.identifier);
652654
}
653655
);
654656
} catch (err) {
@@ -689,9 +691,13 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
689691
},
690692
platforms
691693
},
692-
filesToSync,
694+
filesToSyncMap,
693695
filesToRemove,
694-
startSyncFilesTimeout: startSyncFilesTimeout.bind(this)
696+
startSyncFilesTimeout: async (platform: string) => {
697+
filesToSync = filesToSyncMap[platform];
698+
await startSyncFilesTimeout(platform);
699+
filesToSyncMap[platform] = [];
700+
}
695701
}
696702
});
697703

lib/services/livesync/playground/preview-app-livesync-service.ts

Lines changed: 67 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
99
private excludedFiles = [".DS_Store"];
1010

1111
constructor(private $fs: IFileSystem,
12+
private $hooksService: IHooksService,
1213
private $logger: ILogger,
1314
private $platformService: IPlatformService,
1415
private $platformsData: IPlatformsData,
1516
private $projectDataService: IProjectDataService,
1617
private $previewSdkService: IPreviewSdkService,
1718
private $previewAppPluginsService: IPreviewAppPluginsService,
18-
private $projectFilesManager: IProjectFilesManager) { }
19+
private $projectFilesManager: IProjectFilesManager,
20+
private $projectFilesProvider: IProjectFilesProvider) { }
1921

2022
public initialize() {
2123
this.$previewSdkService.initialize();
@@ -24,13 +26,47 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
2426
public async initialSync(data: IPreviewAppLiveSyncData): Promise<void> {
2527
this.$previewSdkService.on(PreviewSdkEventNames.DEVICE_CONNECTED, async (device: Device) => {
2628
this.$logger.trace("Found connected device", device);
27-
await this.syncFilesOnDeviceSafe(data, device);
29+
const filesToSyncMap: IDictionary<string[]> = {};
30+
let promise = Promise.resolve();
31+
const startSyncFilesTimeout = async (platform: string) => {
32+
promise
33+
.then(async () => {
34+
promise = this.syncFilesForPlatformSafe(data, platform, filesToSyncMap[platform]);
35+
await promise;
36+
});
37+
filesToSyncMap[platform] = [];
38+
};
39+
await this.$hooksService.executeBeforeHooks("preview-sync", {
40+
hookArgs: {
41+
projectData: this.$projectDataService.getProjectData(data.projectDir),
42+
config: {
43+
env: data.env,
44+
platform: device.platform,
45+
appFilesUpdaterOptions: data.appFilesUpdaterOptions,
46+
},
47+
filesToSyncMap,
48+
  startSyncFilesTimeout: startSyncFilesTimeout.bind(this)
49+
}
50+
            });
51+
await this.$previewAppPluginsService.comparePluginsOnDevice(device);
52+
await this.syncFilesForPlatformSafe(data, device.platform);
2853
});
2954
}
3055

31-
public async syncFiles(data: IPreviewAppLiveSyncData, files: string[]): Promise<void> {
56+
public async syncFiles(data: IPreviewAppLiveSyncData, files?: string[]): Promise<void> {
57+
this.showWarningsForNativeFiles(files);
58+
3259
for (const device of this.$previewSdkService.connectedDevices) {
33-
await this.syncFilesOnDeviceSafe(data, device, files);
60+
await this.$previewAppPluginsService.comparePluginsOnDevice(device);
61+
}
62+
63+
const platforms = _(this.$previewSdkService.connectedDevices)
64+
.map(device => device.platform)
65+
.uniq()
66+
.value();
67+
68+
for (const platform of platforms) {
69+
await this.syncFilesForPlatformSafe(data, platform, files);
3470
}
3571
}
3672

@@ -39,37 +75,37 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
3975
this.$previewSdkService.stop();
4076
}
4177

42-
private async syncFilesOnDeviceSafe(data: IPreviewAppLiveSyncData, device: Device, files?: string[]): Promise<void> {
43-
await this.$previewAppPluginsService.comparePluginsOnDevice(device);
44-
this.showWarningsForNativeFiles(files);
45-
46-
this.$logger.info(`Start syncing changes on device ${device.id}.`);
78+
private async syncFilesForPlatformSafe(data: IPreviewAppLiveSyncData, platform: string, files?: string[]): Promise<void> {
79+
this.$logger.info(`Start syncing changes for platform ${platform}.`);
4780

4881
try {
49-
await this.syncFilesOnDevice(data, device, files);
50-
this.$logger.info(`Successfully synced changes on device ${device.id}.`);
82+
const { appFilesUpdaterOptions, env, projectDir } = data;
83+
const projectData = this.$projectDataService.getProjectData(projectDir);
84+
await this.preparePlatform(platform, appFilesUpdaterOptions, env, projectData);
85+
86+
// TODO: This should be refactored after implementing platform param in pubnub's meta data.
87+
const devices = this.$previewSdkService.connectedDevices.filter(device => device.platform === platform);
88+
for (const device of devices) {
89+
await this.applyChanges(projectData, device, files);
90+
}
91+
92+
this.$logger.info(`Successfully synced changes for platform ${platform}.`);
5193
} catch (err) {
52-
this.$logger.warn(`Unable to apply changes on device ${device.id}. Error is: ${JSON.stringify(err, null, 2)}.`);
94+
this.$logger.warn(`Unable to apply changes for platform ${platform}. Error is: ${err}, ${JSON.stringify(err, null, 2)}.`);
5395
}
5496
}
5597

56-
private async syncFilesOnDevice(data: IPreviewAppLiveSyncData, device: Device, files?: string[]): Promise<void> {
57-
const { appFilesUpdaterOptions, env, projectDir } = data;
58-
const platform = device.platform;
59-
const projectData = this.$projectDataService.getProjectData(projectDir);
60-
const platformData = this.$platformsData.getPlatformData(platform, projectData);
61-
62-
await this.preparePlatform(platform, appFilesUpdaterOptions, env, projectData);
63-
64-
const payloads = this.getFilePayloads(platformData, projectData, files);
65-
await this.$previewSdkService.applyChanges(payloads);
98+
private async applyChanges(projectData: IProjectData, device: Device, files: string[]) {
99+
const platformData = this.$platformsData.getPlatformData(device.platform, projectData);
100+
const payloads = this.getFilePayloads(platformData, projectData, _(files).uniq().value());
101+
await this.$previewSdkService.applyChanges(payloads, device.id);
66102
}
67103

68104
private getFilePayloads(platformData: IPlatformData, projectData: IProjectData, files?: string[]): FilePayload[] {
69105
const appFolderPath = path.join(projectData.projectDir, APP_FOLDER_NAME);
70106
const platformsAppFolderPath = path.join(platformData.appDestinationDirectoryPath, APP_FOLDER_NAME);
71107

72-
if (files) {
108+
if (files && files.length) {
73109
files = files.map(file => path.join(platformsAppFolderPath, path.relative(appFolderPath, file)));
74110
} else {
75111
files = this.$projectFilesManager.getProjectFiles(platformsAppFolderPath);
@@ -85,9 +121,15 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
85121

86122
const payloads = filesToTransfer
87123
.map(file => {
124+
const projectFileInfo = this.$projectFilesProvider.getProjectFileInfo(file, platformData.normalizedPlatformName, null);
125+
const relativePath = path.relative(platformsAppFolderPath, file);
126+
const extName = path.extname(relativePath);
127+
const baseName = projectFileInfo.onDeviceFileName.split(extName)[0];
128+
const newFileName = `${baseName}.${platformData.normalizedPlatformName.toLowerCase()}${extName}`;
129+
88130
const filePayload: FilePayload = {
89131
event: PreviewSdkEventNames.CHANGE_EVENT_NAME,
90-
file: path.relative(platformsAppFolderPath, file),
132+
file: path.join(path.dirname(relativePath), newFileName),
91133
binary: isTextOrBinary.isBinarySync(file),
92134
fileContents: ""
93135
};
@@ -97,7 +139,7 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
97139
const base64 = new Buffer(bitmap).toString('base64');
98140
filePayload.fileContents = base64;
99141
} else {
100-
filePayload.fileContents = this.$fs.readText(file);
142+
filePayload.fileContents = this.$fs.readText(path.join(path.dirname(projectFileInfo.filePath), projectFileInfo.onDeviceFileName));
101143
}
102144

103145
return filePayload;

lib/services/livesync/playground/preview-sdk-service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ export class PreviewSdkService extends EventEmitter implements IPreviewSdkServic
2525
this.instanceId = this.messagingService.initialize(initConfig);
2626
}
2727

28-
public applyChanges(files: FilePayload[]): Promise<void> {
28+
public applyChanges(files: FilePayload[], deviceId: string): Promise<void> {
2929
return new Promise((resolve, reject) => {
30-
this.messagingService.applyChanges(this.instanceId, files, err => {
30+
this.messagingService.applyChanges(this.instanceId, files, deviceId, err => {
3131
if (err) {
3232
reject(err);
3333
} else {

lib/services/platform-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
745745
const prepareInfo = this.$projectChangesService.getPrepareInfo(platform, projectData);
746746
// In case when no platform is added and webpack plugin is started it produces files in platforms folder. In this case {N} CLI needs to add platform and keeps the already produced files from webpack
747747
if (appFilesUpdaterOptions.bundle && this.isPlatformInstalled(platform, projectData) && !this.$fs.exists(platformData.configurationFilePath) && (!prepareInfo || !prepareInfo.nativePlatformStatus || prepareInfo.nativePlatformStatus !== constants.NativePlatformStatus.alreadyPrepared)) {
748-
const tmpDirectoryPath = path.join(projectData.projectDir, "platforms", "tmp");
748+
const tmpDirectoryPath = path.join(projectData.projectDir, "platforms", `tmp-${platform}`);
749749
this.$fs.deleteDirectory(tmpDirectoryPath);
750750
this.$fs.ensureDirectoryExists(tmpDirectoryPath);
751751
this.$fs.copyFile(path.join(platformData.appDestinationDirectoryPath, "*"), tmpDirectoryPath);

lib/services/prepare-platform-js-service.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as shell from "shelljs";
44
import * as temp from "temp";
55
import { hook } from "../common/helpers";
66
import { PreparePlatformService } from "./prepare-platform-service";
7+
import { TNS_CORE_MODULES } from "../common/constants";
78

89
temp.track();
910

@@ -41,7 +42,7 @@ export class PreparePlatformJSService extends PreparePlatformService implements
4142
}
4243
}
4344

44-
if (!this.$fs.exists(path.join(config.platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME))) {
45+
if (!config.skipCopyAppResourcesFiles && !this.$fs.exists(path.join(config.platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME))) {
4546
this.copyAppResourcesFiles(config);
4647
}
4748

@@ -59,6 +60,10 @@ export class PreparePlatformJSService extends PreparePlatformService implements
5960
await this.copyTnsModules(config.platform, config.platformData, config.projectData, config.appFilesUpdaterOptions, config.projectFilesConfig);
6061
}
6162
}
63+
64+
if (!config.skipCopyTnsModules && !this.$fs.exists(path.join(config.platformData.appDestinationDirectoryPath, TNS_CORE_MODULES))) {
65+
await this.copyTnsModules(config.platform, config.platformData, config.projectData, config.appFilesUpdaterOptions, config.projectFilesConfig);
66+
}
6267
}
6368

6469
private async getPathToPlatformTemplate(selectedTemplate: string, frameworkPackageName: string, projectDir: string): Promise<{ selectedTemplate: string, pathToTemplate: string }> {

0 commit comments

Comments
 (0)