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
Build a single-file cli #735
Conversation
Right now, doing `npm install` of prettier creates 3500 files, which is a pain to manage and to check in. Using the awesome rollup, we can easily bundle all the dependencies into a single big js file. This way I can just check-in a single file in fb codebase and update it when there's a new version. Performance-wise, it is currently 50ms slower than using ./bin/prettier. Both babylon and flow are taking roughly 30ms to parse and we only need a single one at a time. We can shave off 20ms by minifying the bundle but it breaks flow parser (this is why we don't have a flow option on the website!) rollup doesn't support shebangs so I had to split the bin/prettier into two files, a dummy one with the shebang and I put the code inside of src: `src/cli.js`.
I'm curious, why would an integration need its own bundle? If it's JS-based, like atom, it already supports npm dependencies. If it's other tools like Emacs/Vim/etc they just rely on an external "prettier" command to be available which you can install with That's how all integrations are working now so what is different about your setup that makes |
50ms is a decent amount (on top of an already 200-300ms as far as I know). Another option would be to disable some dependencies. If you are doing integration, you shouldn't need a bunch of the CLI stuff like chaulk, get-stdin, minimist, etc. Can we somehow make those optional? |
Here are all the constraints:
I want prettier to be run super fast when the hotkey is triggered so I need two things:
Because we have to use the same version of prettier for linting and nuclide, we need to have the repo being the source of truth. Because we have it on multiple repos, there are likely going to be multiple versions of prettier deployed for some period of time. In order to download the installed version of prettier on the remote repository, having it being a single file is waaayyyy easier. |
How do you all you use other modules from npm? Do you always bundle them together? We don't have too many dependencies, and you shouldn't need the CLI, so we could get rid of half of them if we figure out how to make them optional. Or are you still invoking it via the CLI? If you use other npm modules, does your infrastructure provide a way to do this automatically for any npm module?
That makes sense. So are you planning on installing it by simply curl-ing the bundle file from a tagged version from github? What if you want a different version of prettier? I guess it seems easier to be able to do |
Soooo, our npm story is a giant mess.
There are two main ways Nuclide deals with remote connections:
the great thing about prettier is that it's written in js so we don't have to worry about binaries not working on different architectures. And, we can bundle it into a single file and download it on the fly. For downloading from npm, we don't want to for security and stability reasons. We check in things inside of the repo. In practice, I would just take the bundled file from the release and check it in the repo. One last consideration is that whenever I upgrade the version, I'll need to codemod all the existing file with the new version, so that developers don't see warnings when they edit files that haven't changed but are pretty printed differently across revisions. Having a single file update means that I can do the codemod and upgrade in one diff. If it was a checked in npm source, the phabricator diff would be all garbage because of all the dependency changes and harder to review. |
I was wondering if you could generate the bundle outside of prettier, but I have experience with similar messy setups in Firefox. We had to do a lot of similar things and it was annoying. I'm fine having this in here so it's ready for others to use. Eventually we could also have a version that just has the API and can be used inside browsers too. Thanks for explaining -- it's good to know the constraints of your setup. If you rebase and fix the conflicts, we can merge this. We should also look into automating the release process a little better now too, since it's especially important to have this file up-to-date (maybe for now that's as simple as having a |
I've setup a separate project for this: https://github.com/vjeux/prettier-rpc We'll likely want to integrate it in the official project at some point but it should be easier to iterate on it outside of the main repo for now. |
Right now, doing
npm install
of prettier creates 3500 files, which is a pain to manage and to check in. Using the awesome rollup, we can easily bundle all the dependencies into a single big js file. This way I can just check-in a single file in fb codebase and update it when there's a new version.Performance-wise, it is currently 50ms slower than using ./bin/prettier. Both babylon and flow are taking roughly 30ms to parse and we only need a single one at a time. We can shave off 20ms by minifying the bundle but it breaks flow parser (this is why we don't have a flow option on the website!)
rollup doesn't support shebangs so I had to split the bin/prettier into two files, a dummy one with the shebang and I put the code inside of src:
src/cli.js
.Fixes #733