Architecture and others
The point of Vulcan Next is to bring everything you need to setup a scalable application, in terms of number of users but also in terms of code. Here is what Vulcan includes:
TypeScriptβ
TypeScript in Nextβ
We use TypeScript extensively, and try to enable it wherever possible (sources, Jest, Cypress, Storybook...).
Scripts written in TypeScriptβ
What's more annoying than writing an utility script, for instance to clean your database, and being forced to use JavaScript or even worse, bash scripts :(!
We have created a command yarn run build:scripts that builds files from .vn/scripts/ts-sources into reusable .js scripts. You can reuse
your code utilities within those scripts. The build script is based on Tsup. It used to be based on Vercel ncc builder, which is however more suited for fully reusable scripts (outside of Vulcan).
Multiple tsconfig via folder nestingβ
The src folder has its own tsconfig.json: this way collocated files like Stories and Unit tests are correctly handled by your text editor, but they can be excluded from the root tsconfig.json to avoid bloating Next.js build.
Code architecture and build systemβ
Code in srcβ
All your code should go into the /src directory (doc).
This folder structure is officially supported by Next. It is relevant when you have a lot of development tooling alongside your actual codebase, like we do in Vulcan.
Package-oriented architectureβ
The structure of a plugin system of Next is still under discussion. In the meantime, we strive to provide code as clean as possible, structured in package, so you can easily remove prebundled features.
To do so, we currently use a Webpack config so folders in packages/@vulcanjs can be imported the same way as node_modules. For instance, packages/@vulcanjs/next-utils can be imported as import "@vulcanjs/next-utils" in your code.
You can reproduce the same behaviour with any other prefix by changing tsconfig.common.json
However, you are not forced to structure your own code as packages. Avoid Hasty Abstractions!
Full-stack NPM packages (advanced)β
If you want real NPM packages, you might want to discover the Vulcan NPM monorepository where we actually develop Vulcan.
Magic src imports with ~β
Import code in src from anywhere by writing import "~/components/foobar".
Relative imports are a huge mess to support. A relative import should never go further than the category it belongs too: pages should never have to import components using a messy ../../../components/myComponent.
Quasi-imorphismβ
We allow folders and packages to contain an index.client or index.server file, that will be used at build time depending on the environment.
/!\ You still need to have a bare index file alongside those environment specific file. Otherwise TypeScript will complain (see the "Learnings" documentation for more details).
Env variables in .envβ
Since Next.js 9.4, .env files contain configuration. Open .env.development to see the default development variables.
Check our article to learn more about configuration in Next.js
Variousβ
Passing package.json info to the client appβ
In next.config.js, you'll find a demonstration of how to safely inject informations from your package.json into your Next application.
For example, we use it to inject current version into the html tag for better deployment tracking.
Sitemap.xml and Robots.txt with next-sitemapβ
We use next-sitemap to create both the robots.txt and sitemap.xml in the postbuild script. Change https://vulcan.next to your root url in /vulcan-next-sitemap.js. Here's more configuration options.
Auto-changelogβ
Run yarn auto-changelog to compute a new changelog. Works best in combination with yarn version (to create git version tags automatically) and git merge --no-ff your-feature (to get merge commits).
Design system best practicesβ
Based on Emma Bostian's course on Frontend Masters, we include basic examples and libraries to get you started writing a design system for your UI. This means:
- An example of a styled button, with Material UI and Styled Components
- A modal example
- Animations with react-spring
- A powerful Storybook configuration
See src/components/ui for the code, and run Storybook to see the demos.
No more excuses to make dull UIs, you have all the tools you need :)
Debuggingβ
Performance debuggingβ
DEBUG=vns:perf npm run dev
Webpack bundle analyzerβ
Run yarn run analyze-bundle to get insight on your Webpack build.
Deploymentβ
Dockerfile for productionβ
See build:docker command.
Dockerfile for Cypressβ
Running Cypress in Docker makes it easier to run your tests locally, while you keep coding. You can also use this file for your CI/CD process.
3rd party tooling as optional dependenciesβ
As a default, Jest, Cypress, Storybook and any other 3rd party tooling is installed as optional dependencies.
- "dependencies" is what your app need to run
- "devDependencies" is what your app need to be built
- "optionalDependencies" is everything else
Package.json naming convention are not intuitive and do not allow for a clean, environment-based distinction between packages. So that's the best we could do!