Skip to content

Commit ab92862

Browse files
authored
feat!: add support for Angular v17 (#67)
* feat: update plugin + demo to ng17 * chore: delete "advanced-routing" example * chore: reintroduce old demo contents * feat: also exclude prerendered routes * chore: delete one more file * fix: prettier * chore: update engine * fix: validate angular version * fix: install package locally * fix: add npm i for package to fix nf build * fix: make build * fix: custom ignore command * chore: update logo * fix: windows doesnt understand # * chore: update readme * fix: update release-please statements * chore: replace commonmodule with v17 builtins * feat: inject request/context * fix: update eslint * fix: license, author * chore: comment about polyfill.mjs * fix: ensure ts imports are posix * chore: fail plugin instead of build * fix: skip instead of failing * fix: base64-encode html * fix: use package name and version for generator * fix: use require.resolve to find angular version * feat: detect old version of plugin * Revert manual version bump * fix: detect when no SSR was set up * fix: until we found a way to run edge functions during dev, remove them * fix: make edge function run locally * chore: note down limitation about netlify serve * fix: update project name in code snippet
1 parent d3f0b1d commit ab92862

File tree

98 files changed

+22896
-73093
lines changed

Some content is hidden

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

98 files changed

+22896
-73093
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
test
3+
README.md

.eslintrc.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
const { overrides } = require('@netlify/eslint-config-node/react_config')
1+
const { overrides } = require('@netlify/eslint-config-node')
22

33
module.exports = {
4-
extends: '@netlify/eslint-config-node/react_config',
4+
extends: '@netlify/eslint-config-node',
55
rules: {
66
'max-depth': 0,
77
complexity: 0,

.github/workflows/release-please.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ jobs:
1616
with:
1717
token: ${{ steps.get-token.outputs.token }}
1818
release-type: node
19-
package-name: '@netlify/plugin-angular-universal'
19+
package-name: '@netlify/angular-runtime'

.netlify/state.json

-3
This file was deleted.

.prettierrc.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
const eslintConfig = require('@netlify/eslint-config-node/.prettierrc.json')
2+
13
module.exports = {
2-
...require('@netlify/eslint-config-node/.prettierrc.json'),
4+
...eslintConfig,
35
endOfLine: 'auto',
46
}
File renamed without changes.

LICENSE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2021 Luke Oliff
3+
Copyright (c) 2023 Netlify
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy of
66
this software and associated documentation files (the "Software"), to deal in

README.md

+38-42
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,43 @@
1-
![Netlify Build plugin Angular Universal – Run Angular Universal seamlessly on Netlify](netlify-plugin-angular.png)
1+
![Netlify Angular Runtime – Run Angular seamlessly on Netlify](netlify-plugin-angular.png)
22

3-
# Angular Universal Plugin
3+
# Angular Runtime
44

55
<p align="center">
6-
<a aria-label="npm version" href="https://www.npmjs.com/package/@netlify/plugin-angular-universal">
7-
<img alt="" src="https://img.shields.io/npm/v/@netlify/plugin-angular-universal">
6+
<a aria-label="npm version" href="https://www.npmjs.com/package/@netlify/angular-runtime">
7+
<img alt="" src="https://img.shields.io/npm/v/@netlify/angular-runtime">
88
</a>
9-
<a aria-label="MIT License" href="https://img.shields.io/npm/l/@netlify/plugin-angular-universal">
9+
<a aria-label="MIT License" href="https://img.shields.io/npm/l/@netlify/angular-runtime">
1010
<img alt="" src="https://img.shields.io/badge/License-MIT-yellow.svg">
1111
</a>
1212
</p>
1313

14-
This build plugin is a utility for supporting Angular Universal on Netlify.
14+
This build plugin implements Angular Support on Netlify.
1515

1616
## Table of Contents
1717

1818
- [Installation and Configuration](#installation-and-configuration)
19+
- [Accessing `Request` and `Context` during Server-Side Rendering](#accessing-request-and-context-during-server-side-rendering)
1920
- [CLI Usage](#cli-usage)
20-
- [Caveats](#caveats)
2121
- [Getting Help](#getting-help)
2222
- [Contributing](#contributing)
2323
- [License](#license)
2424

2525
## Installation and Configuration
2626

27+
Netlify automatically detects Angular projects and sets up the latest version of this plugin. There's no further configuration needed from Netlify users.
28+
2729
### Manual Installation
2830

31+
If you need to pin down this plugin to a fixed version, install it manually.
32+
2933
Create a `netlify.toml` in the root of your project. Your file should include the plugins section below:
3034

3135
```toml
32-
[build]
33-
command = "ng build --configuration production && ng run {projectName}:serverless:production"
34-
publish = "dist/{projectName}/browser"
35-
3636
[[plugins]]
3737
package = "@netlify/plugin-angular-universal"
3838
```
3939

40-
If you'd like to install this plugin at a fixed version, install it via your package manager:
40+
Install it via your package manager:
4141

4242
```bash
4343
npm install -D @netlify/plugin-angular-universal
@@ -48,46 +48,42 @@ yarn add -D @netlify/plugin-angular-universal
4848
Read more about [file-based plugin installation](https://docs.netlify.com/configure-builds/build-plugins/#file-based-installation)
4949
in our docs.
5050

51-
## CLI Usage
52-
53-
### Requirements
54-
55-
To use the Angular Universal plugin while building and deploying with the CLI, you need to have `netlify-cli v5.4.13` installed (or a later version).
56-
57-
Please also make sure to use `ntl deploy --build --prod` (rather than `ntl build`).
51+
## Accessing `Request` and `Context` during Server-Side Rendering
5852

59-
### Plugin Side Effects
53+
During server-side rendering (SSR), you can access the incoming `Request` object and the Netlify-specific `Context` object via providers:
6054

61-
When this plugin is run as part of the build process using the Netlify CLI, direct changes will be made to your project source:
55+
```ts
56+
import type { Context } from "@netlify/edge-functions"
6257

63-
1. It will modify your angular.json to add a `serverless` project configuration.
64-
2. It will add `serverless.ts` and `tsconfig.serverless.json` files.
58+
export class FooComponent {
6559

66-
It is up to you whether to commit these changes to your project. If the plugin makes updates to these files or configurations, it will overwrite what you'd previously committed, and you can commit the new updates. Otherwise, you can stash and ignore them.
60+
constructor(
61+
// ...
62+
@Inject('netlify.request') @Optional() request?: Request,
63+
@Inject('netlify.context') @Optional() context?: Context,
64+
) {
65+
console.log(`Rendering Foo for path ${request?.url} from location ${context?.geo?.city}`)
66+
// ...
67+
}
68+
69+
}
70+
```
6771

68-
### Workflow
72+
Keep in mind that these will not be available on the client-side or during [prerendering](https://angular.dev/guide/prerendering#prerendering-parameterized-routes).
6973

70-
If you'd like to build and deploy your project using the
71-
[Netlify CLI](https://docs.netlify.com/cli/get-started/), we recommend this
72-
workflow to manage git tracking plugin-generated files:
74+
To test this in local development, run your Angular project using `netlify serve`:
7375

74-
1. Make sure all your project's files are committed before running a build with
75-
the CLI
76-
2. Run any number of builds and deploys freely (i.e. `netlify build`,
77-
`netlify deploy --build`, `netlify deploy --prod`)
78-
3. Run `git stash --include-unstaged` to easily ignore plugin-generated files
76+
```sh
77+
netlify serve --dir dist/<your-project-name>/browser
78+
```
7979

80-
It's important to note that the CLI may mix your project's source code and
81-
plugin-generated files; this is why we recommend committing all project source
82-
files before running CLI builds.
80+
## CLI Usage
8381

84-
## Caveats
82+
### Requirements
8583

86-
This plugin is currently in beta.
84+
To use the Angular Universal plugin while building and deploying with the CLI, you need to have `netlify-cli v17.0.0` installed (or a later version).
8785

88-
Right now:
89-
- it does not include out of the box monorepo support
90-
- it does not support Angular Universal prerendering
86+
Please also make sure to use `ntl deploy --build` (rather than `ntl build && ntl deploy`).
9187

9288
## Getting Help
9389

@@ -100,7 +96,7 @@ project, let us know! You can either:
10096

10197
## Contributing
10298

103-
We welcome contributions ❤️ - see the [CONTRIBUTING.md](docs/CONTRIBUTING.md) file
99+
We welcome contributions ❤️ - see the [CONTRIBUTING.md](CONTRIBUTING.md) file
104100
for details.
105101

106102
## License

demo/.browserslistrc

-17
This file was deleted.

demo/.editorconfig

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Editor configuration, see https://editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
indent_style = space
7+
indent_size = 2
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.ts]
12+
quote_type = single
13+
14+
[*.md]
15+
max_line_length = off
16+
trim_trailing_whitespace = false

demo/.gitignore

+44-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,45 @@
1-
/netlify
2-
/serverless.ts
3-
/tsconfig.serverless.json
4-
/_redirects
1+
# See http://help.github.com/ignore-files/ for more about ignoring files.
2+
3+
# Compiled output
4+
/dist
5+
/tmp
6+
/out-tsc
7+
/bazel-out
8+
9+
# Node
510
/node_modules
11+
npm-debug.log
12+
yarn-error.log
13+
14+
# IDEs and editors
15+
.idea/
16+
.project
17+
.classpath
18+
.c9/
19+
*.launch
20+
.settings/
21+
*.sublime-workspace
22+
23+
# Visual Studio Code
24+
.vscode/*
25+
!.vscode/settings.json
26+
!.vscode/tasks.json
27+
!.vscode/launch.json
28+
!.vscode/extensions.json
29+
.history/*
30+
31+
# Miscellaneous
32+
/.angular/cache
33+
.sass-cache/
34+
/connect.lock
35+
/coverage
36+
/libpeerconnection.log
37+
testem.log
38+
/typings
39+
40+
# System files
41+
.DS_Store
42+
Thumbs.db
43+
44+
.netlify
45+
!.netlify/state.json

demo/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Demo
2+
3+
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.0.0-rc.3.
4+
5+
## Development server
6+
7+
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
8+
9+
## Code scaffolding
10+
11+
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12+
13+
## Build
14+
15+
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
16+
17+
## Running unit tests
18+
19+
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20+
21+
## Running end-to-end tests
22+
23+
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
24+
25+
## Further help
26+
27+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

demo/angular.json

+103-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,103 @@
1-
{"$schema":"./node_modules/@angular/cli/lib/config/schema.json","cli":{"analytics":false},"version":1,"newProjectRoot":"projects","projects":{"angular-bfdx":{"projectType":"application","schematics":{},"root":"","sourceRoot":"src","prefix":"app","architect":{"build":{"builder":"@angular-devkit/build-angular:browser","options":{"outputPath":"dist/angular-bfdx/browser","index":"src/index.html","main":"src/main.ts","polyfills":"src/polyfills.ts","tsConfig":"tsconfig.app.json","aot":true,"assets":["src/favicon.ico","src/assets"],"styles":["src/site.css","src/mobile.css"],"scripts":[]},"configurations":{"production":{"fileReplacements":[{"replace":"src/environments/environment.ts","with":"src/environments/environment.prod.ts"}],"optimization":true,"outputHashing":"none","sourceMap":false,"namedChunks":false,"extractLicenses":true,"vendorChunk":false,"buildOptimizer":true,"budgets":[{"type":"initial","maximumWarning":"2mb","maximumError":"5mb"},{"type":"anyComponentStyle","maximumWarning":"6kb","maximumError":"10kb"}]}}},"serve":{"builder":"@angular-devkit/build-angular:dev-server","options":{"browserTarget":"angular-bfdx:build"},"configurations":{"production":{"browserTarget":"angular-bfdx:build:production"}}},"extract-i18n":{"builder":"@angular-devkit/build-angular:extract-i18n","options":{"browserTarget":"angular-bfdx:build"}},"test":{"builder":"@angular-devkit/build-angular:karma","options":{"main":"src/test.ts","polyfills":"src/polyfills.ts","tsConfig":"tsconfig.spec.json","karmaConfig":"karma.conf.js","assets":["src/favicon.ico","src/assets"],"styles":["src/styles.css"],"scripts":[]}},"lint":{"builder":"@angular-devkit/build-angular:tslint","options":{"tsConfig":["tsconfig.app.json","tsconfig.spec.json","e2e/tsconfig.json","tsconfig.server.json"],"exclude":["**/node_modules/**"]}},"e2e":{"builder":"@angular-devkit/build-angular:protractor","options":{"protractorConfig":"e2e/protractor.conf.js","devServerTarget":"angular-bfdx:serve"},"configurations":{"production":{"devServerTarget":"angular-bfdx:serve:production"}}},"server":{"builder":"@angular-devkit/build-angular:server","options":{"outputPath":"dist/angular-bfdx/server","main":"server.ts","tsConfig":"tsconfig.server.json"},"configurations":{"production":{"outputHashing":"media","fileReplacements":[{"replace":"src/environments/environment.ts","with":"src/environments/environment.prod.ts"}],"sourceMap":false,"optimization":true}}},"serve-ssr":{"builder":"@nguniversal/builders:ssr-dev-server","options":{"browserTarget":"angular-bfdx:build","serverTarget":"angular-bfdx:server"},"configurations":{"production":{"browserTarget":"angular-bfdx:build:production","serverTarget":"angular-bfdx:server:production"}}},"prerender":{"builder":"@nguniversal/builders:prerender","options":{"browserTarget":"angular-bfdx:build:production","serverTarget":"angular-bfdx:server:production","routes":["/"]},"configurations":{"production":{}}},"serverless":{"builder":"@angular-devkit/build-angular:server","options":{"outputPath":"dist/angular-bfdx/serverless","main":"serverless.ts","tsConfig":"tsconfig.serverless.json"},"configurations":{"production":{"outputHashing":"media","fileReplacements":[{"replace":"src/environments/environment.ts","with":"src/environments/environment.prod.ts"}],"sourceMap":false,"optimization":true}}}}}},"defaultProject":"angular-bfdx"}
1+
{
2+
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3+
"version": 1,
4+
"newProjectRoot": "projects",
5+
"projects": {
6+
"demo": {
7+
"projectType": "application",
8+
"schematics": {},
9+
"root": "",
10+
"sourceRoot": "src",
11+
"prefix": "app",
12+
"architect": {
13+
"build": {
14+
"builder": "@angular-devkit/build-angular:application",
15+
"options": {
16+
"outputPath": "dist/demo",
17+
"index": "src/index.html",
18+
"browser": "src/main.ts",
19+
"polyfills": [
20+
"zone.js"
21+
],
22+
"tsConfig": "tsconfig.app.json",
23+
"assets": [
24+
"src/favicon.ico",
25+
"src/assets"
26+
],
27+
"styles": [
28+
"src/styles.css"
29+
],
30+
"scripts": [],
31+
"server": "src/main.server.ts",
32+
"prerender": true,
33+
"ssr": {
34+
"entry": "server.ts"
35+
}
36+
},
37+
"configurations": {
38+
"production": {
39+
"budgets": [
40+
{
41+
"type": "initial",
42+
"maximumWarning": "500kb",
43+
"maximumError": "1mb"
44+
},
45+
{
46+
"type": "anyComponentStyle",
47+
"maximumWarning": "2kb",
48+
"maximumError": "4kb"
49+
}
50+
],
51+
"outputHashing": "all"
52+
},
53+
"development": {
54+
"optimization": false,
55+
"extractLicenses": false,
56+
"sourceMap": true
57+
}
58+
},
59+
"defaultConfiguration": "production"
60+
},
61+
"serve": {
62+
"builder": "@angular-devkit/build-angular:dev-server",
63+
"configurations": {
64+
"production": {
65+
"buildTarget": "demo:build:production"
66+
},
67+
"development": {
68+
"buildTarget": "demo:build:development"
69+
}
70+
},
71+
"defaultConfiguration": "development"
72+
},
73+
"extract-i18n": {
74+
"builder": "@angular-devkit/build-angular:extract-i18n",
75+
"options": {
76+
"buildTarget": "demo:build"
77+
}
78+
},
79+
"test": {
80+
"builder": "@angular-devkit/build-angular:karma",
81+
"options": {
82+
"polyfills": [
83+
"zone.js",
84+
"zone.js/testing"
85+
],
86+
"tsConfig": "tsconfig.spec.json",
87+
"assets": [
88+
"src/favicon.ico",
89+
"src/assets"
90+
],
91+
"styles": [
92+
"src/styles.css"
93+
],
94+
"scripts": []
95+
}
96+
}
97+
}
98+
}
99+
},
100+
"cli": {
101+
"analytics": false
102+
}
103+
}

0 commit comments

Comments
 (0)