PNPM - Starting new project not working as expected - javascript

I'm trying to use a centralised package manager (pnpm) instead of the vanilla npm, because, I like having space on my hard drive. I'm just trying to get the project started and running into difficulty and there is very little online to actually guide me through starting a project with this package manager. Does anyone have experience getting this to work for React/React Native?
Any ideas would be very welcome.
I've tried two different ways of setting this up:
Created a new project with pnpx create-react-app my-app. This just did exactly what npx create-react-app would do, which includes installing over 200MB of modules I've already had on my system a million times over. I've checked the node_modules folder and none of the files are hard links, they are the modules themselves.
Created a new project without helper commands (i.e. touch App.js, index.js, index.html etc.) then pnpm i react... etc. This worked in a fashion, all of the node packages were links to my global store (in ~/), but then when I try pnpm start to get my server going, I get the error: Cannot find module ... /my-project/server.js. I do not have a server.js file, but then again, using regular npm and npx commands, I have never needed one.
I have used pnpm i server to see if I can get it working that way. Nothing. I'm relatively new to React, so I'm sure I've done something ridiculous, however regardless of how junior I am, I followed the official instructions and they haven't worked for me.
pnpm debug file says the following:
{
"0 debug pnpm:scope": {
"selected": 1,
"workspacePrefix": null
},
"1 error pnpm": {
"message": {
"errno": 1,
"code": "ELIFECYCLE",
"pkgid": "my-cv#1.0.0",
"stage": "start",
"script": "node server.js",
"pkgname": "my-cv"
},
"err": {
"name": "Error",
"message": "my-cv#1.0.0 start: `node server.js`\nExit status 1",
"code": "ELIFECYCLE",
"stack": "Error: my-cv#1.0.0 start: `node server.js`\nExit status 1\n at EventEmitter.<anonymous> (/usr/local/lib/node_modules/pnpm/lib/node_modules/#zkochan/npm-lifecycle/index.js:302:16)\n at EventEmitter.emit (events.js:200:13)\n at ChildProcess.<anonymous> (/usr/local/lib/node_modules/pnpm/lib/node_modules/#zkochan/npm-lifecycle/lib/spawn.js:55:14)\n at ChildProcess.emit (events.js:200:13)\n at maybeClose (internal/child_process.js:1021:16)\n at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)"
}
}
}
UPDATE: So I've managed to get it to work, I think... I got hold of all of the required packages that are used in npx create-react-app and put them inside package.json before executing pnpm i. However, aside from wondering whether this is possible without going to that amount of trouble, looking at the file structure, in addition to the aliases I have inside the node_modules folder, I seem to have a hidden folder .registry.npmjs.org. This is exactly the same as the one I have in my system root, that I assumed was the central store.
TLDR: It appears that despite pnpm appearing to work (aliases are created inside the node_modules folder), I still have duplicate packages on my system. Can anyone confirm whether this is the case?

I realise this is an old question now.... but it's still not adequately resolved (ideally, create-react-app should have a switch which allows it to use pnpm natively.... but that's for another day).
My solution is a bit tedious, but works. First, create your react app as normal:
pnpx create-react-app my-app --template typescript
Wait the requisite time for npm to download ~350mb of stuff you've already got. Next, run the following (assuming Linux):
cd my-app
rm -rf node_modules/
pnpm i
Depending on how many modules got re-used, you'll be saving up to 350mb of disk space.

Regarding disk space usage. The packages inside node_modules are hard links. pnpm has a section about this in the FAQ:
pnpm creates hard links from the global store to project's node_modules folders. Hard links point to the same place on the disk where the original files are. So, for example, if you have foo in your project as a dependency and it occupies 1MB of space, then it will look like it occupies 1MB of space in the project's node_modules folder and the same amount of space in the global store. However, that 1MB is the same space on the disk addressed from two different locations. So in total foo occupies 1MB, not 2MB.
For more on this subject:
Why do hard links seem to take the same space as the originals?
A thread from the pnpm chat room
An issue in the pnpm repo
Regarding the hidden folder inside node_modules, you can read in this article: Flat node_modules is not the only way.
pnpm used to have issues with React Native. pnpm uses symlinks a lot and React Native doesn't like symlinks.
P.S. if you don't get help on SO, you can always post to our Gitter chat

Related

Node cannot find path in node_modules / 'react-scripts' is not recognized as an internal or external command

