Repository navigation
Add TypeScript foundation and upgrade build tooling - #3794
Merged
Merged
Conversation
Vondry
force-pushed
the
chore/typescript-foundation
branch
from
August 14, 2026 08:34
b408864 to
b4dd35d
Compare
Contributor
Author
|
I created follow up #3797 with test setup. |
Contributor
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
trim() still throws for some non-string values despite the stated behavior guarantee.
Review effort: Balanced
Findings: None
What changed in this PR
Adds a TypeScript foundation while retaining the Vue 2.7 application architecture and existing component behavior.
Changes:
- Upgrades Encore and related frontend tooling.
- Adds strict TypeScript compilation, linting, and CI checks.
- Converts filters and API helpers to TypeScript, replacing global Vue filters with direct imports.
| File | Description |
|---|---|
webpack.config.js |
Enables Vue 2.7 and TypeScript loaders. |
tsconfig.json |
Defines strict TypeScript settings. |
package.json |
Upgrades tooling and adds TypeScript dependencies/scripts. |
package-lock.json |
Locks upgraded frontend dependencies. |
eslint.config.mjs |
Adds TypeScript linting. |
assets/js/version.js |
Updates generated-file formatting. |
assets/js/services/api/dashboardNews.ts |
Converts dashboard news helpers to TypeScript. |
assets/js/services/api/dashboardNews.js |
Removes the JavaScript implementation. |
assets/js/services/api/content.ts |
Converts cached-content access to TypeScript. |
assets/js/services/api/content.js |
Removes the JavaScript implementation. |
assets/js/filters/string.ts |
Converts string filters into typed exports. |
assets/js/filters/date.ts |
Converts date filters into typed exports. |
assets/js/filters/index.ts |
Exports typed filter helpers. |
assets/js/filters/index.js |
Removes global filter registration entry point. |
assets/js/bolt.js |
Stops loading global Vue filters. |
assets/js/app/listing/Components/Table/Row/index.vue |
Uses imported string helpers. |
assets/js/app/listing/Components/Table/Row/_Meta.vue |
Uses the imported date helper. |
assets/js/app/listing/Components/Table/Row/_Actions.vue |
Uses imported date and trim helpers. |
assets/js/app/editor/Components/Slug.vue |
Uses the imported slug helper. |
assets/js/app/editor/Components/Select.vue |
Uses the imported raw helper. |
assets/js/app/editor/Components/Markdown.vue |
Uses the imported strip helper. |
assets/js/app/editor/Components/Html.vue |
Uses the imported strip helper. |
.github/workflows/assets_code_analysis.yaml |
Adds TypeScript checking to CI. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
bobvandevijver
requested changes
Sep 26, 2026
bobvandevijver
force-pushed
the
chore/typescript-foundation
branch
from
September 26, 2026 14:23
b4dd35d to
6c9c25a
Compare
Member
|
@Vondry already rebased for you, when those small changes have been made it can be merged 👍🏻 |
Contributor
Author
Great, should be ready now. |
First step of the staged Vue 3 / TypeScript migration. Introduces TypeScript on the existing Vue 2.7 codebase without touching any component logic, so the eventual framework swap lands as a much smaller, mechanical change. Build tooling: - Upgrade @symfony/webpack-encore 1.8.2 -> 4.7.0. 4.7 is the last release supporting Vue 2; Encore 5.0 dropped it. The version option of enableVueLoader() is deliberately omitted: it only accepts 2 or 3, and passing 2 selects the target that still requires vue-template-compiler. Left unset, Encore detects vue@2.7 and picks its "vue2.7" target, which uses the SFC compiler Vue 2.7 ships itself, so vue-template-compiler is no longer needed. - Bump sass-loader 9 -> 14 and postcss-loader 4 -> 8 to match Encore 4.7's peer ranges, and add webpack and webpack-cli as explicit dependencies as Encore 4 requires. - Drop @babel/plugin-transform-regenerator and @babel/plugin-transform-runtime, which were declared but unreferenced. TypeScript: - Add tsconfig.json with strict plus noImplicitReturns, noFallthroughCasesInSwitch, noImplicitOverride, isolatedModules, allowUnreachableCode false and allowUnusedLabels false. The include list is .ts/.d.ts only; the SFCs have no lang="ts" yet, so they are not type-checked until they move to <script setup lang="ts"> and the checker becomes vue-tsc. - Add typescript 6, ts-loader and @types/luxon, wire ts-loader through Encore.enableTypeScriptLoader(), and add a typecheck script plus a CI step running it. - Scope typescript-eslint to assets/**/*.ts so the Vue 2 SFCs keep being linted by the vue2 preset. Filters: - Convert assets/js/filters and assets/js/services/api to TypeScript. - Replace the Vue 2 global filters, removed in Vue 3, with directly imported functions at all 13 call sites across 7 components. Return types are inferred rather than annotated. Behaviour is unchanged apart from trim(), strip() and uppercase() no longer throwing a TypeError on null or non-string input. Values that previously rendered are unaffected: trim() still passes non-strings through untouched instead of coercing them, so numbers are not truncated and objects do not become "[object Object]".
The filters are imported directly from ./date and ./string at every call site, and bolt.js no longer imports ./filters to register them as Vue filters, so nothing references the index.
Drop the unknown-typed locals in getRecords(), getNews() and fetchNews(). The callers are still plain JS SFCs, so narrowing the return type to unknown bought nothing yet; the proper types come with the component conversion.
Keep the Encore chain in its previous order and append the TypeScript loader at the end, dropping the explanatory comments, so the diff against master stays minimal.
Vondry
force-pushed
the
chore/typescript-foundation
branch
from
September 28, 2026 05:52
98e2902 to
78f2818
Compare
bobvandevijver
approved these changes
Sep 28, 2026
Member
|
Thank you @Vondry! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add TypeScript foundation and upgrade build tooling
Second step of the Vue 3 / TypeScript migration, which adds TypeScript to the existing Vue 2.7 codebase without touching component logic
Changes
sass-loader14 andpostcss-loader8, and dropsvue-template-compiler.tsconfig.json(strict,.ts-only include),ts-loaderviaenableTypeScriptLoader(),npm run typecheck+ a CI step, andtypescript-eslintscoped toassets/**/*.ts.Vue.filter()/$options.filters, both removed in Vue 3) replaced with direct imports at all 13 call sites.Review notes
enableVueLoader()'sversionoption is deliberately omitted. It only accepts2or3, and2selects the target that still requiresvue-template-compiler. Unset, Encore detectsvue@2.7and uses the SFC compiler Vue 2.7 ships itself.lang="ts". That comes when they move to<script setup lang="ts">and the checker becomesvue-tsc.Behaviour
Unchanged, except
trim(),strip()anduppercase()no longer throw aTypeErroronnull/non-string input. Values that previously rendered are unaffected —trim()still passes non-strings through untouched rather than coercing, so numbers aren't truncated and objects don't become[object Object].Verified by diffing the compiled render functions of all changed SFCs, and by a 348-case differential harness against the pre-migration implementations.
Next
Vitest + tests for the converted filters, then components to Composition API.
Testing
I manually clicked through the admin pages and verified that they work as previously