What package versions are installed when running vite build? - vue.js

This is probably a pretty basic question, but I can't find an answer:
If I have a project with a dependency in package.json listed as foobar: ^3.2.1, what version of that dependency will be installed when I run vite build, assuming that the latest available version of the package is 3.4.5?

First thing first, vite build won't change anything to your dependencies. I won't install ones nor update them. It will only build your project (i.e. compile / transpile / minify / bundle etc.) using your source code and the code it imports (likely within the node_modules).
It will build locally, so using your local dependencies in the node_modules folder.
To check the current package version you have installed, you can run:
npm list --depth=0 | grep foobar
(The grep part is optional)
You can also open your package-lock.json or yarn.lock file and search for your package to know to what version your package has been fixed to.
To understand about the semantic version with npm, read this documentation: https://docs.npmjs.com/about-semantic-versioning

Related

How to have `pnpm install` install everything exactly to the specs of the pnpm-lock file?

If you connect a github project to a product like cloudflare pages or Vercel, commits to the remote repo trigger new builds. These builds will run the appropriate install and build commands. I haven't updated a site in months, but major changes have come to dependencies being used and it's causing me so many headaches to try and go through one-by-one and address each and every issue that has surfaced. I'm using pnpm, is there anyway I can have pnpm install look at the existing pnpm-lock.yaml so I can eventually build a project that is entirely the same as a previous build I had 6 months ago? I just want to edit some text on my site and not have to make all these updates. I tried "freezing" the versions of all my dependencies and dev dependencies in package.json by removing instances of ^ to match what I see in my lock file, but that didn't work.
Package Management with PNPM
See also why-does-npm-install-rewrite-package-lock-json
Semver
The semver specification explains how to use semantic versioning though you can probably skip to the npm docs.
As you probably know the numbers are in the form major.minor.patch. If you don't mind which patch release you have as long as it is the specified major and minor version you can use the ~ prefix. Similarly, to allow any minor version use ^.
Walkthrough
Inital Setup
pnpm init
pnpm add express
The package.json will contain (at time of writing):
"express": `"^4.18.2"`
A pnpm-lock.yaml is also created:
specifiers:
express: ^4.18.2
dependencies:
express: 4.18.2
express -> '.pnpm/express#4.18.2/node_modules/express'/
Using pnpm install
Giving it a first run without changing anything produces:
$ pnpm install
Lockfile is up to date, resolution step is skipped
Already up to date
Done in 653ms
Now if I change package.json to be exactly v4.16.0 we shall see an update to pnpm-lock.yaml
specifiers:
express: 4.16.0
dependencies:
express: 4.16.0
Adding the patch wildcard ~4.16.0 and running pnpm install again gives:
specifiers:
express: ~4.16.0
dependencies:
express: 4.16.0
Note that the install version did not change. If I delete the node_modules/ directory and reinstall, still no change.
Ok, now try updating the minor version in package.json to ~4.17.0.
specifiers:
express: ~4.17.0
dependencies:
express: 4.17.3
This time it did update the dependency and installed the latest patch version but did install the exact major and minor version. If you think about what the ~ means then this is expected.
The specifiers section in the lock file is just what we specify as the dependency in the package.json file. The dependencies section in the lock file should reflect the version that is installed, or will be installed.
If I delete the node_modules/ folder and pnpm install again then we still have 4.17.3.
Explanation
What confuses a lot of people about pnpm install/npm install is how the lock-file works with the semver specifier:
The installed version listed as a dependency in the lockfile must be compatible with the version specified in the package file.
If it is compatible, no changes will be made.
If it is incompatible, then the latest compatible version will be installed.
Perhaps because sometimes it seems to install the latest version, and not othertimes, the behaviour is not clear. To state this again, changes will only be made when there is an incompatibility between the packge version and lockfile version. The lockfile dependency never has the ~ or ^ wildcards because only one version is actually installed and that's what the lockfile is supposed to track.
Using --frozen-lockfile in a CI environment
The docs for pnpm install describe how the install will fail if the lockfile is out of sync or needs updating.
Changing the package.json back to ~4.16.0 and then doing the install:
$ pnpm install --frozen-lockfile
Lockfile is up to date, resolution step is skipped
 ERR_PNPM_OUTDATED_LOCKFILE  Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with package.json
