Skip to content
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

Do not delete generated package.json on mvn clean #6151

Closed
Artur- opened this issue Aug 1, 2019 · 21 comments · Fixed by #6385, #6422 or #6433
Closed

Do not delete generated package.json on mvn clean #6151

Artur- opened this issue Aug 1, 2019 · 21 comments · Fixed by #6385, #6422 or #6433
Assignees
Milestone

Comments

@Artur-
Copy link
Member

Artur- commented Aug 1, 2019

For various reasons, you run mvn clean package on your project instead of mvn package. This might be to update dependencies and remove old ones, to make sure code is re-generated or whatever other reason.

When doing mvn clean package, npm install is triggered even though the generated package.json has not been updated. Because the generated file is stored in target, it is removed by mvn clean and comparing the newly generated one to the existing one does not work.

This should be solved so mvn clean package does not need to run npm install.

Potential solutions:

  1. Move the generated package.json out of target so it is not removed. E.g. use the same webpack.config.js+webpack.generated.js pattern and name it /package.generated.json
  2. Store a hash of the generated package.json contents somewhere else for comparison purposes, e.g. main package.json
@project-bot project-bot bot added this to Inbox - needs triage in OLD Vaadin Flow ongoing work (Vaadin 10+) Aug 1, 2019
@mvysny
Copy link
Member

mvysny commented Aug 1, 2019