I'm on windows 10
When I run:
npm run start
or
npm start
I get an error:
npm start
> app-test#0.1.0 start
> react-scripts start
'react-scripts' is not recognized as an internal or external command,
operable program or batch file.
What I already tried:
npm ci
remove node_modules and reinstall project
npm audit fix
run command from elevated PowerShell (as admin)
Uninstall Node v.18 win NVM and reinstall common Node installation LTS v.16
Check if react scripts is on dependencies section in package.json - and it's of course there.
Recreate project itself and also create a fresh new React project with npx create-react-app
Clearing npm cache
Nothing's helped me.
BUT This project runs fine WHEN I explicitly tell the node path to subfolder with a script:
app-test> node node_modules/react-scripts/scripts/start.js
Compiled successfully!
You can now view app-test in the browser.
Local: http://localhost:3000
On Your Network: http://192.168.91.1:3000
Note that the development build is not optimized.
To create a production build, use npm run build.
webpack compiled successfully
What's interesting that an old React projects also resided in the parent folder starts normally even I renew node_modules in these projects doing them npm i or npm ci
But any time I try to create and start new React app command npm start fails
UPD1: Tried to create-react-app on any other drive or folder. And it's running ok.
So culprit seems permissions policies in my common working directory ?
UPD2:
I resolved a problem though still have no clear idea who was actually the really culprit of this bug.
I copied all my parent developer folder with all code examples to another drive, then tried to create react app there and out of the blue it worked fine at then new location.
Also I removed this original folder from the drive where it used to be. And do git clone "..." at this directory< recreating the exact structure as it was before all experiments.
Then I tried create-react-app exactly at that location as I've unsuccessfully tried before swapping folders and it was OK !
Tried couple of time with different folder location within parent directory and all sill working fine now !
I remembered now I already have such bug before. And I had to reinstall Windows that time.
I also want to mention that I also have another machine with Windows, another one with Linux and had also laptop with an OSX so I can ( or could) push to this very git repository from any of these computers.
Suggestion of somebody who have any idea, why this bug was happening repeatable would be highly appreciated.
Thanks.

How can I reset my dependency tree after ruining node_modules and package.json?

I'm building an app using create-react-app and completely messed up my dependencies. I tried deleting node-modules and package-lock.json, but I messed up package.json too, so that didn't work. When I tried it and ran npm start, it gave me an error saying that react-scripts wasn't recognized as an internal or external command, operable program, or batch file.
I, stupidly, didn't commit/push anything to git before messing everything up, so I can't just do git clone and get back to an older version of my project that actually worked. I just want a way to get my project's environment looking like I just hit create-react-app. Is that possible without just literally doing that and copying/pasting all of my source code files?
If you want exact same dependecies as create react up just copy its package.json, otherwise you cant do much thats why VCS are so important.

How should I handle package-lock.json when I deploy from git via ssh?

I have a deployment process where I check code into a git repository, and via web hooks a deployment script is run on the production server. On that server, I connect to git using ssh and a .pem key, pull from git, npm install, build webpack and restart the service process.
I never intend to commit anything from the prod servers - they should be able to deploy automatically. However, this does not work, because the package-lock.json file is frequently updated when I run npm install, and so the next time I deploy, the git pull step fails, saying that I conflict with existing package-lock.json file because it has changes that are not committed.
My current solution is to .gitignore the package-lock.json file. But that defeats its purpose, to provide builds that are identical to the ones on my dev machine.
What would be the right way to handle package-lock.json?
There's a helpful StackOverflow Question/Answer about why your package.lock is changing. The closest most useful answer seems to reference an NPM bug that's seeing much activity here in October 2017.
But currently, package.json overrides package-lock.json, meaning if you use ~2.1 and there's a 2.2 version of that package, your production deploy will get upgraded.
Assuming you're not from the future, there's two different ideas here:
Use only non-prefixed, specific version numbers (2.1 vs ~2.0) in your package.json. (This is not great)
npm install --no-save... which doesn't solve the underlaying issue of lock files getting ignored, but I think will keep the package-lock.json from being updated.

Change Directory in Node REPL not working?