Note that in CI environments this setting is true by default. If you still need to run install in such cases, use "pnpm install --no-frozen-lockfile"
In fact, even if I specify the installed version exactly 4.17.3, because it differs to the specifier ~4.17.0, then it will err. The package.json and pnpm-lock.yaml are out of sync even though the version are compatible.
Finally I will make our package compatible with the latest version that was installed with the first pnpm add express command. To do this I use the minor version wildcard ^4.0.0 and unfreeze the lockfile with pnpm install --no-frozen-lockfile.
specifiers:
express: ^4.0.0
dependencies:
express: 4.17.3
While the specifier is updated to match the package file, the version is not chaged; it is compatible.
Running pnpm install --frozen-lockfile will work again, but not update the installed version.
Conclusion
In a normal environment the lockfile will determine the exact version installed unless it is not compatible with the package file, in which case it will install the lastest version specified by the package file.
In a CI environment the lockfile will not by default be updated and will need to be compatible with the package file for installs to occur.
If you want the latest version specified pnpm update will do the update to the lastest compatible version given in the package file.
Disclaimer
I've tested out everything here but it is complex and I have limited experience using pnpm in a real CI environment.
before deploying your project delete pnpm-lock.yaml

How to upgrade one individual file from node_modules folder instead of upgrading the whole package

I need to upgrade one of the yarn.lock file from node_modules folder to remove the Raven vulnerabilities issue.
The file path is
src/node_modules/form-data/yarn.lock
I know I can use npm install to install a new package. But is there a way that I can keep the whole package to the current version, but upgrade one file in the package?
You can edit the file directly. Or you can fork the package and update just the file, then publish your fork. But no, there is no way to use npm (and presumably not yarn either) to update a file without updating the package. That is by design. There are big debugging and malware possibilities if you run an npm command and have it report back that you are running version 1.2.3 but in reality you are running version 1.2.3 with one or more files modified.
I'm puzzled a bit by your desire to update a yarn.lock file in a package. yarn.lock files don't affect anything if they're inside node_modules. This is true both for npm and yarn. The yarn.lock file is ignored if it is not in your top-level project. Updating yarn.lock inside node_modules won't do anything to your running code. Perhaps the dependency is listed in your top-level yarn.lock file for your project?

How to prevent nested node_modules inside node_modules