I agree, the npm install should be run only when the package.generated.json changes. We could also store the hash into the node_modules folder (given it's not deleted by mvn clean).

There are couple of reasons to avoid npm install:

  1. Decrease build time
  2. Re-generating 10000+ files kills Intellij file watcher (or at least used to kill, with 2019.1.3)
  3. Anti-virus software may slow things to a crawl if they decide to scan every of 10000+ files.
  4. Server-side guys will be annoyed that they're forced to wait until "that JavaScript thing" finally builds. Many of projects factored out GWT compilation to a standalone jar artifact for precisely this reason.

@Legioth
Copy link
Member

Legioth commented Aug 1, 2019

I don't like the first suggested solution of putting the generated package.json file in the root of the project since it would then be included in version control unless we also update .gitignore in all starters and such. I don't think anything will go wrong if it's in version control, but it will confuse users when their version control system reports that they have changes in files that they haven't touched.

Another way of fixing this would be to update all starters to exclude that particular file from mvn clean. One potential drawback is that it might be confusing if you still have a /target directory after mvn clean although it's almost empty.

Storing a copy of the file or a hash of the contents in node_modules is maybe not academically correct, but it might actually work.

Storing a hash as a "version number" in the entry in the main package.json file might also work. Giving a proper version number to the generated package.json might also remove the need for forcibly removing package-lock.json, which also contributes to making npm install take longer.

@retomerz
Copy link

retomerz commented Aug 2, 2019

First, thanks for investing this "speed issue". I am the one which reported this (along with #6150) via vaadin.com support portal.

I don't like the first suggested solution of putting the generated package.json file in the root of the project since it would then be included in version control unless we also update .gitignore in all starters and such. I don't think anything will go wrong if it's in version control, but it will confuse users when their version control system reports that they have changes in files that they haven't touched.

Another way of fixing this would be to update all starters to exclude that particular file from mvn clean. One potential drawback is that it might be confusing if you still have a /target directory after mvn clean although it's almost empty.

Storing a copy of the file or a hash of the contents in node_modules is maybe not academically correct, but it might actually work.

Storing a hash as a "version number" in the entry in the main package.json file might also work. Giving a proper version number to the generated package.json might also remove the need for forcibly removing package-lock.json, which also contributes to making npm install take longer.

Please correct me, but at the moment there is already a generated file webpack.generated.js in the project root which should not committed to the VCS according to your documentation [1] (Point 6).
But basically I agree with you, the project root should not be spammed with generated/temporary files.
They should be placed in /target. I am also not a fan of the solution to exclude the /target/package.json from the Maven clean plugin.
I think "mvn clean" should delete the whole /target directory.

I know npm and the vaadin-maven-plugin too little, but /target/package.json looks for me that the file can be committed to the VCS.
So I would also suggest to introduce one more file on the project root, for example package.flat.json.
/target/package.json is compared with package.flat.json and will be overwritten only when its necessary (dependency changed).

Just my 2 cents.

[1] https://vaadin.com/docs/v14/flow/v14-migration/v14-migration-guide.html

@Legioth
Copy link
Member

Legioth commented Aug 2, 2019

webpack.generated.js is done in an awkward way because of difficulties with putting that file in any other place. In general, we should still try to avoid files that need to be treated in special ways.

While it's technically possible to have the internally generated package.json file in version in the root of the project (with a different name to avoid conflicting with the main package.json file), that would introduce yet another file that you either need to add to .gitignore or commit even though you haven't made any changes to it.

For that reason, we would like to find a solution that can have the file in some other location.

@Artur-
Copy link
Member Author

Artur- commented Aug 2, 2019

If you have two package.json files in the same folder then you might have some problems if both happen to install something into the same node_modules folder

@pleku pleku moved this from Inbox - needs triage to Product backlog in OLD Vaadin Flow ongoing work (Vaadin 10+) Aug 5, 2019
@caalador
Copy link
Contributor

caalador commented Aug 5, 2019

As the contents for the folder ./target/frontend will be copied to ./node_modules/@vaadin/flow-deps we could do a compare on build. if we haven't run npm install we won't have the file available in node_modules as it is copied at that time, and if we have run it we can compare the created package.json against the node_modules version and only if they differ we execute npm install.

@Legioth
Copy link
Member

Legioth commented Aug 6, 2019

the contents for the folder ./target/frontend will be copied to ./node_modules/@vaadin/flow-deps

On my machine, the contents aren't copied but instead, flow-deps is a symlink to ../../target/frontend.

@caalador
Copy link
Contributor

caalador commented Aug 6, 2019

On my machine, the contents aren't copied but instead, flow-deps is a symlink to ../../target/frontend.

Right. Also on windows its apparently a JUNCTION and not an actual copy.

@caalador
Copy link
Contributor

caalador commented Aug 7, 2019

Acceptance criteria:

  • Store the hash of the generated package.json as the main package.json version when npm install has run.
  • Check for the need to run npm install by checking the hash of the generated package.json against the version in the main package.json

@pleku pleku added the bug label Aug 21, 2019
@pleku pleku removed this from Product backlog in OLD Vaadin Flow ongoing work (Vaadin 10+) Aug 21, 2019
@pleku pleku added this to Needs triage in OLD Vaadin Flow bugs & maintenance (Vaadin 10+) via automation Aug 21, 2019
@pleku pleku moved this from Needs triage to P1 - High priority in OLD Vaadin Flow bugs & maintenance (Vaadin 10+) Aug 23, 2019
@denis-anisimov denis-anisimov self-assigned this Sep 2, 2019
@denis-anisimov denis-anisimov moved this from P1 - High priority to WIP in OLD Vaadin Flow bugs & maintenance (Vaadin 10+) Sep 2, 2019
denis-anisimov pushed a commit that referenced this issue Sep 3, 2019
Stores hash of the generated package json file in the main package json
(inside node_modules, outside target folder) and updates it every time
when the generated content is changed. TaskUpdatePackages modified
status is changed only if the hash value is changed. It allows do not
run npm install even if the generated package.json file is regenerated.

Fixes #6151
@Legioth
Copy link
Member

Legioth commented Sep 5, 2019

As a workaround, you can configure maven-clean-plugin to not remove the file target/frontend/package.json.

OLD Vaadin Flow bugs & maintenance (Vaadin 10+) automation moved this from WIP to Closed - pending release Sep 6, 2019
ujoni pushed a commit that referenced this issue Sep 6, 2019
…ged (#6385)

Stores hash of the generated package json file in the main package json
(inside node_modules, outside target folder) and updates it every time
when the generated content is changed. TaskUpdatePackages modified
status is changed only if the hash value is changed. It allows do not
run npm install even if the generated package.json file is regenerated.

Fixes #6151
@Legioth
Copy link
Member

Legioth commented Sep 6, 2019

The merged patch is not enough to fix this issue because the ordering inside target/frontend/package.json changes from run to run. This also causes the hash to change.

@Legioth Legioth reopened this Sep 6, 2019
OLD Vaadin Flow bugs & maintenance (Vaadin 10+) automation moved this from Closed - pending release to Needs triage Sep 6, 2019
@denis-anisimov
Copy link
Contributor

That means that acceptance criteria is not correct.

@denis-anisimov denis-anisimov removed their assignment Sep 6, 2019
@denis-anisimov denis-anisimov moved this from Needs triage to P1 - High priority in OLD Vaadin Flow bugs & maintenance (Vaadin 10+) Sep 6, 2019
@caalador caalador self-assigned this Sep 9, 2019
@project-bot project-bot bot moved this from P1 - High priority to WIP in OLD Vaadin Flow bugs & maintenance (Vaadin 10+) Sep 9, 2019
OLD Vaadin Flow bugs & maintenance (Vaadin 10+) automation moved this from WIP to Closed - pending release Sep 10, 2019
caalador added a commit that referenced this issue Sep 10, 2019
When hashing sort dependencies
so we only flag modified if
dependencies have changed.

Closes #6151
@Legioth
Copy link
Member

Legioth commented Sep 10, 2019

This is still not resolved properly, even though it's slightly less obvious now. I don't know exactly what goes on, but doing mvn clean jetty:run will not honour what's in package-lock.json but instead install the newest available version from a dependency range. To reproduce this, we need to first do some setup to emulate a situation where an (old) version is kept in use only because of package-lock.json:

  1. Update Beverage Buddy to use 2.1-SNAPSHOT of flow-server
  2. Run mvn clean jetty:run once to ensure vaadinAppPackageHash is updated in package.json.
  3. Add "left-pad": "1.2.0" as a dependency in package.json.
  4. Do npm install and then npm ls left-pad to verify that version 1.2.0 is indeed installed
  5. Update package.json to instead use "left-pad": "^1.2.0", run npm install again and verify that the same version is still used.
  6. Make a copy of your package-lock.json file for future reference
  7. Observe that after running npm install after removing node_modules, then you will still have version 1.2.0 of left-pad. This means that the project has reproducible builds as long as package-lock.json is in version control.
  8. Observe that after running npm install after removing both node_modules and package-lock.json, then you will get version 1.3.0 of left-pad. Furthermore, the contents of package-lock.json will be different.
  9. Undo the "destructive" side effects of the previous step by putting back the package-lock.json file from step 6., removing node_modules and doing npm install again (and verify that version 1.2.0 is used and that package-lock.json still has the original contents from step 6).

After this setup, the situation is thus emulating what would have happened if version 1.3.0 would have been recently released.

In this situation, doing mvn jetty:run will keep using version 1.2.0 as expected. The problem is that you will end up with version 1.3.0 and a modified package-lock.json after mvn clean jetty:run.

@Legioth Legioth reopened this Sep 10, 2019
OLD Vaadin Flow bugs & maintenance (Vaadin 10+) automation moved this from Closed - pending release to Needs triage Sep 10, 2019
@Legioth
Copy link
Member

Legioth commented Sep 10, 2019

In fact, the only thing that is relevant for this ticket is the very last detail that npm install still seems to happen when doing mvn clean jetty:run. The fact that npm install causes unexpected updates to happen is the topic of a separate ticket.

EDIT: Separate issue created for preserving the installed left-pad version even in cases when npm install should actually be run: #6430

@caalador
Copy link
Contributor

The current problem is that we do clean up because we see that the shrinkwrap version has changed.
This problem is probably the cause also for 6430 where package-lock.json is removed and updated.

@denis-anisimov
Copy link
Contributor

shrinkwrap version should be changed only when the platform release differs from the one is written in some package* files.
That may happen one time and we should keep this behavior since otherwise we will have again version conflicts issue.
But that should happen once: after the first time the versions should be the same and files should not be removed.

@caalador
Copy link
Contributor

The problem is that when we clean the version is lost and when we check in package-lock.json we look for value instead of version so we never find a version to check for.

caalador added a commit that referenced this issue Sep 11, 2019
Fix getting shrinkwrap version from
package-lock.json

fixes #6151
@denis-anisimov
Copy link
Contributor

So it was just a typo, my bad.

OLD Vaadin Flow bugs & maintenance (Vaadin 10+) automation moved this from Needs triage to Closed - pending release Sep 11, 2019
denis-anisimov pushed a commit that referenced this issue Sep 11, 2019
Fix getting shrinkwrap version from
package-lock.json

fixes #6151
@Legioth
Copy link
Member

Legioth commented Sep 11, 2019

Great. Now it seems to work even in my sneaky case. Let's just remember that there are (at least) three different patches that need to be cherry picked for this issue.

@denis-anisimov
Copy link
Contributor

Let's just remember that there are (at least) three different patches that need to be cherry picked for this issue.

Yes, that's the trickiest thing.

mehdi-vaadin pushed a commit that referenced this issue Sep 13, 2019
…ged (#6385)

Stores hash of the generated package json file in the main package json
(inside node_modules, outside target folder) and updates it every time
when the generated content is changed. TaskUpdatePackages modified
status is changed only if the hash value is changed. It allows do not
run npm install even if the generated package.json file is regenerated.

Fixes #6151


(cherry picked from commit d887d09)
mehdi-vaadin pushed a commit that referenced this issue Sep 13, 2019
When hashing sort dependencies
so we only flag modified if
dependencies have changed.

Closes #6151

(cherry picked from commit e84bf89)
mehdi-vaadin pushed a commit that referenced this issue Sep 13, 2019
Fix getting shrinkwrap version from
package-lock.json

fixes #6151

(cherry picked from commit 98d877a)
mehdi-vaadin pushed a commit that referenced this issue Sep 13, 2019
…ged (#6385)

Stores hash of the generated package json file in the main package json
(inside node_modules, outside target folder) and updates it every time
when the generated content is changed. TaskUpdatePackages modified
status is changed only if the hash value is changed. It allows do not
run npm install even if the generated package.json file is regenerated.

Fixes #6151


(cherry picked from commit d887d09)
mehdi-vaadin pushed a commit that referenced this issue Sep 13, 2019
When hashing sort dependencies
so we only flag modified if
dependencies have changed.

Closes #6151

(cherry picked from commit e84bf89)
mehdi-vaadin pushed a commit that referenced this issue Sep 13, 2019
Fix getting shrinkwrap version from
package-lock.json

fixes #6151

(cherry picked from commit 98d877a)
@mehdi-vaadin mehdi-vaadin added this to the 2.0.12 milestone Sep 16, 2019
@mehdi-vaadin mehdi-vaadin moved this from Closed - pending release to Closed - released in OLD Vaadin Flow bugs & maintenance (Vaadin 10+) Sep 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment