Cannot load linked modules from npm/yarn link in WSL - javascript

I'm running into a really strange issue when trying to import a local dependency into my project.
I have a project called 'test_project' and another project that will be linked called 'test_module'. I link test module to the global node_modules folder (I've tried npm link and yarn link). Then in test_project I link test_module. I import test_module into the index.js file, but when I do a yarn/npm start I get this error:
Failed to compile.
./src/index.js
Cannot find file: 'index.js' does not match the corresponding name on disk: '/mnt/c/users/<my_username>/Projects/test_module/Users'.
For whatever reason '/Users' is getting added to the end of the path and I have no idea why. I've blown away my environment twice now and it keeps happening. Is this an issue with WSL? Do I have something configured wrong?
EDIT: 'test_project' was generated from create-react-app, with no modifications. In case you wanted to know how my environment is setup.
EDIT2: I tried this in Window's CMD, and everything worked properly. So it seems like the issues is caused by a combination of WSL, my node installation, and whatever the hell else :/
Thanks

I figured out how to resolve the issue. You need to edit your wsl config and set the root to '/'. My theory is somewhere a relative path is being used, and using '/' as the root removes '/mnt/' from the path, allowing it to step back properly. However, I can't back it up with facts :D
Anyway, the fix is easy.
sudo vim /etc/wsl.conf
Then add this field so the file looks like this:
[automount]
root = /
options = "metadata"
(I have the options field there to resolve permission issues)
Then fully logout/signout, log back in, unlink the module, blow away the node_modules folder, run npm install, and then re-link. It should all work at that point.
Cheers!

This issue had been driving me nuts for a long time but I was able to solve it for the project I'm working on. (Remounting the WSL root didn't fix the issue for me unfortunately.) The symptoms are slightly different from the ones in the original question but I'm hoping what I found might at least provide some insight.
For me, the issue was a combination of factors. It occurred whenever I tried to run react-scripts start for a certain project. The odd part was that I had another project in the WSL with a nearly identical setup that ran fine.
After some hacking, I narrowed the issue down to the case-sensitive-paths-webpack-plugin that react-scripts was using internally. By dropping a bunch of console.log() statements in the fileExistsWithCase method, I was able to pinpoint the cause of the issue.
The method confirms whether a file/directory exists on disk with casing that matches the passed string (filepath). In order to do this, it recursively checks each directory in the path. Unfortunately the error logging appears to be a bit broken because, when an error bubbles up through the recursion loops, it appends the name of the folder in error as if it were the original filename (reported this as an issue in the create-react-app repo).
For example, the error from the original question was
Cannot find file: 'index.js' does not match the corresponding name on disk: '/mnt/c/users/<my_username>/Projects/test_module/Users'.
In this case, after recursing a few times, the library listed everything in /mnt/c and, seeing that the users directory did not exist but the Users directory did, the error bubbled up and was incorrectly reported with a bad file of /mnt/c/users/<my_username>/Projects/test_module/Users.
Now, when checking each file/directory, the library first checks its cache. And ahead of time it primes the cache with the current working directory. This was ultimately why one of my projects worked but the other didn't. The project that worked was using npm so the node_modules were of the form $PWD/node_modules/foo which would stop recursing once $PWD was reached. The other project, however, was using pnpm and the failing dependencies were hoisted up to a higher directory. In my case, those dependencies failed whenever it tried to validate a directory on my system called /mnt/c/Users/[username]/wslhome, which it saw as WSLHome on disk.
I was lucky enough to just be able to rename WSLHome to wslhome to get things working for my project. Unfortunately /mnt/c/Users wouldn't be as easily renamed since it's created by Windows.
Overall, it looks like the issue largely hinges on how the absolute paths of the package's dependencies are defined and whether the casing matches what Node's path sees.
UPDATE: When I went to use the project today it started failing again, this time complaining about the "Users" directory having improper casing. -_- So it appears that the issue may be somewhat inconsistent. I came upon an article about updating case sensitivity options when using Windows directories and, after adding case=dir to my wsl.conf options and restarting the subsystem, the error disappeared. Given its inconsistent nature, however, I can't say for certain whether that was the solution.
One additional observation that's potentially related is that discrepancies seem to be visible when running readlink -f against a dependency directory. Sometimes the results have the proper casing and sometimes they do not. (For example, right now, readlink -f ~/dev improperly returns a subdirectory of /mnt/c/users whereas readlink -f . correctly returns a subdirectory of /mnt/c/Users while in the ~/dev directory.)

Related

Visual code and NodeJs, inference of not installed packages namespaces