I've created my own npm package, let's call it XYZ, it has #material-ui dependency in it's package.json file.
When I install it in project A I have nested node_modules inside of XYZ folder(so it's A\node_modules\XYZ\node_modules\#material-ui), but when I install it in project B I don't have nested node_modules folder. Both project A and B has #material-ui in their package.json files with same versions.
How to force my XYZ package to use #material-ui from A\node_modules?
There are upside of having less nested folders and downside having more folders in node_modules folder directly and version control problems.
Use correct npm version
Correct yarn and npm (ie: npm v3) should not have such structure issue. It should always flatten the whole structure where possible and only have nested node_modules if the versions are incompatible with the one at top.
Check versions
So if you have it working properly on one project and not on another, its probably due to version. Check out if the #material-ui is same version on both. Maybe two different packages are conflicting with each other at some point.
Check how you are installing them
From your question, it says it's same version. However, you did not mention how you installed your package on both project. If you install with yarn link or npm link it should install dependencies properly as expected.
Check if you are using different packages
If you check the package, recently material-ui has been deprecated, and the notice says to upgrade to #material-ui/core instead. It might be some packages inside that folder is not same. Either way, it's like this whenever there is some dependency conflict. Check inside the #material-ui folder.
Flatten them manually (dangerous)
There are several packages to forcefully resolve this issue. They will go thru the nested node_modules folders and flatten them into single folder.
flatten-packages
Install with, npm install -g flatten-packages.
Run executable flatten-packages to rearrange all packages in node_modules folder in the project directory.
Flatten will delete older version of a package. You should take care of version breaking changes related errors.
You can use npm dedupe command to accomplish this.
You can put the command in postinstall script in package.json, and every time NPM installs package, the npm dedupe command will flatten all the duplicated packages in same version for you.
For more information, see https://docs.npmjs.com/cli/dedupe
npm postinstall script
I had the same issue in a React Native app with my NPM package.
The problem was that in project A the version of React Native used was (0.59.5) below the version used in my package (0.59.8).
Installing the package in a brand new project (B), of course was using the latest version of React Native in that moment, that was the same of my package (0.59.8).
I have another addition to the accepted answer:
Clear Local node_modules folder Cache
rm -rf node_modules
Handle with care: Sometimes migrating projects to new npm modules can cause weird cache issues inside a node_modules folder, especially those that have been around for a while, or happened to have newer versions of packages installed in sub-dependencies that differed from the installed version in root.
Once you remove direct dependencies via the package.json dependencies, the packages will be removed from the <root>/node_modules. This can cause a bug where the new modules are still nested under your dependency instead of being moved to root as expected.
So by wiping out your local node_modules, you can do a clean reinstall and let the flattening to its work.

How do devDependencies work when you yarn add <package>?

If you have a project that depends on packageA and you yarn add packageA but packageA has a devDependency on packageB to build, shouldn't that cause packageA to not work for you? Since packageA won't be able to build unless its devDependencies are installed too?
I guess my main question is if a pacakge has a devDependency on a built tool like babel, how does it get built and work when it gets yarn added by a project? Shouldn't build tools like webpack be a normal dependency?
No, they shouldn't, because the package that is yarn added is already built in an environment where the devDependencies are available. For example, when a package needs babel or webpack to build, then during the publishing a built bundle is created in a CI/CD pipeline that is valid es5 code and that is what you pull from npm. No build required after that.
GOOD MORNING :)
If you are having dependency problems on your dependencies of package.json, it is very simple to solve =]
What happens is that the dependency modules that the modules of your project need (dependencies) must be installed in the global npm as a package node (module), that is:
npm install -g youPackageName
If you have already installed a module in other projects or in the current project and want to turn it into a global package, you can use the command:
npm link youPackageName

npm 5 install folder without using symlink

Before publishing my node library, I could use the advice the npm documentation wrote about:
To test a local install, go into some other folder, and then do:
cd ../some-other-folder
npm install ../my-package
Prior to version 5 of npm, I had no problem as it produce what I expected, ie a folder with the output of what I will publish.
However, using npm 5, it now creates a symlink to my local project as described in the npm documentation:
npm install :
Install the package in the directory as a symlink in the current
project. Its dependencies will be installed before it's linked. If
sits inside the root of your project, its dependencies may be
hoisted to the toplevel node_modules as they would for other types of
dependencies.
How can I use the "old" way to install local project? Or is there a new way to check if my library is correct?
Thank you.
Use npm pack + npm install (as suggested by install-local package)
npm pack <path-to-local-package>
npm install <package-version.tgz>
This will effectively copy your local package to node_modules.
Note that this will package only production relevant files (those listed in the files section of your package.json). So, you can install it in a test app under the package own directory. Something like this:
my-package
package.json
test
test-app
package.json
node_modules
my-package
Assuming that test dir is not included in the files in my-package/package.json.
This works the same way with npm 5 and older versions.
I wrote npm-install-offline which allows you to install npm packages from a local repository or folder. By default it copies the folder on install but you can also choose to symlink.
https://www.npmjs.com/package/npm-install-offline
npx npm-install-offline ../some-package
Or
npx npm-install-offline my-npm-package --repo ./my-offline-npm
It also will install the package dependencies which npm does not do with local packages.