MDN's next fr(ont)e(n)d.
- Copy
.env-dist
to.env
and update - Install dependencies
npm install
- In one terminal window, start the backend:
node --env-file=.env --run rari -- serve
- In another terminal window, start the frontend:
- Run local dev server
npm run dev
- Open
http://localhost:3000/en-US/
to see the homepage
Note
If you already have another local server running on port 3000, fred will use the next available port (e.g. 3001).
- Components should live in the
components/
folder, with reserved names which cause certain behavior, explained further below:component-name/
global.css
- (reserved): automatically added to global styleselement.js
- (reserved): custom element, automatically imported client side, always imported server sideelement.css
- (recommended): styles for custom element's shadow domserver.js
- (reserved): server component, will automatically load the adjacentserver.css
file when usedserver.css
- (reserved): automatically added to page styles when its server component is used in that page
global.css
: components which have CSS which should be loaded on all pages should expose that through aglobal.css
file:- This should be used sparingly, use it for things needed in almost all components, like colors, fonts, etc.
- Or, when creating a custom element, use it to set the "browser default" styles on that custom element: usually as simple as just
mdn-component-name { display: block; }
or similar
element.js
: custom elements should be defined incomponents/component-name/element.js
- The class should be exported, and named
MDNComponentName
- Acronyms should be kept all caps, to match the naming of
HTMLElement
class names, and added toACRONYMS
inbuild/plugins/generate-element-map.js
to allow the correct types to be generated
- Acronyms should be kept all caps, to match the naming of
- The element should be registered with a name of
mdn-component-name
- If all this is done:
- The element will be automatically loaded client side if it's present in the DOM at page load
- Elements inserted client side (i.e. in a hook, or another custom element) won't be automatically loaded, and the hook should handle loading them: probably with an async
import()
- Elements inserted client side (i.e. in a hook, or another custom element) won't be automatically loaded, and the hook should handle loading them: probably with an async
- The element will be automatically loaded server side for SSR
- The element will automatically be added to
types/element-map.d.ts
to provide proper types in e.g.querySelector("mdn-component-name")
- The element will be automatically loaded client side if it's present in the DOM at page load
- The class should be exported, and named
server.js
: server components should be defined incomponents/component-name/server.js
- The class should extend
ServerComponent
fromcomponents/server/index.js
, and be namedComponentName
- The class should extend
server.css
: server component styles should be placed incomponents/component-name/server.css
- These will be automatically loaded server side when the adjacent
ServerComponent
is used- Therefore, these styles should be scoped to the component, usually with a wrapping class
- These will be automatically loaded server side when the adjacent
- We use TypeScript in JSDoc annotations for typing, so we can write and directly execute JavaScript (with no transpilation step)
- We occasionally use TypeScript files directly for writing types/interface which are too complex to easily write in JSDoc
- Eventually we'll have a fully typed codebase, with no errors: while we're in active development we can ignore errors in the interest of development speed/pragmatism:
- If we do so, we should use
// @ts-expect-error
so we get an error when we fix the error and don't leave unnecessary// @ts-ignore
comments lying around. While we're in active development these can lack a comment, but eventually we'll require an explanatory comment on each.
- If we do so, we should use