Skip to content

Commit 1cd9122

Browse files
committed
feat: migrate examples from TSLint to ESLint - Remove all tslint.json files and TSLint dependencies - Add modern ESLint 9 flat config (eslint.config.js) to all examples - Update angular.json to use @angular-eslint/builder - Remove Jasmine dependencies from Jest examples to fix type conflicts - Clean up migration guide format and remove duplicate content All 7 examples now build and lint cleanly with Angular 20 and modern ESLint.
1 parent 807f468 commit 1cd9122

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1868
-1187
lines changed

MIGRATION.MD

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Migration from version 19 to version 20
22

3+
## Breaking Changes
4+
5+
### Node.js Version Requirements
6+
- **Minimum Node.js version is now 20.19.0** (previously 18.19.1)
7+
- Node.js 18 is no longer supported
8+
9+
### Example Projects: TSLint → ESLint Migration
10+
All example projects have been migrated from the deprecated TSLint to modern ESLint using Angular's official migration tools. If you're using these examples as reference, update your linting setup accordingly by running `ng add @angular-eslint/schematics`.
11+
312
## Custom ESBuild builder
413

514
1. The `forceEsbuild` property has been removed from the dev-server configuration. This property is no longer supported since the builder now uses `@angular/build` directly, which uses esbuild by default.
@@ -51,6 +60,8 @@
5160

5261
This enables more sophisticated plugins that can adapt their behavior based on the current build target and configuration.
5362

63+
3. **Migration to @angular/build:** The custom-esbuild package now uses `@angular/build` instead of `@angular-devkit/build-angular` for better performance and modern build tooling.
64+
5465
## Custom Webpack builder
5566

5667
- No breaking changes (except for updating to Angular 20)