Just earlier, I posted my question:
https://stackoverflow.com/questions/28336443/how-to-not-put-my-js-files-in-user-myuser-for-node-js
I have a file, hello.js, located in /Users/MyUser/Desktop/Node/
I can see that my default directory is /Users/MyUser/
Okay, so I get that I need to change my working directory. What I have been able to find so far is to use >process.chrdir('/Users/MyUser/Desktop/Node/');
Cool, that works, but now when I get out of the REPL shell, the directory resets.
The person who responded to my question said that I needed to run >node init and later npm install <name of dependency> --save
My first question: I have ran >node init and see that I can create this package.json file, what does this do exactly?
Secondly: I was told that I need to add dependancies. Could someone please explain to me what this means in Node terms? Does a dependancy simply mean a folder that I want node to include? Do I want to add this Node folder on my Desktop to be able to run my scripts?
I am currently trying to go through the learnyounode courses, however I do not want to have to save all of these test files in my /User/MyUser directory, so any advice would be greatly appreciated.
Thanks
I have ran >node init and see that I can create
this package.json file, what does this do exactly?
npm init is used to create a package.json file interactively. This will ask you a bunch of questions, and then write a package.json for you.
package.json is just a file that handle the project's dependencies and holds various metadata relevant to the project[ project description, version, license information etc]
I was told that I need to add dependencies. Could someone please
explain to me what this means in Node terms?
Lets say you're building an application that is dependent on a number of NPM modules, you can specify them in your package.json file this way:
"dependencies": {
"express": "2.3.12",
"jade": ">= 0.0.1",
"redis": "0.6.0"
}
Now doing npm install would install a package, and any packages that it depends on.
A package is:
a folder containing a program described by a package.json file
a gzipped tarball containing (1)
a url that resolves to (2)
a # that is published on the registry with (3)
a # that points to (4)
a that has a "latest" tag satisfying (5)
a that resolves to (2)
If you need to install a dependency that haven't been included in package.json, simply do npm install <packageName>. Whether or not you want to include this newly installed package in package.json is completely your take. You can also decide how this newly installed package shall appear in your package.json
npm install <packageName> [--save|--save-dev|--save-optional]:
--save: Package will appear in your dependencies.
--save-dev: Package will appear in your devDependencies.
--save-optional: Package will appear in your optionalDependencies.
Does a dependency simply mean a folder that I want node to include?
Umm, partly yes. You may consider dependencies as folders, typically stored in node_modules directory.
Do I want to add this Node folder on my Desktop to be able to run my
scripts?
No, node manages it all. npm install will automatically create node_modules directory and you can refer to those dependencies with
require() in your .js files
var express = require('express');
Node REPL simply provides a way to interactively run JavaScript and see the results. It can be used for debugging, testing, or just trying things out.
process.cwd() points to the directory from which REPL itself has been initiated. You may change it using process.chdir('/path'), but once you close the REPL session and restart, it would always re-instantiate process.cwd() to the directory from which it has been started.
If you are installing some packages/dependencies in node project1 and think those dependencies can also be useful for node project2,
install them again for project2 (to get independentnode_modules directory)
install them globally [using -g flag]. see this
reference packages in project2 as
var referencedDependency = require('/home/User/project1/node_modules/<dependency>')
Simply doing process.chdir('/home/User/project1/node_modules/') in REPL and referencing as
var referencedDependency = require('<dependency>') in your js file wont work.
>process.chdir('/Users/MyUser/Desktop/Node/'); change the working directory only for that particular REPL session.
Hope it helps!
This has nothing to do with node.js but is rather inherent in the design of Unix (which in turn influences the design of shells on other operating systems).
Processes inherit values from their parent's environment but their environments are distinct.
That terse description of how process environments work has a sometimes unexpected behavior: you cannot change your parent's environment. It was designed this way explicitly for security reasons.
What this means is, when you change the working directory in a process and quits that process your shell's working directory will not be affected. Indeed, your shell's working directory isn't affected even when the process (in this case, node REPL) is running.
This exact question is often asked by people writing shell scripts wanting to write a script that CDs into someplace. But it's also common to find this question asked by people writing other languages such as Perl, Tcl, Ruby etc. (even C).
The answer to this question is always the same regardless of language: it's not possible to CD from another program/script/process.
I'm not sure how Windows handles it so it may be possible to do it there. But it's not possible on Unixen.

webpack --watch isn't compiling changed files

