6 ms·
Habits of a Happy Node Hacker
- secretagent 11y agoRegarding point 9, if you don't check your `node_modules` into version control don't you run the risk of them disappearing from NPM?
- hunterloftis 11y ago"If you are paranoid about depending on the npm ecosystem, you should run a private npm mirror or a private cache. If you want 100% confidence in being able to reproduce the specific bytes included in a deployment, you should use an additional mechanism that can verify contents rather than versions. For example, Amazon machine images, DigitalOcean snapshots, Heroku slugs, or simple tarballs." https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git https://docs.npmjs.com/misc/faq#should-i-check-my-node-modul...
- thoughtpalette 11y agoThat's a good point, I've never considered the possibility of a package I'm using disappear from NPM. I never check in my node_modules folder and let CI build processes handle all of that.
- vog 11y agoEven when assuming availability, what about modules that change? Either because authors "bugix" their existing versions and don't bother to increase the version number. Or because a malicious network actor delivered modified code. That's why I prefer to add a SHA-256 hash/checksum to every downloaded dependency file. In some settings that hash might be more important than the actual version number.
- LukeB_UK 11y agonpm only lets you publish a version once, if the version number already exists for that module, you have to change the version number
- vog 11y agoOkay, that's good to know. But I'm still uneasy with this, as the crypto hash approach provides some more safety features. For example, it protects against attacks the NPM platform itself (assuming they happen after you incorporated the library into your project). Also, it enables us to download the package from any other source (e.g. some archive/mirror), via plain HTTP, while still being safe from downloading a modified package. That's why I still wish the crypto hashes were included in package.json (automatically on "install --save-exact", of course).
- jtwebman 11y agoI think if you are worried about this you should be using Dockers and Docker Hub.
- seivan 11y agoYou could fork the libs and point to your own repo. That's what we usually did with Cocoapods.
- draw_down 11y agoDo you guys not use pip, and stuff? I'm surprised by all the confusion on this point. Package managers are part of modern programming platforms. Repos only need to have your code, not everyone else's.
- bshimmin 11y agoNode.js is the rare example of a Linux-centric tool with great cross-platform support. Apart from the problems with Windows, npm, and path lengths.
- sonnyp 11y agoIt was an npm issue, fixed in npm 3. http://www.felixrieseberg.com/npm-v3-is-out-and-its-a-really-big-deal-for-windows/ http://www.felixrieseberg.com/npm-v3-is-out-and-its-a-really...
- userbinator 11y agoI may be somewhat biased because my primary platform is Windows, but IMHO 260 bytes is plenty for a full path. I've personally never run into that limit with what I do, but I'm aware that there are some programming languages and environments which even encourage very deep nesting (often with directories that contain nothing more than another one), making it much harder to navigate the resulting structure. It's good to see the Node.js people recognise this situation and go back to flatter hierarchies, even if it was Windows' path length limitations that motivated it. http://blog.codinghorror.com/filesystem-paths-how-long-is-too-long/ http://blog.codinghorror.com/filesystem-paths-how-long-is-to...
- deleted 11y ago[deleted]
- netcraft 11y agoThe new babel 6 stuff was the first time I had hit the limitation, but their names are extraordinarily long.
- detaro 11y agoThe annoying thing is that the limitation only exists in some APIs. So you can create paths that are to long, but then most software can't deal with them, which is worse than not allowing long paths at all.
- 11y ago
- douche 11y agoUntil I looked at the actual title of the post, I was a little concerned that somebody had invented a time machine. It's been changed now, but originally was titled "10 Habits of a Happy Node Hacker (2016)"
- dang 11y agoThe "10" violated the guidelines explicitly (magic numbers in titles are supposed to be removed) and the "(2016)", while fine in principle, is ambiguous with HN's convention for annotating years. So we took those out.
- cvburgess 11y agoThe article suggests using node-foreman (#6); can someone explain the advantage of Procfile-based environment management? I read the docs and didn't see anything that couldn't be handled by a simple config.json or some environment variables.
- schwuk 11y agoThe article is on heroku.com, so of course it's going to encourage Heroku-centric solutions.
- hunterloftis 11y agoNode-foreman does use environment variables. The usefulness of the tool (vs just straight env vars) is mostly in its ability to: 1) start multiple processes at once during local dev, much like a process manager can on a platform like Heroku or a compose file can in Docker. For instance, I'm working on a system now that uses `web`, `game`, and `sms` processes - which can all be started together via `nf start`, and then when one crashes during development the whole system spins down. 2) inject env vars into a local app via `.env` files (similar to your config.json example)
- acbabis 11y ago#4 seems spurious. Just another example of "If everyone did it my way, then everyone would be doing it my way." What if people don't want to do it your way? What if people can actually remember to spell correctly? EDIT: *nix has case-sensitivity so that people can actually use it.
- hunterloftis 11y agoIt isn't about spelling. It's about behavior that will be presumed correct in one environment but not in another. It's about portability. For another node example - in Linux, you can successfully use paths like `let filepath='foobar/' + filename`. That's correct in the given environment. However, such code will break when run in Windows. This is why `let filepath = path.join('foobar', filename)` is a superior solution. A Windows or OSX user can save Myfile.js all day long and require('MyFile') with success. That same code will break as soon as you try to run it in Linux. These recommendations are the product of supporting the many thousands of Node apps built each week on Heroku.
- acbabis 11y agoThanks for the reply. While I understand the argument about preventing pitfalls, it's reasonable to expect programmers to pay attention to capitalization, since source code requires you to anyway. I think the path of least resistance here, is to tell programmers to spell things the same way as the last person to work on the code spelled it.
- AgentME 11y agoWindows supports regular / symbols in pathnames. What system doesn't?
- chowes 11y agoIronically, right after the author mentions "The leading edge of developers are simplifying their builds" w/ vanilla JS, he suggests using Babel to get bleeding edge JS features...
- bwindels 11y agoThe need for babel will (hopefully) go away in the future, though. So using ES6 features with Babel will end you up with a simpler project eventually, as opposed to writing ES5 with some libraries to do the same.
- crimsonalucard 11y agoKind of a random question. What's the state of generator based control flow? Is this the future "habit" of a node hacker?
- mkozlows 11y agoasync/await is built on generators and promises.
- crimsonalucard 11y agoSorry I haven't followed the node community for a while. Are you referring to this: https://github.com/yortus/asyncawait https://github.com/yortus/asyncawait? Is this becoming popular / the new standard?
- Kiro 11y ago> Cluster your app How is this possible in my multiplayer game where the whole world lives in the program? E.g. var map = [...] and then map[x][y] when I want to use it, var players = [], players.push(newPlayer) etc. How can I share this state in a cluster?
- jw989 11y agoWell, you're main app should obviously not be clustered but think about the api you use to manage data. I don't know your architecture but I'm sure that you can separate your api from your user state and cluster those apis as well as use various reverse proxies and load balancing services.
- jonesetc 11y agoYou need some form of IPC. Easiest thing that comes to my mind is just to use a redis hash.
- chowes 11y agoIn your current state, clustering is probably not be the best advice for your use case. That being said, if you are planning on scaling, you'll likely be moving your map object into it's own process, or a more traditional database, etc. Then whatever node application you have that facilitates the communication between that db/process and your users (via websockets or http) will be the place where clustering will come in handy.
- angersock 11y agoClustering is useful mainly when your app gets large or when you are handling redundancy. If you aren't doing that, your app is small enough not to need it. :) If you want a fun exercise, try monkeypatching your global objects (map, players, etc.) to have getters/setters/etc. that transparently handle the syncing stuff.
- habitue 11y agoYour app should be clustered, and your db (where your state should live) can be clustered too. Ultimately you want as little state in your app servers as possible, since this makes it harder to scale them out, reboot them etc. That's the ideal case anyway, its hard to avoid session state with websockets etc, but you can still push a lot down to the database layer
- jasim 11y ago> As long as each dependency is listed in package.json, anyone can create a working local copy of your app - including node_modules - by running npm install. But it is going to download the internet, will take forever, and if the network is patchy, any dependencies that weren't downloaded will remain unresolved, even if you reinstall the package, and you'll have to manually install them with the help of `npm list`, or nuke node_modules and start over, and pray that this time the network remains perfect for a few minutes at a stretch. (someone please tell me I've got it all wrong)
- sisk 11y agoYou're not necessarily wrong (that a ton of modules will be downloaded) but there are two points worth mentioning. 1) you can install from cache with something like: npm install --cache-min 9999999 2) npm's infrastructure has scaled extremely well. Gone are the days of spotty uptime and slow resolution. I maintain an npm proxy for one of—if not the—single largest consumer of npm modules and other than the very occasional 502 blip, npm has been rock-solid.
- jasim 11y agoThanks for clarifying. I'll try the cache-min flag. But I suspect that if the cache contains packages with unresolved dependencies, then they'll also be of no use, and have to be removed too. Also npm's servers has never given any trouble, the issue was always with my networks.
- albinofrenchy 11y agoEither way you are going to have to potentially download a lot of stuff; I'd rather not have that bloat integrated into the repo. Also consider if you come onto a project and they've upgraded a library version multiple times, when you clone from the repo you are going to grab every revision they've ever used and checked in. This is going to be much bigger and slower than the equivalent npm install for that package. If you are grabbing from an external repo, the spotty network is going to mess you up either way. If it's internal and your internet is that spotty, consider hosting a local npm cacheing server like this -- https://www.npmjs.com/package/sinopia https://www.npmjs.com/package/sinopia. My only issue with this technique is that 'npm start' and the rest aren't smart enough (please correct me if I'm wrong and there is a way to make it care!) to grab dependencies if you upgrade a dependency version and check that in.
- bsimpson 11y agoThanks Hunter. That was a really helpful article. Though I don't agree with every suggestion, memory tuning and clustering are both really important and not discussed widely enough. save-exact is a good tip too - I've just been mass-deleting the carets before committing.