Everything a developer changes on a Core dna site lives in its theme repository. This guide covers the repository and its build, printing records in templates, stylesheets and client-side code, and the parts of a site around the main content.
L1–L2
Unit 04 · Client-side code
TypeScript in a theme
Client-side codePage 25 of 35Updated
TypeScript fits a theme's webpack build with ts-loader and strict checking. The setup two production repositories use, the one boundary worth typing carefully (data a template prints for scripts to read), why an empty value arrives as an empty array, and how strict to be where.
Who this is for. The developer starting TypeScript in a theme, or working in one that has it. Afterwards you can set it up the way production repositories do, type the data that crosses from template to script, and know where strictness pays and where it gets in the way.
The setup
Two production repositories compile TypeScript in their webpack build with ts-loader. The larger turns on full strict checking ("strict": true) and keeps plain JavaScript files beside the TypeScript ones, giving them to babel-loader:
With these rules, .js files are transpiled by Babel and never type-checked, whatever allowJs says: the checking happens in ts-loader, which sees only .ts. Converting a file is renaming it and fixing what the compiler reports. tsconfig.json is never served, so it is safe to commit.
The boundary worth typing: data from templates
The platform's data reaches a theme's scripts in two ways: through the APIs, and printed into the page by a template. The second is where types matter most: type it in one module, since the template hands the data across as plain JSON. Print each hand-off once, as JSON, in one include:
Every field optional. Site data is edited in the admin without a deploy; any key can be missing on any environment.
An empty value arrives as []. PHP has one type for lists and maps, and an empty one is encoded as a JSON array, in both engines. Twig's {} becomes the same empty PHP array. Normalise it once, as above, rather than in every caller.
Values arrive as stored. A switch can be true or "1", a number can be a string. Type what the template really prints, and convert at the boundary.
How strict to be
Strict in your own modules, where the compiler can see both sides of every call. Loose, and checked at run time, at the boundaries: the template hand-off, API responses, and third-party globals such as a tag manager's dataLayer. Typing an API response as exactly what you expect only moves the failure from the compiler to the visitor; type it as possibly missing and handle the missing case.