I tried running webpack --watch and after editing my JS files, it doesn't trigger an auto-recompilation.
I've tried reinstalling webpack using npm uninstall but it's still not working.
Any ideas?
If your code isn't being recompiled, try increasing the number of watchers (in Ubuntu):
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
Source: https://webpack.github.io/docs/troubleshooting.html
FYI: it seems OS X can have a folder get corrupted and no longer send fsevents (which watchpack/chokidar/Finder uses) for itself and any child folders. I can't be sure this is what happened to you, but it was very frustrating for me and a colleague.
We were able to rename the corrupt parent folder and then watch events immediately came through as expected. See this blog post for more info: http://livereload.com/troubleshooting/os-x-fsevents-bug-may-prevent-monitoring-of-certain-folders/
The recommended fixes from the above link are:
rebooting the computer
checking the disk and repairing permissions via Disk Utility
adding the folder to Spotlight privacy list (the list of folders to not index), and then removing from it, effectively forcing a reindexing
renaming the folder, and then possibly renaming it back
re-creating the folder and moving the old contents back into it
First two did not work for us, didn't try the Spotlight suggestion, and the re-creation did not prove necessary.
We were able to find the root problem folder by opening Finder and creating files in each successive parent folder until one showed up immediately (since Finder will get hosed by this bug as well). The root-most folder that does not update is the culprit. We just mv'd it and mv'd it back to its original name, and then the watcher worked.
No idea what causes the corruption, but I'm just glad to have a fix.
Adding the following code to my webpack configuration file fixed the issue for me.
Don't forget to ignore your node_modules folder, as that would kill performance for HMR (Hot Module Replacement):
watchOptions: {
poll: true,
ignored: /node_modules/
}
I have had this problem when working with WebStorm.
Disabling Settings -> System Settings -> "safe write" resolved it for me.
Found the recommendation to do so in: WebPack Troubleshooting
Folder case sensitivity was my issue. My code calls to require() had all lowercase path names BUT the actually directories had an uppercase letter in them. I renamed all my directories to lowercase and webpack watching worked instantly.
Just to add to possible solutions:
I had my project folder inside a Dropbox folder, moving it out solved the problem for me. (OS X)
One issue is that if your path names aren't absolute then things like this will happen. I had accidentally set resolve.root to ./ instead of __dirname and this caused me to waste a lot of time deleting and re-creating files like the guys above me.
Note that if you run webpack within a virtual machine (Vagrant / Virtualbox) and you change your files on the host platform, file updates in the shared folder may not trigger inotify on Ubuntu. That will cause the changes to not be picked up by webpack.
see: Virtualbox ticket #10660
In my case, editing and saving the file on de guest (in vi) did trigger webpack. Editing it on the host (in PhpStorm, Notepad or any other application) dit NOT trigger webpack whatever I did.
I solved it by using vagrant-fsnotify.
Updates: deleting the entire directory and git cloning afresh from repo fixes my problem.
If changing fs.inotify.max_user_watches as pointend out by César still doesn't work try to use polling instead of native watchers by creating your script as shown in the docs or running webpack with --watch --watch-poll options.
Work for me in Laravel Homestead
--watch --watch-poll
I was having the same issue on a .vue file.
When the server restarted all worked fine, but on the next save it didn't recompiled anymore.
The issue was on the import file path that had one letter capitalized. It's very hard to figure this issue because everything works on a server reboot. Check the case of your paths.
If you are using Vim you should try setting backupcopy to yes rather than the default auto. Otherwise Vim will sometimes rename the original file and create a new one, which will mess up with webpack watch:
https://github.com/webpack/webpack/issues/781
Just add this to your vim settings if this is the case:
set backupcopy=yes
It wasn't recompiling for me but then I realized / remembered that webpack watches the dependency graph and not just a folder (or files). Sure enough the files I was changing weren't part of that graph yet.
I had similar issue, neither webpack or rollup in watch mode ware catching the changes I made. I found out that it was basically my fault as I was changing module (.tsx file) which wasn't yet imported anywhere in the application (for example App.ts which is entry point) and I was expecting build tools to report errors I made there.
For me, creating folders and files in VS Code was the issue. To fix, I re-cloned my repo and this time, created new folders and files through the command line instead of Code. I think Code was corrupting the files for some reason. I saw the application just updated so maybe it's a new bug.
The way I resolved the issue was finding a capitalization error in an import path. Folder on file system had lower case first letter, import path was upper case. Everything compiled fine, so this was just a webpack watch include issue.
Also had this issue inside a VirtualBox (5.2.18) Ubuntu (18.04) VM using Vagrant (2.1.15) with rsync synchronization. Suddenly, first build runs great but Webpack does not take the changes into consideration afterwards, even with fs.inotify.max_user_watches=524288 set. Adding poll: true in Webpack config didn't help either.
Only vagrant-notify-forwarder worked (vagrant-fsnotify didn't, for some reason), but then the rebuild happened too quickly after saving the file on the host and I suppose that rsync didn't have enough time to finish its task (maybe due to the amount of synced directories inside my Vagrantfile?).
Finally I made the watch work again by also increasing the aggregateTimeout in my Webpack config:
module.exports = {
watch: true,
watchOptions: {
aggregateTimeout: 10000
},
...
}
If this solution works for you, try lowering this value again, otherwise you'll have to wait 10 seconds until the build restarts each time you hit save. The default value is 300 ms.
What was the cause in my case:
It seems that the value of: max_user_watches
in the /proc/sys/fs/inotify/max_user_watches
is affecting webpack
To check your actual value
$cat /proc/sys/fs/inotify/max_user_watches
16384
16384 was in my case and it still wasnt enough.
I tried different type of solutions like:
$ echo fs.inotify.max_user_watches=100000 | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -p
But it seems that even if I changed the value, when I restarted my PC it would go back to default one 16384.
SOLUTION if you have Linux OS(my case, I have Manjaro):
Create the file:
sudo nano /etc/sysctl.d/90-override.conf
And populate it with:
fs.inotify.max_user_watches=200000
It seems 200000 is enough for me.
After you create the file and add the value, just restart the PC and you should be ok.
I have the same issue. And I notice it's not compiling because my folder contains some character(*). And using the old watcher plugin seems to resolve the issue.
Add this line to your webpack config file.
plugins: [
new webpack.OldWatchingPlugin()
]
For me deleting node_modules and doing npm install or yarn again to install all the packages solved the problem
An easy solution on MacOS is the following :
Open two terminal windows in the same directory that your project resides.
In the first terminal window run : webpack --watch
In the second terminal windows run : webpack-dev-server
I have tried many possible solutions and this seems to be the most reliable
Possible solution: changing context to the app directory.
I had all my webpack config files in a sub folder:
components/
webpack/
development.js
app.js
In webpack/development.js, set context: path.join(__dirname, '../') solved my problem.
After trying a handful of strategies for fixing this problem I ended up just giving up but then while solving another issue I tried again and all of sudden the --watch flag was finally working.
To be honest I do not know what specifically made it work but after performing the following steps it just started working:
1. Install most recent gcc version
$ sudo port install gcc48
$ sudo port select --set gcc mp-gcc48
2. Install most recent clang version
$ sudo port install clang-3.6
$ sudo port select --set clang mp-clang-3.6
3. Export variables holding the patch to C and C++ compiler
$ export CC=/opt/local/bin/clang
$ export CXX=/opt/local/bin/clang++
It might have happened that while installing these packages some dependency just added the missing piece of the puzzle, who knows ...
Hope this help anyone struggling out there to make it working.
I am adding another answer because I believe that this is the best solution so far.
I am using it every day and it rocks!
Just install this library :
https://github.com/gajus/write-file-webpack-plugin
Description :
Forces webpack-dev-server program to write bundle files to the file system.
How to install :
npm install write-file-webpack-plugin --save-dev
Try changing --watch to -d --watch
worked for me
If this happened suddenly in your project, then this could fix the issue.
Maybe somehow the files which were tracking your project changes which webpack looks for got corrupted.
You can create them again just by following simple steps.
come out of your project dir. ($: cd ..)
move your project to different directory ($: mv {projectName} {newName})
go into the new dir ($: cd {newName})
start the server and check if it reloads on every file change (it should work in most cases, because now webpack creates new files to watch for changes)
come out of the dir ($: cd ..)
move it back to its original name ($: mv {newName} {projectNam})
This worked for me............
I came across this question when I was having a similar issue-- it appeared that webpack was not rebundling, even when running webpack --config.
I even deleted bundle.js and the webpage was still displaying as before my edits.
For those of you who get this same problem, I finally did the 'empty cache and hard reload' option in chrome (right click the reload button with the devtools open) and that did that trick
I met the same issue, tried many things, finally Chrome Clear Browsing Data on Mac worked for me.
These modules have been installed:
"browser-sync": "^2.26.7",
"browser-sync-webpack-plugin": "^2.2.2",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.9"
Problem was in distiction between .js and .ts files. Why ?
On project build, Visual Studio compiles typescript files into .js and .js.map.
This is totally unecessary, because webpack handles typescript files as well (with awesome-typescript-loader). When editing componet .tsx files in Visual Studio Code or With disabled compileOnSave option in tsconfig.json, edited ts file is not recompiled and my webpack was processing unactual .js file.
Solution was to disable compiling typescript files in visual studio on project build. Add
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
in PropertyGroup of your .csproj.

Categories

Resources