-
-
Notifications
You must be signed in to change notification settings - Fork 197
feat: Improve rebuild of native plugins and node_modules checks #3750
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
feat: Improve rebuild of native plugins and node_modules checks #3750
Conversation
Currently all changes in `node_modules` are skipped as we do not check for changes in case `--syncAllFiles` is not passed. In fact the meaning of this option is for LiveSync operations and by default CLI does not watch for changes in node_modules. However, the separate commands like prepare, build, test and even the initial LiveSync must check the node_modules and prepare the correct files. In latest versions (4.2.x) we were always checking all `node_modules` even during change of a single file during LiveSync. After that we've applied a change in the current master branch to skip node_modules check in case specific option is passed to the projectChangesService. The problem with latest approach is that we've missed this option is always passed based on syncAllFiles. This led to the problem that once you have node_modules setup, CLI from master branch never checks for changes in these files and does not move them to platforms dir. With the current changes, node_modules will be checked on all commands. Once LiveSync starts, all consecutive changes in project files will not check node_modules unless `syncAllFiles` option is passed to CLI.
In case CLI builds `.aar` file for the Android part of a plugin during project preparation, consecutive prepares should not build the `.aar` file. Add logic to keep the hashes of the files that have been used for building the plugin and persist them in the `<project dir>/platforms/tempPlugin/<plugin-name>/plugin-data.json`. Before building a new `.aar` file, CLI will check if the mentioned file exists and compare its content with the shasums of the current source files of the plugin. This way we ensure the `.aar` will be built only when the sources are changed.
In case a plugin needs to apply some modifications over its own source, based on the project files, currently it cannot do it. The earliest possible hooks are before-shouldPrepare and beforePrepare, but they are both run after CLI had check the project for changes. In case the plugin uses any of these hooks and apply changes to its source code, CLI will not move the changes to platforms dir of the project as it will not recheck the project state. In order to resolve this issue, add a hook to checkForChanges method. This way a plugin can apply the changes in before-checkForChanges hook and CLI will detect them correctly. Change the method parameters to be a single object, which will allow easier modifications in the future without breaking the plugins that are already using the hook.
0eca517
to
86a7e55
Compare
lib/definitions/project-changes.d.ts
Outdated
@@ -41,8 +41,12 @@ interface IProjectChangesOptions extends IAppFilesUpdaterOptions, IProvision, IT | |||
nativePlatformStatus?: "1" | "2" | "3"; | |||
} | |||
|
|||
interface ICheckForChangesOptions extends IPlatform, IProjectDataComposition { | |||
projectChangesOptions: IProjectChangesOptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing semicolon at the end.
return this.$filesHashService.generateHashes(pluginNativeDataFiles); | ||
} | ||
|
||
private async writePluginHashInfo(fileHashesInfo: IStringDictionary, pluginTempDir: string): Promise<void> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to be async
method.
Also return type should be void
fileHashesInfo: IStringDictionary | ||
}): Promise<boolean> { | ||
|
||
let shouldBuildAar = !!opts.manifestFilePath || opts.androidSourceDirectories.length > 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!!opts.manifestFilePath || opts.androidSourceDirectories.length
should be enough check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this way shouldBuildAar
will become integer instead of boolean. I suppose that even the tslint check will fail as the method should return boolean. I believe that we should not change the variable types based on some conditions. If we want this one shorter, we could use let shouldBuildAar = !!opts.manifestFilePath || !!opts.androidSourceDirectories.length;
if you believe that its more readable.
} | ||
|
||
return shouldBuildAar; | ||
} | ||
|
||
private getSourceFilesHashes(pluginTempPlatformsAndroidDir: string, shortPluginName: string): Promise<IStringDictionary> { | ||
const pathToAar = path.join(pluginTempPlatformsAndroidDir, `${shortPluginName}.aar`); | ||
const pluginNativeDataFiles = this.$fs.enumerateFilesInDirectorySync(pluginTempPlatformsAndroidDir, (file: string, stat: IFsStats) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.$fs.enumerateFilesInDirectorySync(pluginTempPlatformsAndroidDir, (file: string, stat: IFsStats) => file !== pathToAar);
is shorter
const shortPluginName = getShortPluginName(options.pluginName); | ||
const pluginTempDir = path.join(options.tempPluginDirPath, shortPluginName); | ||
const pluginTempMainSrcDir = path.join(pluginTempDir, "src", "main"); | ||
// In case plugin was already built in the current process, we need to clean the old sources as they may break the new build. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move these 3 lines in something like this.clean(pluginTempDir) or even fs.clean in order to keep the method as short and readable as possible
fileHashesInfo: IStringDictionary | ||
}): Promise<boolean> { | ||
|
||
let shouldBuildAar = !!opts.manifestFilePath || opts.androidSourceDirectories.length > 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this way shouldBuildAar
will become integer instead of boolean. I suppose that even the tslint check will fail as the method should return boolean. I believe that we should not change the variable types based on some conditions. If we want this one shorter, we could use let shouldBuildAar = !!opts.manifestFilePath || !!opts.androidSourceDirectories.length;
if you believe that its more readable.
run ci |
fix: Changes in node_modules are always skipped
Currently all changes in
node_modules
are skipped as we do not check for changes in case--syncAllFiles
is not passed.In fact the meaning of this option is for LiveSync operations and by default CLI does not watch for changes in node_modules. However, the separate commands like prepare, build, test and even the initial LiveSync must check the node_modules and prepare the correct files.
In latest versions (4.1.x) we were always checking all
node_modules
even during change of a single file during LiveSync. After that we've applied a change in the current master branch to skip node_modules check in case specific option is passed to the projectChangesService. The problem with latest approach is that we've missed this option is always passed based on syncAllFiles.This led to the problem that once you have node_modules setup, CLI from master branch never checks for changes in these files and does not move them to platforms dir.
With the current changes, node_modules will be checked on all commands. Once LiveSync starts, all consecutive changes in project files will not check node_modules unless
syncAllFiles
option is passed to CLI.feat: Rebuild plugins for Android only when necessary
In case CLI builds
.aar
file for the Android part of a plugin during project preparation, consecutive prepares should not build the.aar
file. Add logic to keep the hashes of the files that have been used for building the plugin and persist them in the<project dir>/platforms/tempPlugin/<plugin-name>/plugin-data.json
.Before building a new
.aar
file, CLI will check if the mentioned file exists and compare its content with the shasums of the current source files of the plugin. This way we ensure the.aar
will be built only when the sources are changed.feat: Add hook for checkForChanges
In case a plugin needs to apply some modifications over its own source, based on the project files, currently it cannot do it. The earliest possible hooks are before-shouldPrepare and beforePrepare, but they are both run after CLI had check the project for changes. In case the plugin uses any of these hooks and apply changes to its source code, CLI will not move the changes to platforms dir of the project as it will not recheck the project state.
In order to resolve this issue, add a hook to checkForChanges method. This way a plugin can apply the changes in before-checkForChanges hook and CLI will detect them correctly.
Change the method parameters to be a single object, which will allow easier modifications in the future without breaking the plugins that are already using the hook.
PR Checklist
What is the current behavior?
CLI 4.1.x:
Whenever CLI checks for changes, it always lists all node_modules and checks for changes there. This happens on all commands and on every change during LiveSync. In case a change in
node_modules
is detected, CLI checks if it is inplatforms/android
directory of the plugin. In case yes, CLI rebuilds all plugins which do not have their own.aar
. CLI rebuilds the.aar
files even for plugins, for which it has already built.aar
and there's no change in their source code that requires rebuild of this.aar
.master branch
CLI skips all checks for changes in
node_modules
. The only chance to get your changes applied is to pass--syncAllFiles
. Whenever a change inplatforms/android
dir of any plugin is detected and--syncAllFiles
is passed, CLI will rebuild all.aar
files.What is the new behavior?
CLI checks
node_modules
for changes during all commands. During LiveSync, CLI will checknode_modules
for changes only during the initial sync (i.e. the first operation of the started command). When a change is detected, CLI will not checknode_modules
for changes unless--syncAllFiles
is passed.When a change in any
platforms/android
directory of a plugin is detected, CLI will check all plugins and their source files. In case the source files that are used for building the.aar
have not been changed since last build, CLI will not rebuild the.aar
.Fixes/Implements/Closes #[Issue Number].