I am having an annoying issue. If
I start a blank Node project
no modules installed in it
I do a import '', and, in between the brackets, I press ctrl+space, I get inferred some namespaces which should not actually be there.
I admit I probably did some wrong manipulation when learning how to code, but I tried to solve many of those things:
I deleted the unnecessary globally installed packages
I removed node_modules folders that I accidentally installed in my /Users folder.
But I still get some of them referenced by VC inference:
As you can see in the image I get some random inferred namespace. When trying to reach the originating folder by pressing cmd on Mac, VC doesn't highlight and create the usual hyperlink (when the package is actually there, VC creates a link to navigate to the references file).
How can I get rid of those fake namespaces?? hope you can help me out!
Ok this one was super quick and simple, in fact in my /Users folder I forgot to delete a package.json file which was telling VC thats something was installed ....
so, by my understanding, if a parent folder contains a package.json file it basically propagates down to the children folders...
Interesting to know!

React App production build blank has nothing but a blank page

I am quite new to react (and still learning), so I apologize if the problem is too basic.
I have created a shoe store App (inspired by this tutorial on React Router v6)
The problem I am facing is that the App works perfectly on development build.
But when I create a production build (yarn build) and serve it using npx serve -s build, I get an empty page
The console gives an error that shoeData (a javascript object on a separate shoeData.js file with named export.) is not defined. There was no such error on development build. In fact, just before the errors on the console in the production build, an array has been logged twice using the following code
console.log(Object.keys(shoeData).filter((productId) => shoeData[productId].featured));
The above code uses the shoeData object, therefore the object is available to the component at least initially.
I have also modified the package.json to add "homepage": "." since people have solved similar issues using this fix, but it doesn't work in this case.
The complete project is available on GitHub here
Any help in this regard would be highly appreciated
What I can see on url is that, ReferenceError: shoeData is not defined is being shown. Please look after it.
I'm also looking what's the reason just cloning the repo
This line looks weird,you should pass string to src rather than require a file.
I just clone the repo and make sure the problem is cause by require().
Steps to fix:
Move images/ into public/ folder
Replace all require('...').default with image url, such as /images/${shoeData[productId].gender}/${productId}/01.jpg.
Remove homepage field from package.json

VSCode intelliSense autocomplete for javascript

I would like Visual Studio Code to autocomplete all words within the open document instead of the just the scope specific variables it finds. What should I change in the settings?
edit: code version 0.3.0 at time of question.
I just figured it out. This will use all words on the page for auto complete.
// Always include all words from the current document.
"javascript.suggest.alwaysAllWords": true,
// Complete functions with their parameter signature.
"javascript.suggest.completeFunctionCalls": true,
Even though it has been quite some time for this question, I thought I might be of help to anyone else who bumbles across the same question.
So here goes . And this is for the latest version of VS Code as of writing.
For a true intellisense, i.e. for example you intend to get all the methods related to "console" as soon as you press '.' , you can use the respective Typescript definition file.
Now I agree that this fix is targeted at node,and needs the same along with npm on your system. But still, works for all Major JavaScript work you might run across.
on Linux, for this, you'd need "npm" and install TypeScript Definition Manager (tsd) globally.
npm install -g tsd
then within your current project directory (or by changing to the project directory) , open a terminal window and add the following lines
tsd query node --action install
tsd query express --action install
then, as soon as you'll open your .js file in the current directory, you'll get proper autocomplete / intellisense for all DOM object and other possible stuff.
It worked for me, and this is the only reason I use VSCode on linux (for JavaScript at least, even though I like LightTable too)
for further information (and clarifications if I somehow couldnt manage to be clear enough) visit the following link:
Node.js applications on VS Code

How to avoid node require loading same module twice

I'm developing a node module my-module which in turn depends on another module other-module. other-module is thus a dependency explicitly listed in my module's package.json.
As my module modifies the behaviour of other-module just by being required, it is important that other-module is loaded only once and that this, one-and-only 'instance' is the one referenced throughout any application that requires both my and other.
I expected this to hold true according to node's Module Caching Policy but what I've come across while writing a simple test app is this:
If my-module is npm installed before other-module then the latter is brought in as a dependency of the former. npm installing other-module afterwards brings it into the node_modules hierarchy a second time. Then, when my module requires other-module, node loads my module's 'local' copy and when the app requires it a second time node loads it again, (this time the version that was installed due to the second npm install). This obviously is not the intended result.
If my-module is npm installed after other-module then I end up with only one copy of other-module in node_modules and my test app works as expected.
This behaviour got me looking through node's relevant policies again and sure enough I came across the 'Module Caching Caveats':
Modules are cached based on their resolved filename. Since modules may resolve to a different filename based on the location of the calling module (loading from node_modules folders), it is not a guarantee that require('foo') will always return the exact same object, if it would resolve to different files.
At this point it looks like that my module may or may not behave as expected depending on the order of npm installs.
Are there any best practices I'm missing? Is there any way to avoid this mess without changing the way my module works?
The short answer: You can not.
As you pointed out node will load the required module from the most local place. This is as far as I know unique to a package manager and it enables you to don't care about the exact dependency tree of your modules. Node and npm will figure that out for you. In my opinion this is something really good.
Dependency hell is simply avoided by giving your modules the opportunity to require an exact version of what they need.
I think what you are trying to do, unless I do not understand your question fully, is not good node practice. Modules are loaded and assigned to a local variable. Global state should be avoided, as this can lead to rather awkward and untestable code. Additionally if you would succeed to inject your modified module into other's people code, there could be no guarantee that their code would still work. This would be as in the old Prototype.js_ days when it was ok to hack around with JavaScript's built-in globals like String or Array, which led to some disastrous code.
However keep in mind that this writing is just the opinion of one person. If you don't find more answers here, post your question otherwhere like the node's IRC channel.
I had the similar problem while developing tests with jest.
The following statement would allow you to load the same module again in different context:
jest.resetModules();

