The Node.js® Website
at main 502 lines 31 kB view raw view rendered
1# Node.js Collaborator Guide 2 3- [Issues and Pull Requests](#issues-and-pull-requests) 4- [Accepting Modifications](#accepting-modifications) 5 - [Involving the Website Team](#involving-the-website-team) 6- [Technologies used in the Website](#technologies-used-in-the-website) 7- [Code editing](#code-editing) 8 - [Adding new pages](#adding-new-pages) 9 - [Create the page content](#create-the-page-content) 10 - [Translating pages](#translating-pages) 11- [Creating Components](#creating-react-components) 12 - [Styling a Component](#styling-a-component) 13 - [Best practices when creating a Component](#best-practices-when-creating-a-component) 14 - [How a new Component should look like when freshly created](#how-a-new-component-should-look-like-when-freshly-created) 15 - [Best practices for Component development in general](#best-practices-for-component-development-in-general) 16- [Unit Tests and Storybooks](#unit-tests-and-storybooks) 17 - [General Guidelines for Unit Tests](#general-guidelines-for-unit-tests) 18 - [General Guidelines for Storybooks](#general-guidelines-for-storybooks) 19- [Remarks on Technologies used](#remarks-on-technologies-used) 20- [Seeking additional clarification](#seeking-additional-clarification) 21 22This document contains information for Collaborators of the Node.js website project regarding maintaining the code, documentation, and issues. 23 24Collaborators should be familiar with the guidelines for new contributors in [CONTRIBUTING.md](./CONTRIBUTING.md). 25 26## Issues and Pull Requests 27 28Courtesy should always be shown to individuals submitting issues and pull requests to the Node.js website project. 29 30Collaborators should feel free to take full responsibility for managing issues and pull requests they feel qualified to handle, as long as this is done while being mindful of these guidelines, the opinions of other Collaborators and guidance of the Website Group. 31 32Collaborators may **close** any issue or pull request they believe is not relevant to the future of the Node.js project. 33Where this is unclear, the issue should be left open for several days for additional discussion. 34Where this does not yield input from Node.js Collaborators or additional evidence that the issue has relevance, then the issue may be closed. 35Remember that issues can always be re-opened if necessary. 36 37> \[!IMPORTANT]\ 38> We recommend Collaborators to avoid Updating/Rebasing PRs unnecessarily, since we use [GitHub Merge Queues](https://github.blog/2023-07-12-github-merge-queue-is-generally-available/) 39> to merge Pull Requests, which automatically rebases and runs CI-checks against the latest base branch. 40 41## Accepting Modifications 42 43All Node.js code and documentation modifications should be performed via GitHub pull requests. 44Only the Website Team can merge their work and should do so carefully. 45 46All pull requests must be reviewed and accepted by a Collaborator with sufficient expertise who can take full responsibility for the change. 47In the case of pull requests proposed by an existing Collaborator, an additional Collaborator is required for sign-off. 48 49Pull Requests can only be merged after all CI Checks have passed. 50As usual, CI Checks need to be manually triggered by adding a `github_actions:pull-request` label to the Pull Request. 51 52In some cases, it may be necessary to summon a qualified Collaborator to a pull request for review by @-mention. 53 54If you are unsure about the modification and are not prepared to take full responsibility for the change, defer to another Collaborator. 55 56We recommend collaborators follow the guidelines on the [Contributing Guide](./CONTRIBUTING.md#before-merging) for reviewing and merging Pull Requests. 57 58### Involving the Website Team 59 60Collaborators may opt to elevate pull requests or issues to the group for discussion by mentioning `@nodejs/nodejs-website`. This should be done where a pull request: 61 62- has a significant impact on the codebase, 63- is inherently controversial; or 64- has failed to reach a consensus amongst the Collaborators who are actively participating in the discussion. 65 66The Website group should be the final arbiter where needed. 67 68## Technologies used in the Website 69 70The Node.js Website is built upon [React][] and [Next.js][] respectively, the UI Rendering Engine and the Framework that builds the Website; 71 72The Website also uses several other Open Source libraries (not limited to) listed below: 73 74- Styling is done with [PostCSS][] and CSS Modules 75 - We use a combination of PostCSS plugins to create a [Sass](https://sass-lang.com/) alike environment 76 - We recommend reading the documentation of our plugins in case of doubt 77 - [PostCSS Mixins](https://github.com/postcss/postcss-mixins) 78 - [PostCSS Import](https://github.com/postcss/postcss-import) 79 - [PostCSS Simple Vars](https://github.com/postcss/postcss-simple-vars) 80- [Tailwind][] is used as our CSS Framework and the Foundation of our Design System 81- [Hero Icons](https://heroicons.com/) is an SVG Icon Library used within our Codebase 82- [Radix UI][] is a collection of customizable UI components 83- [Shiki][] is a Syntax Highlighter used for our Codeboxes 84 - The syntax highlighting is done within the processing of the Markdown files with the MDX compiler as a Rehype plugin. 85- [MDX][] and Markdown are used for structuring the Content of the Website 86- [`next-intl`][] is the i18n Library adopted within the Website 87 - It provides an excellent integration with Next.js, But it also supports standalone support for i18n if it eventually migrates from Next.js to something else. 88 - Supports React Server Components and Next.js Middlewares 89- [`next-sitemap`](https://www.npmjs.com/package/next-sitemap) is used for Sitemap and `robots.txt` Generation 90- We use [Rehype](https://github.com/rehypejs/rehype) and [Remark](https://github.com/remarkjs/remark) to extend MDX functionality 91- We use [Storybook](https://storybook.js.org/) for Manual Testing and Visual Regression Tests of our React Components 92 - Storybook also provides a sandboxed environment, which is very useful whilst for crafting React Components 93- We use [Sentry](https://sentry.io/about) for reporting Exceptions and monitoring the performance and reliability of the application 94 95## Code Editing 96 97### Structure of this Repository 98 99- React Components are defined on `/components` 100- React Templates are defined on `/layouts` 101- Global Stylesheets are declared on `/styles` 102 - Styles are done with [PostCSS][] 103- Public files are stored on `/public` 104 - Static Images, JavaScript files, and others are stored within `/public/static` 105- Internationalisation is done on `/i18n` 106 - React Localisation Data is stored within `/i18n/locales` 107 - We use the [ICU Message Syntax](https://formatjs.io/docs/core-concepts/icu-syntax/) for Translations 108 - Configuration for Locales is done within `/i18n/config.json` 109- Website Content is defined within `/pages` 110 - Initial development usually happens in English: `/pages/en` 111 - Localized versions of `/pages/en` are done within `/pages/{localeCode}` 112 - All content is in Markdown and is per locale. 113 - The top of each Markdown file is a YAML (Frontmatter) block for page-specific localization information passed to various templates. 114 - The bulk of the Markdown content for each page is referenced as `{children}` on their respective JSX Layout (`layouts/`) 115- Multi-Purpose React Hooks are defined on `/hooks` 116- Multi-Purpose TypeScript definitions are defined on `/types` 117- React Context Providers are defined on `/providers` 118- Build-time Data Fetching Scripts are defined on `/next-data` 119 - Used for Node.js Release data fetching 120 - Generation of build-time indexes such as blog data 121- Multi-Purpose Scripts are stored within `/scripts` 122 - Such as Node.js Release Blog Post generation 123- Storybook Configuration is done within `/.storybook` 124 - We use an almost out-of-the-box Storybook Experience with a few extra customisations 125 126### Adding new Pages 127 1281. Create new page content including the layout, title and copy. 1292. Update the relevant `/layout` to add a link to the new page. 130 131#### Create the page content 132 133Create a new markdown file in `/pages/en`. 134 135At the top of the markdown file, within the Markdown Frontmatter, set a page the title and layout. 136 137```markdown 138--- 139title: Title of the Page 140layout: layout-name 141--- 142 143[Content of the Page] 144``` 145 146> \[!NOTE]\ 147> A list of currently available Layouts is provided within `components/withLayout` on the `layoutComponents` map.\ 148> This is a temporary map and this map might change its location and be defined in a different way in the future. 149 150### Translating Pages 151 152See the [Translation Guidelines](./TRANSLATION.md) for the website translation policy. 153 154## Creating React Components 155 156The Node.js Website uses [React][] as a Frontend Library to develop the Website. 157React allows us to create user interfaces with a modern take on Web Development. 158 159If you're unfamiliar with React or Web Development in general, we encourage a read before taking on complex issues and tasks as this repository is **not for educational purposes** and we expect you to have a basic understanding of the technologies used. 160 161We also recommend getting familiar with technologies such as [Next.js][], [MDX][], [PostCSS][], and "concepts" such as "CSS Modules" and "CSS-in-JS". 162 163### Styling a Component 164 165As mentioned, we write all Component-styles in separate `.module.css` files. This is like writing any CSS in a separate file (besides the fact that we use [PostCSS][]). 166 167This concept of writing styles on dedicated CSS files and importing them within JavaScript (or React) is a pattern named **[CSS Module](https://github.com/css-modules/css-modules)**. 168These allow us to write PostCSS (or regular CSS, or any flavor of CSS if you have a way of interpreting it) within a `.module.css` and import the class names directly to our React Components. 169We recommend reading guides on "Styling React Components with CSS Modules", which there are many available on the web. 170 171It's important to mention that we use [Tailwind][] as a CSS Framework. Hence, margins, paddings, font sizes, font weights, colors, and other sorts of styles are all provided with Tailwind. 172We recommend reading [Tailwind Docs](https://tailwindcss.com/docs/preflight) to get familiar with Tailwind's styles. 173We also recommend reading [this guide for setting up Tailwind on your IDE](https://tailwindcss.com/docs/editor-setup). 174 175Finally, if you're unfamiliar with how to use Tailwind or how to use Tailwind within CSS Modules, we recommend reading [this guide](https://tailwindcss.com/docs/using-with-preprocessors). 176 177#### Example of a CSS Module 178 179```css 180.myComponent { 181 @apply some 182 tailwind 183 classes; 184} 185``` 186 187#### Guidelines when writing CSS 188 189- We use camelCase for defining CSS classes 190- We use Tailwind's `@apply` selector to apply Tailwind Tokens 191 - We discourage the usage of any plain CSS styles and tokens, when in doubt ask for help 192 - We require that you define one Tailwind Token per line, just as shown on the example above, since this improves readability 193- Only write CSS within CSS Modules, avoid writing CSS within JavaScript files 194- We recommend creating mixins for reusable animations, effects and more 195 - You can create Mixins within the `styles/mixins` folder 196 197> \[!NOTE]\ 198> Tailwind is already configured for this repository. You don't need to import any Tailwind module within your CSS module.\ 199> You can apply Tailwind Tokens with Tailwind's `@apply` CSS rule. [Read more about applying Tailwind classes with `@apply`](https://tailwindcss.com/docs/functions-and-directives#apply). 200 201> \[!IMPORTANT]\ 202> When using IDEs such as Visual Studio Code, we recommend installing the official [Stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) 203> and [Tailwind](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) Extensions.\ 204> These are recommended Extensions for IntelliSense, Syntax Highlighting and Error Checking when styling your Component. 205 206### Best practices when creating a Component 207 208- All React Components should be placed within the `components` folder. 209- Each Component should be placed, whenever possible, within a sub-folder, which we call the "Domain" of the Component 210 - The domain represents where these Components belong to or where they will be used. 211 - For example, Components used within Article Pages or that are part of the structure of an Article or the Article Layouts, 212 should be placed within `components/Article` 213- Each component should have its folder with the name of the Component 214- The structure of each component folder follows the following template: 215 ```text 216 - ComponentName 217 - index.tsx // the component itself 218 - index.module.css // all styles of the component are placed there 219 - index.stories.tsx // component Storybook stories 220 - __tests__ // component tests (such as unit tests, etc) 221 - index.test.mjs // unit tests should be done in ESM and not TypeScript 222 ``` 223- React Hooks belonging to a single Component should be placed within the Component's folder 224 - If the Hook as a wider usability or can be used by other components, it should be placed in the root `hooks` folder. 225- If the Component has "sub-components" they should follow the same philosophy as the Component itself. 226 - For example, if the Component `ComponentName` has a sub-component called `SubComponentName`, 227 then it should be placed within `ComponentName/SubComponentName` 228 229#### How a new Component should look like when freshly created 230 231```tsx 232import type { FC } from 'react'; 233 234import styles from './index.module.css'; 235 236type MyComponentProps = {}; // The types of the Props of your Component 237 238const MyComponent: FC<MyComponentProps> = ({ prop1, prop2... }) => ( 239 // Actual code of my Component 240); 241 242export default MyComponent; 243``` 244 245### Best practices for Component development in general 246 247- Only spread props `{ ... }` on the definition of the Component (Avoid having a variable named `props`) 248- Avoid importing `React`, only import the modules from React that you need 249- When importing types, use `import type { NameOfImport } from 'module'` 250- When defining a Component, use the `FC` type from React to define the type of the Component 251 - When using `children` as a prop, use the `FC<PropsWithChildren<MyComponentProps>>` type instead 252 - Alternatively you can define your type as `type MyComponentProps = PropsWithChildren<{ my other props }>` 253- Each Props type should be prefixed by the name of the Component 254- Components should always be the `default` export of a React Component file 255- Avoid using DOM/Web APIs/`document`/`window` API access within a React Component. 256 Use utilities or Hooks when you need a Reactive state 257- Avoid making your Component too big. Deconstruct it into smaller Components/Hooks whenever possible 258 259## Unit Tests and Storybooks 260 261Each new feature or bug fix should be accompanied by a unit test (when deemed valuable). 262We use [Jest][] as our test runner and [React Testing Library][] for our React unit tests. 263 264We also use [Storybook][] to document our components. 265Each component should have a storybook story that documents the component's usage. 266 267Visual Regression Testing is automatically done via [Chromatic](https://www.chromatic.com/) to ensure that Components are rendered correctly. 268 269### General Guidelines for Unit Tests 270 271Unit Tests are fundamental to ensure that code changes do not disrupt the functionalities of the Node.js Website: 272 273- Unit tests should be written as `.mjs` files. 274- We recommend adding unit tests for content covering `util`, `scripts`, `hooks`, and `components` whenever possible. 275- Unit Tests should ensure that a given change's functionality is working as expected. 276- When creating unit tests for React components, we recommend that the tests cover all the possible states of the component. 277- We also recommend mocking external dependencies, if unsure about how to mock a particular dependency, raise the question on your Pull Request. 278 - We recommend using [Jest's Mock Functions](https://jestjs.io/docs/en/mock-functions) for mocking dependencies. 279 - We recommend using [Jest's Mock Modules](https://jestjs.io/docs/en/manual-mocks) for mocking dependencies unavailable on the Node.js runtime. 280 - Common Providers and Contexts from the lifecycle of our App, such as [`react-intl`][] should not be mocked but given an empty or fake context whenever possible. 281- We recommend reading previous unit tests from the codebase for inspiration and code guidelines. 282 283### General Guidelines for Storybooks 284 285Storybooks are an essential part of our development process. They help us to document our components and to ensure that the components are working as expected. 286 287They also allow Developers to preview Components and be able to test them manually/individually to the smallest unit of the Application. (The individual Component itself). 288 289**Storybooks should be fully typed and follow the following template:** 290 291```tsx 292import type { Meta as MetaObj, StoryObj } from '@storybook/react'; 293import NameOfComponent from '@components/PathTo/YourComponent'; 294 295type Story = StoryObj<typeof NameOfComponent>; 296type Meta = MetaObj<typeof NameOfComponent>; 297 298// If the component has any props that are interactable, they should be passed here 299// We recommend reading Storybook docs for args: https://storybook.js.org/docs/react/writing-stories/args 300export const Default: Story = {}; 301 302// If the Component has more than one State/Layout/Variant, there should be one Story for each variant 303export const AnotherStory: Story = { 304 args: {}, 305}; 306 307export default { component: NameOfComponent } as Meta; 308``` 309 310- Stories should have `args` whenever possible, we want to be able to test the different aspects of a Component 311- Please follow the template above to keep the Storybooks as consistent as possible 312- We recommend reading previous Storybooks from the codebase for inspiration and code guidelines. 313- If you need to decorate/wrap your Component/Story with a Container/Provider, please use [Storybook Decorators](https://storybook.js.org/docs/react/writing-stories/decorators) 314 315## Remarks on Technologies Used 316 317The Node.js Website is a somewhat complex application and at times non-trivial solutions have been implemented to solve certain technical challenges. 318Historical decision making can be largely found on past issues, conversations on Slack and GitHub discussions. However, we also wish to highlight some of the notable development decisions that we have made here. 319 320### Why Next.js? 321 322We've found that Next.js is simply versatile, hackable, stable, community-maintained and has a great ecosystem. 323The reasoning goes deeper, but as a long-term Framework it is the most suitable choice. 324 325#### Why do we continue to support static builds? 326 327It was decided together with the TSC (Technical Steering Committee) that the Node.js Website should always support fully static builds that do not depend on any 3rd party services. 328This is to ensure that the Website is always available and that we do not depend on any 3rd party services to serve our content. 329 330(For example, if we abandon Vercel, our Website should still completely work as standalone as possible) 331 332#### What is `next.dynamic.mjs`? 333 334Our whole Website uses a custom renderer for rendering the pages. 335As you might have seen, within the `pages` directory we have [Next.js Dynamic Route](https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes) named `[...path].tsx` that matches against all possible routes of the Website. 336 337This means that each `.md(x)` file within `pages/` is not rendered by Next.js regular App Tree (`pages/_document.tsx` and `pages/_app.tsx`) but a custom render tree. 338 339This custom render uses `getStaticPaths` and [Incremental Static Generation](https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration) to generate the full list of supported pages of the Website. 340For example, this allows us to generate Localized Pages for every page that is not translated, by telling Next.js to create a localised path. 341`next.dynamic.mjs` is responsible for getting a full list of the source pages (`pages/en`) and identifying which pages have been translated. 342 343Non-translated pages will have their Localized contexts and translated React message-bags (`react-intl`) but the content will be the same as the source page (English). 344Whereas localized pages will have localized context and content. 345 346This custom solution is also able to decide what paths should be compiled during runtime. 347This is a combination of rules defined on `next.constants.mjs` and `[...path].tsx`. 348 349The `[...path].tsx` file ultimately utilizes the `theme.tsx` file as its layout source. 350This setup enables the loading of the Layout Provider and MDX Provider, which in turn, encapsulate and manage the rendering of any child content or components. This includes both content and components provided by the Layout Provider and the transformed MDX content originating from the `.md(x)` source page. 351 352#### What is `next.data.mjs`? 353 354This file is responsible for loading, fetching and generating build-time required information such as Node.js Release data, Blog Posts Metadata (for pagination and indexation), RSS feeds, etc. 355 356#### What is `site.json`? 357 358This file is used for defining Website Metadata, such as which RSS feeds should be generated, Social Media Information and other Metadata used during the Website build-time. 359We use a JSON format to ease collaboration. 360 361#### What is `next.locales.mjs` and why not use Next.js built-in i18n? 362 363While Next.js provides a built-in i18n feature, it doesn't offer the flexibility we require. Our specific needs include the ability to generate comprehensive lists of supported locales and pages for each locale. Additionally, we operate with a subfolder-based approach for content, as opposed to the extension-based approach (e.g., `filename.language.md(x)`) that is compatible with Next.js's built-in i18n. 364 365We opted for the subfolder approach to maintain consistency with our previous Node.js website's content structure and to ensure long-term maintainability, rather than relying on Next.js's i18n functionality. 366 367#### What is `next.rewrites.mjs`? 368 369This file is responsible for defining the rewrite rules for the Website. 370It is used for defining redirects and other rewrite rules. (Such as Internal Redirects and External ones). 371 372The `redirects.json` file specifies two types of operations: rewrites and redirects. 373 374- Rewrites: These operations do not alter the original URL but instead render the content from the rewritten URL. It's important to note that the rewritten URL path must be valid and exist on the website. 375- Redirects: Redirect operations, on the other hand, change the original URL to a new one. While these new URLs can be either internal (within the website) or external (leading to a different domain), it is more common for redirects to point externally. 376 377This file contains a simple template engine that supports `/:locale` to indicate that this path should also be available under all available locales as prefix. 378 379#### Why do we use Next.js Middlewares? 380 381We have a simple Next.js Middleware that is responsible for handling initial Locale detection and redirection. 382It detects browser locales and redirects to the most suitable locale for the user. And it fallbacks to `/en` if no suitable locale is found. 383 384#### What are Layouts? 385 386Layouts Wrap the content of the Markdown files. 387They are responsible for adding additional styling and structure surrounding the content of the Markdown files. 388 389Layouts are defined within the `layouts` folder. 390They are React Components that receive the `children` prop, which is the transformed MDX content of the Markdown file. 391 392Each Page layout is configured within their Markdown's Frontmatter as `layout: name-of-layout`. 393 394### How we style the Website? 395 396We use [PostCSS][] to style the Node.js Website; PostCSS is a CSS Preprocessor, like Sass and Less. 397 398#### How exactly do we style Components? 399 400We style each individual React Component with a dedicated CSS file (A CSS Module) that uses CSS syntax (with the extra powerups of PostCSS). 401 402The [Styling a Component](#styling-a-component) section contains a more detailed guide on how we style our Components. 403 404#### Why we use PostCSS over Sass or Less? 405 406The main advantage of PostCSS is its minimal pluggable API that allows us to extend the native CSS-syntax with custom plugins. 407 408Next.js natively supports PostCSS and always uses PostCSS as part of the bundling and building process. 409By not using Sass or Less we remove another dependency from our build process and remove one layer of preprocessing our styles (CSS). 410 411We currently use a set of PostCSS plugins that create a SCSS-a-like environment. 412 413#### What PostCSS Plugins we use? 414 415- `postcss-mixins`: Allows us to use Sass-like Mixins 416- `postcss-import`: Allows us to use Sass-like Imports 417- `postcss-simple-vars`: Allows us to use Sass-like Variables 418- `postcss-nested`: Allows us to use Sass-like Nesting 419- `postcss-calc`: Strips `calc` expressions and replaces them with the result 420 421It is important to mention that even though we use SCSS-like syntax, we do not use SCSS, and some of these plugins 422are not 100% compatible with the SCSS syntax. 423For example, `postcss-mixins` does not support `@include` and `@extend` directives (and it uses `@define-mixin` for defining Mixins and `@mixin` for including Mixins). 424 425#### Do we use a CSS Framework? 426 427The Node.js Website uses Tailwind as a CSS Framework for crafting our React Components and style the Website. 428 429[Tailwind][] is an utility-first CSS Framework. It allows us to create a Design System that is easy to maintain and extend. It also allows us to create a consistent Design Language across the Website. 430 431#### Font Families on the Website 432 433We use `next/fonts` Open Sans as the default font for the Node.js Website. 434The font is configured as a CSS variable and then configured on `tailwind.config.js` as the default font for the Website. 435 436#### Why we use RadixUI? 437 438- It is a minimalistic component library broken down in individual packages for each Component 439- It already handles all WAI-ARIA and Accessibility shortcuts/bindings needed for Interactive Elements 440- It allows us to focus on designing interactive Components without the effort of adding all the surrounding sugar and code needed to make the Component accessibility-friendly. 441 442### Why MDX? 443 444MDX is an extension on Markdown that allows us to add JSX Components within Markdown. 445Besides that, MDX is also a pluggable parser built on top of `unified` which supports Rehype and Remark Plugins. 446MDX is becoming the standard for parsing human-content on React/Next.js-based Applications. 447 448**Some of the plugins that we use include:** 449 450- `remark-gfm`: Allows us to bring GitHub Flavoured Markdown within MDX 451- `remark-headings`: Generates Metadata for Markdown Headings 452 - This allows us to build the Table of Contents for each Page, for example. 453- `rehype-autolink-headings`: Allows us to add Anchor Links to Markdown Headings 454- `rehype-slug`: Allows us to add IDs to Markdown Headings 455 456#### Syntax Highlighting (Shiki) and Vercel 457 458Shiki is integrated on our workflow as a Rehype Plugin, see the `next.mdx.shiki.mjs` file. We also use the `nord` theme for Shiki and a subset of the supported languages as defined on the `shiki.config.mjs` file. 459 460### Vercel 461 462We use Vercel as our hosting provider. It is a great platform that offers an excellent CI/CD pipeline which allows us to deploy our website with ease. 463 464It is important to mention that there are some rules on our Vercel Deployments such as: 465 466- Branches starting with `dependabot` (Dependabot Automated PRs) or `gh` (GitHub Merge Queues) are not deployed to Vercel. 467- Vercel Deployments are triggered for all other branches during `push` activities. 468- We have a custom install script that executes `npm ci --omit=dev` (the same way we do on our CI Pipelines) 469 - Hence if Builds fail unexpectedly, make sure that your dependency that is being used during build-time is on `dependencies` and not `devDependencies`. Checkout out [DEPENDENCY_PINNING.md](./DEPENDENCY_PINNING.md) for more information. 470- Our sponsorship with Vercel is maintained by the OpenJS Foundation 471 472### Why we have a `.vscode` folder 473 474The repository defines an optimized configuration for code editing. This is optional and is not required to contribute to the project. However, the settings and extensions specified help create a uniform and more efficient developer experience. This configuration is found in the `.vscode` directory: 475 476- `extensions.json` suggests VSCode extensions that make the editor more compatible with the code. For example, a Tailwind extension creates auto-complete intellisense for tailwind styles within our components. Eslint, prettier, and editorconfig extensions read their respective config files and automatically format or lint code as written. This helps save CI feedback loops when a contribution does not meet our standards. 477- `settings.json` contains some common sense defaults that aide development and enforce consistency across the codebase. For example, we want files formatted on save and we want prettier to be used as the formatter. Without these settings, new contributors may have different authoring experiences when contributing, leading to inconsistent code and CI failures. We also disable VSCode's default CSS parser so PostCSS and Tailwind syntax are respected. 478 479Defining a `.vscode` configuration like this also aides browser-only development using [GitHub's Codespaces feature](https://github.com/features/codespaces). The web-based GUI will read these same configuration files and setup the remote development environment the same way every time. 480 481### Why we have an `.npmrc` file 482 483The npm ecosystem resolution and installation of `peerDependencies` installation [changed in recent versions](https://nodejs.org/en/blog/npm/peer-dependencies#using-peer-dependencies). The project documents what version of `Node.js` and `npm` to use via the [`.nvmrc` file](https://github.com/nodejs/nodejs.org/blob/main/.nvmrc). Not all contributors have tooling to automatically read this file and adhere to the correct version, however. To ensure all contributors install dependencies the same way, a local `.npmrc` file directly configures peerDependency installation behavior. 484 485## Seeking additional clarification 486 487A lot of the current structure is due to retro-compatibility, keeping a simple and familiar file structure and keeping files that have historical reasons or needs. 488 489If you're unfamiliar or curious about something, we recommend opening a Discussion on this GitHub Repository. 490 491[Jest]: https://jestjs.io/ 492[React Testing Library]: https://testing-library.com/docs/react-testing-library/intro/ 493[Storybook]: https://storybook.js.org/ 494[`react-intl`]: https://formatjs.io/docs/react-intl/ 495[Next.js]: https://nextjs.org/ 496[MDX]: https://mdxjs.com/ 497[PostCSS]: https://postcss.org/ 498[React]: https://react.dev/ 499[Shiki]: https://github.com/shikijs/shiki 500[Tailwind]: https://tailwindcss.com/ 501[Radix UI]: https://www.radix-ui.com/ 502[`next-intl`]: https://www.npmjs.com/package/next-intl