engineering grouparoo next.js node.js
2021-06-03 - Originally posted at https://www.grouparoo.com/blog/distributing-nextjs-via-npm
↞ See all posts
Grouparoo uses Next.js to build our web frontend(s), and we distribute these frontend User Interfaces (UIs) via NPM as packages, e.g. @grouparoo/ui-community
. This allows Grouparoo users to choose which UI they want to use (or none) by changing their package.json
:
Example package.json
for a Grouparoo project:
1{ 2 "author": "Your Name <email@example.com>", 3 "name": "grouparoo-application", 4 "description": "A Grouparoo Deployment", 5 "version": "0.0.1", 6 "dependencies": { 7 "@grouparoo/core": "0.3.3", 8 "@grouparoo/postgres": "0.3.3", 9 "@grouparoo/mailchimp": "0.3.3", 10 "@grouparoo/ui-community": "0.3.3" // <-- Choose UI Package to install 11 }, 12 "scripts": { 13 "start": "cd node_modules/@grouparoo/core && ./bin/start" 14 }, 15 "grouparoo": { 16 "plugins": [ 17 "@grouparoo/postgres", 18 "@grouparoo/mailchimp", 19 "@grouparoo/ui-community" // <-- Choose UI Package to load 20 ] 21 } 22}
Here is how we bundle up our Next.js applications so that our customers can use them out of the box.
next build
and npm run prepare
The first step in “compiling” your Next.js projects is to use the next build
command. We alias this to the “prepare” npm lifecyle command so that this command will be run automatically before npm publish
. In this way we can ensure that we always have a freshly built bundle to use when we publish our packages.
This is different from Next’s recommendation to alias next build
to npm build
because we are not “deploying” our sites - we are publishing them. Many hosting providers look for a build
script in your pacakge.json
to run when the deploy, hence Next.js’ recommendation.
.npmignore
vs .gitignore
The next step in bundling up a Next.js application for deployment via NPM is to include the build files. In all Next.js projects, you want to ignore the .next
folder in your .gitignore
. The .next
folder is where Next.js keeps all the build artifacts it creates — minified javascript, css chunks, etc. Assuming your “source code” is Typescript and SCSS, everything in the .next
folder should be ignored, and rebuilt as needed from the source.
BUT… the content of .next
is actually what the visitors to your site really load - that’s the HTML, CSS, and Javascript that ends up in the browser. Since we are trying to package up a usable site, we need to bundle the contents of .next
into our NPM bundles. However, we still want to exclude these rapidly changing files from git
’s history.
The solution is a .npmignore
file! By default, NPM will use a .gitignore
file to determine which files it packs up into your packages, and which files it ignores. But, you can override this behavior by placing a .npmignore
in your project. For example:
.gitignore
.DS_Store
node_modules
.next
.npmignore
.DS_Store
node_modules
# .next is included
.pack
filesThe final thing we learned is that while the contents of the .next
directory are needed for your visitors, not everything is needed. We saw that we were shipping 300mb packages to NPM for our Next.js UIs. We dug into the .next
folder and learned that if you opt-into Webpack v5 for your Next.js site, large .next/cache/*.pack
files will be created to speed up how Webpack works. This is normal behavior, but we were inadvertently publishing these large files to NPM! We added the .next/cache/*
directory to our .npmignore
and our build sizes went down to a more reasonable 20mb.
Our final .npmignore
looks like this:
.npmignore
.DS_Store
node_modules
.next/cache/*
I write about Technology, Software, and Startups. I use my Product Management, Software Engineering, and Leadership skills to build teams that create world-class digital products.
Get in touch