xcode 4 + phonegap ... not update JS upon build?

I've run into a weird issue that has had me scratching my head for the past hour.
I'm working on an iPad app using Xcode 4 and PhoneGap. It's using jQuery. I've put all my JS into a scripts.js file.
Things are working well.
I spend about an hour doing a lot of CSS tweaking. I'd update the CSS file, stop the app, rebuild, and push to the iPad simulator or my iPad. That's been working fine. Every update to the CSS file is reflected on the new build.
I then needed to update the JS file. I couldn't get things to work and then I finally realized none of my JS changes were actually be put into the build. I finally blanked out my JS file completely, rebuilt, and it's still not updating.
The file I'm updated is being updated in the finder in the project folder (I can right-click 'view in finder' and that file is, indeed, updated).
So I'm stumped. Is the xcode compiler caching the JS file somehow instead of grabbing the updated file? Is there a way to force it to grab the updated JS?
I found it necessary to hold the Option button when clicking the menu command which turns the command from "Clean" to "Clean Build Folder..." and this caused my assets to be refreshed.
Well, after some more googling, this seems to be a common problem. Xcode seems to cache files even after you've edited them.
One option appears to be to run the 'clean' command before a new build. I tried that, no luck.
Other solutions appear to involve rebuilding the .plist file each time. I don't fully understand that (yet) in terms of how to do that automatically, but did find this workaround:
Open your .plist file
change something (in my case, I rename one of the app icon files each time)
save and build
Doing that magically forces xcode to FINALLY grab all the updated files and do a proper build.
I can't explain why Xcode seems perfectly happy grabbing my updated .css file each and every time but won't update the .html or or .js files without first doing this .plist file edit.
Seems as if Apple still has a few bugs to work out. I guess we'll have to wait patiently for the next 4gig .x relase of it. ;)
Just add a new "Run Script" build phase to your target in XCode and paste this :
touch -cm ${SRCROOT}/www
I do not have mac right now, but few things to try:
Try to look at Your project build (or prebuild or something) action where www folder is supposed to be copied.
Try to change index.html and see if it works.
Try to copy paste all Your javascript code to index.html script tag
Try to validate Your javascript (For example: Google Closure Compiler) and see if it has no problems
None of these worked for me :(
The only way I can get the thing to update its html and js is by running a "corodova run ios" at the command line.
Find the file called copy-www-build-step.sh.
Mine was in [project_folder]/platforms/ios/cordova/lib/copy-www-build-step.sh
In that file, find the lines beginning rsync -a "...
Add -c to the rsync lines, so they ready rsync -a -c "...
copy-www-build-step.sh is the script that copies the files over from www/ to where they go inside the app file. rsync is the unix file copying command they use. Without that -c, rsync just compares the file size on each file and folder and copies them over if the size has changed, and a couple of spaces or quotes don't count as enough of a change. With the -c, it checksums them and compares the checksums, which will catch even the smallest changes.
I think this will work best, because it's not a workaround, it actually fixes the cause of the problem.
I just had this issue, and the build phase command posted here (which is actually now used by the default Phonegap project) did not work for me, since I am editing my files on a Parallels Windows VM, in Visual Studio.
What I did, was use this instead, in the Build Phase of my project:
find "${PROJECT_DIR}/www/." -exec touch -cm {} \;
Thats basically a recursive touch. I then set up Visual Studio to always reload the file, if it has been saved. Hope this helps.
I'm not sure which did it, but I did the following:
Changed an icon value in my MyProject-Info.plist
Quit the simulator
Product -> (hold option) -> Clean Build Folder
Run
I had this same issue with the iOS Simulator, I tried most of the suggestions above with no success, it would not pick up my changes.
Later another possible solution occurred to me, which did work:
Delete the app from the simulator. (ie. Click and hold on the icon, then hit the X when it starts to shake, then Hardware Home)
Then re-run from xCode.
(NB: "cordova build ios" was also required)
Nothing solution of above work
finally i saw there are two index.html file and .js file in the project created using Command line tool of Cordova
So make changes as below shown under Staging folder

Categories