examples/custom-esbuild/sanity-esbuild-app-esm/angular.json

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,18 @@
2929
"outputPath": "dist/sanity-esbuild-app-esm",
3030
"index": "src/index.html",
3131
"browser": "src/main.ts",
32-
"polyfills": ["zone.js"],
32+
"polyfills": [
33+
"zone.js"
34+
],
3335
"tsConfig": "tsconfig.app.json",
3436
"inlineStyleLanguage": "scss",
35-
"assets": ["src/favicon.ico", "src/assets"],
36-
"styles": ["src/styles.scss"],
37+
"assets": [
38+
"src/favicon.ico",
39+
"src/assets"
40+
],
41+
"styles": [
42+
"src/styles.scss"
43+
],
3744
"scripts": []
3845
},
3946
"configurations": {
@@ -99,28 +106,42 @@
99106
},
100107
"esm": {
101108
"buildTarget": "sanity-esbuild-app-esm:build:esm",
102-
"middlewares": ["esbuild/send-hello-middleware.js"]
109+
"middlewares": [
110+
"esbuild/send-hello-middleware.js"
111+
]
103112
},
104113
"cjs": {
105114
"buildTarget": "sanity-esbuild-app-esm:build:cjs",
106-
"middlewares": ["esbuild/send-hello-middleware.cjs"]
115+
"middlewares": [
116+
"esbuild/send-hello-middleware.cjs"
117+
]
107118
},
108119
"tsEsm": {
109120
"buildTarget": "sanity-esbuild-app-esm:build:tsEsm",
110-
"middlewares": ["esbuild/send-hello-middleware.ts"]
121+
"middlewares": [
122+
"esbuild/send-hello-middleware.ts"
123+
]
111124
}
112125
},
113126
"defaultConfiguration": "cjs"
114127
},
115128
"test": {
116129
"builder": "@angular-devkit/build-angular:karma",
117130
"options": {
118-
"polyfills": ["zone.js", "zone.js/testing"],
131+
"polyfills": [
132+
"zone.js",
133+
"zone.js/testing"
134+
],
119135
"tsConfig": "tsconfig.spec.json",
120136
"karmaConfig": "karma.conf.cjs",
121137
"inlineStyleLanguage": "scss",
122-
"assets": ["src/favicon.ico", "src/assets"],
123-
"styles": ["src/styles.scss"],
138+
"assets": [
139+
"src/favicon.ico",
140+
"src/assets"
141+
],
142+
"styles": [
143+
"src/styles.scss"
144+
],
124145
"scripts": []
125146
}
126147
},
@@ -164,13 +185,25 @@
164185
"watch": true,
165186
"headless": false
166187
}
188+
},
189+
"lint": {
190+
"builder": "@angular-eslint/builder:lint",
191+
"options": {
192+
"lintFilePatterns": [
193+
"src/**/*.ts",
194+
"src/**/*.html"
195+
]
196+
}
167197
}
168198
}
169199
}
170200
},
171201
"cli": {
172202
"analytics": false,
173-
"packageManager": "yarn"
203+
"packageManager": "yarn",
204+
"schematicCollections": [
205+
"angular-eslint"
206+
]
174207
},
175208
"schematics": {
176209
"@schematics/angular:component": {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// @ts-check
2+
import eslint from "@eslint/js";
3+
import tseslint from "typescript-eslint";
4+
import angular from "angular-eslint";
5+
6+
export default tseslint.config(
7+
{
8+
files: ["**/*.ts"],
9+
extends: [
10+
eslint.configs.recommended,
11+
...tseslint.configs.recommended,
12+
...tseslint.configs.stylistic,
13+
...angular.configs.tsRecommended,
14+
],
15+
processor: angular.processInlineTemplates,
16+
rules: {
17+
"@angular-eslint/directive-selector": [
18+
"error",
19+
{
20+
type: "attribute",
21+
prefix: "app",
22+
style: "camelCase",
23+
},
24+
],
25+
"@angular-eslint/component-selector": [
26+
"error",
27+
{
28+
type: "element",
29+
prefix: "app",
30+
style: "kebab-case",
31+
},
32+
],
33+
},
34+
},
35+
{
36+
files: ["**/*.html"],
37+
extends: [
38+
...angular.configs.templateRecommended,
39+
...angular.configs.templateAccessibility,
40+
],
41+
rules: {},
42+
}
43+
);

examples/custom-esbuild/sanity-esbuild-app-esm/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,16 @@
3030
"devDependencies": {
3131
"@angular-builders/custom-esbuild": "workspace:*",
3232
"@angular-devkit/build-angular": "20.0.2",
33+
"@angular-eslint/builder": "20.1.0",
3334
"@angular/cli": "20.0.2",
3435
"@angular/compiler-cli": "20.0.3",
3536
"@angular/language-service": "20.0.3",
37+
"@eslint/js": "^9.29.0",
3638
"@types/jasmine": "5.1.5",
3739
"@types/node": "20.17.12",
40+
"angular-eslint": "20.1.0",
3841
"cypress": "14.4.1",
42+
"eslint": "^9.29.0",
3943
"jasmine-core": "5.5.0",
4044
"karma": "6.4.4",
4145
"karma-chrome-launcher": "3.2.0",
@@ -44,6 +48,7 @@
4448
"karma-jasmine-html-reporter": "2.1.0",
4549
"puppeteer": "24.10.1",
4650
"ts-node": "10.9.2",
47-
"typescript": "5.8.3"
51+
"typescript": "5.8.3",
52+
"typescript-eslint": "8.34.0"
4853
}
4954
}

examples/custom-esbuild/sanity-esbuild-app-esm/tsconfig.app.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* To learn more about this file see: https://angular.io/config/tsconfig. */
22
{
3-
"extends": "./tsconfig.base.json",
3+
"extends": "./tsconfig.json",
44
"compilerOptions": {
55
"outDir": "./out-tsc/app",
66
"types": []

examples/custom-esbuild/sanity-esbuild-app-esm/tsconfig.base.json

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,33 @@
1-
/*
2-
This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language server to improve development experience.
3-
It is not intended to be used to perform a compilation.
4-
5-
To learn more about this file see: https://angular.io/config/solution-tsconfig.
6-
*/
1+
/* To learn more about this file see: https://angular.io/config/tsconfig. */
72
{
8-
"files": [],
9-
"references": [
10-
{
11-
"path": "./tsconfig.app.json"
12-
},
13-
{
14-
"path": "./tsconfig.spec.json"
15-
}
16-
]
3+
"compileOnSave": false,
4+
"compilerOptions": {
5+
"outDir": "./dist/out-tsc",
6+
"forceConsistentCasingInFileNames": true,
7+
"strict": true,
8+
"noImplicitOverride": true,
9+
"noPropertyAccessFromIndexSignature": true,
10+
"noImplicitReturns": true,
11+
"noFallthroughCasesInSwitch": true,
12+
"esModuleInterop": true,
13+
"sourceMap": true,
14+
"declaration": false,
15+
"downlevelIteration": true,
16+
"experimentalDecorators": true,
17+
"moduleResolution": "node",
18+
"importHelpers": true,
19+
"target": "ES2022",
20+
"module": "ES2022",
21+
"useDefineForClassFields": false,
22+
"lib": [
23+
"ES2022",
24+
"dom"
25+
]
26+
},
27+
"angularCompilerOptions": {
28+
"enableI18nLegacyMessageIdFormat": false,
29+
"strictInjectionParameters": true,
30+
"strictInputAccessModifiers": true,
31+
"strictTemplates": true
32+
}
1733
}

examples/custom-esbuild/sanity-esbuild-app-esm/tsconfig.spec.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* To learn more about this file see: https://angular.io/config/tsconfig. */
22
{
3-
"extends": "./tsconfig.base.json",
3+
"extends": "./tsconfig.json",
44
"compilerOptions": {
55
"outDir": "./out-tsc/spec",
66
"types": [

examples/custom-esbuild/sanity-esbuild-app/angular.json

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,18 @@
2929
"outputPath": "dist/sanity-esbuild-app",
3030
"index": "src/index.html",
3131
"browser": "src/main.ts",
32-
"polyfills": ["zone.js"],
32+
"polyfills": [
33+
"zone.js"
34+
],
3335
"tsConfig": "tsconfig.app.json",
3436
"inlineStyleLanguage": "scss",
35-
"assets": ["src/favicon.ico", "src/assets"],
36-
"styles": ["src/styles.scss"],
37+
"assets": [
38+
"src/favicon.ico",
39+
"src/assets"
40+
],
41+
"styles": [
42+
"src/styles.scss"
43+
],
3744
"scripts": []
3845
},
3946
"configurations": {
@@ -88,24 +95,36 @@
8895
},
8996
"esm": {
9097
"buildTarget": "sanity-esbuild-app:build:esm",
91-
"middlewares": ["esbuild/send-hello-middleware.mjs"]
98+
"middlewares": [
99+
"esbuild/send-hello-middleware.mjs"
100+
]
92101
},
93102
"cjs": {
94103
"buildTarget": "sanity-esbuild-app:build:cjs",
95-
"middlewares": ["esbuild/send-hello-middleware.js"]
104+
"middlewares": [
105+
"esbuild/send-hello-middleware.js"
106+
]
96107
}
97108
},
98109
"defaultConfiguration": "cjs"
99110
},
100111
"test": {
101112
"builder": "@angular-devkit/build-angular:karma",
102113
"options": {
103-
"polyfills": ["zone.js", "zone.js/testing"],
114+
"polyfills": [
115+
"zone.js",
116+
"zone.js/testing"
117+
],
104118
"tsConfig": "tsconfig.spec.json",
105119
"karmaConfig": "karma.conf.js",
106120
"inlineStyleLanguage": "scss",
107-
"assets": ["src/favicon.ico", "src/assets"],
108-
"styles": ["src/styles.scss"],
121+
"assets": [
122+
"src/favicon.ico",
123+
"src/assets"
124+
],
125+
"styles": [
126+
"src/styles.scss"
127+
],
109128
"scripts": []
110129
}
111130
},
@@ -145,13 +164,25 @@
145164
"watch": true,
146165
"headless": false
147166
}
167+
},
168+
"lint": {
169+
"builder": "@angular-eslint/builder:lint",
170+
"options": {
171+
"lintFilePatterns": [
172+
"src/**/*.ts",
173+
"src/**/*.html"
174+
]
175+
}
148176
}
149177
}
150178
}
151179
},
152180
"cli": {
153181
"analytics": false,
154-
"packageManager": "yarn"
182+
"packageManager": "yarn",
183+
"schematicCollections": [
184+
"angular-eslint"
185+
]
155186
},
156187
"schematics": {
157188
"@schematics/angular:component": {

0 commit comments

Comments
 (0)