From 9f4625986665f15020f0df32d7de2cfdee2d3e80 Mon Sep 17 00:00:00 2001 From: sanderelias Date: Tue, 23 Nov 2021 10:52:02 +0100 Subject: [PATCH 1/3] docs(platform-server): update docs, and add getting started for SPS --- docs/Reference/legacy-support/overview.md | 1 + docs/Reference/legacy-support/polyfills.md | 2 +- docs/Reference/plugins/types/beforeAll.md | 2 +- docs/Reference/plugins/types/overview.md | 24 ++--- .../{rendererDom.md => postProcessByDom.md} | 8 +- ...ndererDom_es.md => postProcessByDom_es.md} | 0 .../types/{render.md => postProcessByHtml.md} | 8 +- docs/Reference/plugins/types/render_es.md | 76 --------------- docs/Reference/plugins/types/routeRenderer.md | 19 ++++ docs/Reference/plugins/types/system.md | 3 +- docs/Reference/routRenders/overview.md | 19 ++++ docs/Reference/routRenders/sps.md | 93 +++++++++++++++++++ .../create-a-blog/generate-new-blog-posts.md | 2 + docs/roadmap.md | 4 +- 14 files changed, 160 insertions(+), 101 deletions(-) rename docs/Reference/plugins/types/{rendererDom.md => postProcessByDom.md} (63%) rename docs/Reference/plugins/types/{rendererDom_es.md => postProcessByDom_es.md} (100%) rename docs/Reference/plugins/types/{render.md => postProcessByHtml.md} (82%) delete mode 100644 docs/Reference/plugins/types/render_es.md create mode 100644 docs/Reference/plugins/types/routeRenderer.md create mode 100644 docs/Reference/routRenders/overview.md create mode 100644 docs/Reference/routRenders/sps.md diff --git a/docs/Reference/legacy-support/overview.md b/docs/Reference/legacy-support/overview.md index 5cdeba16b..cfbe388d7 100644 --- a/docs/Reference/legacy-support/overview.md +++ b/docs/Reference/legacy-support/overview.md @@ -8,3 +8,4 @@ position: 900 - [Angular v8](/docs/Reference/legacy-support/angular-v8) - [IE polyfills](/docs/Reference/legacy-support/polyfills) +- Angular <12. Use Scully version 1 (`ng add scullyio/init@1`) diff --git a/docs/Reference/legacy-support/polyfills.md b/docs/Reference/legacy-support/polyfills.md index bc2c30160..d7201f6ed 100644 --- a/docs/Reference/legacy-support/polyfills.md +++ b/docs/Reference/legacy-support/polyfills.md @@ -15,7 +15,7 @@ This page lists the recommended polyfills. Scully uses [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event) to be aware of different points in the application's lifecycle. -### Internet Explorer 10+ +### Internet Explorer 10+ (Deprecated, V1 only) To make **Internet Explorer 10+** work, install and import the following polyfill: diff --git a/docs/Reference/plugins/types/beforeAll.md b/docs/Reference/plugins/types/beforeAll.md index 8ff8bc4ca..f30159508 100644 --- a/docs/Reference/plugins/types/beforeAll.md +++ b/docs/Reference/plugins/types/beforeAll.md @@ -2,7 +2,7 @@ title: beforeAll Plugin Type published: true lang: en -position: 104 +position: 100 --- # `beforeAll` Plugin Type diff --git a/docs/Reference/plugins/types/overview.md b/docs/Reference/plugins/types/overview.md index f1d8f4ecf..4067c5e7f 100644 --- a/docs/Reference/plugins/types/overview.md +++ b/docs/Reference/plugins/types/overview.md @@ -12,24 +12,24 @@ position: 10 Scully uses a plugin system which allows users to define new ways for Scully to pre-render an application. There are five main types of plugins which allow code to be injected into various stages of the Scully process lifecycle: -
- -- [Plugin types](#plugin-types) - - [Overview](#overview) - - [`router`](#router) - - [`render`](#render) - - [`fileHandler`](#filehandler) - - [`routeDiscoveryDone`](#routediscoverydone) - - [`allDone`](#alldone) #### [`router`](/docs/Reference/plugins/types/router) `router` plugins teach Scully how to get the required data to be pre-render pages from the route-params. -#### [`render`](/docs/Reference/plugins/types/render) +#### [`postProcessByDom`](/docs/Reference/plugins/types/postProcessByDom.md) + +`postProcessByDom` plugins are used to transform the rendered HTML. +After the Angular application renders, the HTML content is passed to a `postProcessByDom` plugin where it can be further modified. + +### [`routeRenderer`](/docs/Reference/plugins/types/routeRenderer.md) + +The `routeRenderer` is a scullySystem plugin that can be swapped out to use a different way to render the pages + +#### [`postProcessByHtml`](/docs/Reference/plugins/types/postProcessByHtml.md) -`render` plugins are used to transform the rendered HTML. -After the Angular application renders, the HTML content is passed to a `render` plugin where it can be further modified. +`postProcessByHtml` plugins are used to transform the rendered HTML. +After the Angular application renders, the HTML content is passed to a `postProcessByHtml` plugin where it can be further modified. #### [`fileHandler`](/docs/Reference/plugins/types/fileHandler) diff --git a/docs/Reference/plugins/types/rendererDom.md b/docs/Reference/plugins/types/postProcessByDom.md similarity index 63% rename from docs/Reference/plugins/types/rendererDom.md rename to docs/Reference/plugins/types/postProcessByDom.md index 56aa98e10..2996eae47 100644 --- a/docs/Reference/plugins/types/rendererDom.md +++ b/docs/Reference/plugins/types/postProcessByDom.md @@ -9,14 +9,14 @@ position: 100 ## Overview -A **render plugin** is used to transform the rendered HTML. -After the Angular application renders, the HTML content is passed to a **render plugin** where it can be further modified. +A **postProcessByDom plugin** is used to transform the rendered HTML. +After the Angular application renders, the HTML content is passed to a **postProcessByDom plugin** where it can be further modified. -A **render plugin** could be used to transform a page containing markdown into a page that renders it. +A **postProcessByDom plugin** could be used to transform a page containing markdown into a page that renders it. ## Interface -A **`postProcessByDom` plugin** is a function that returns a `Promise`. The string in the promise must be the transformed +A **postProcessByDom plugin** is a function that returns a `Promise`. The string in the promise must be the transformed HTML. The interface looks like this: ```typescript diff --git a/docs/Reference/plugins/types/rendererDom_es.md b/docs/Reference/plugins/types/postProcessByDom_es.md similarity index 100% rename from docs/Reference/plugins/types/rendererDom_es.md rename to docs/Reference/plugins/types/postProcessByDom_es.md diff --git a/docs/Reference/plugins/types/render.md b/docs/Reference/plugins/types/postProcessByHtml.md similarity index 82% rename from docs/Reference/plugins/types/render.md rename to docs/Reference/plugins/types/postProcessByHtml.md index 242f0a813..7f0225100 100644 --- a/docs/Reference/plugins/types/render.md +++ b/docs/Reference/plugins/types/postProcessByHtml.md @@ -9,14 +9,14 @@ position: 100 ## Overview -A **render plugin** is used to transform the rendered HTML. -After the Angular application renders, the HTML content is passed to a **render plugin** where it can be further modified. +A **postProcessByHtml plugin** is used to transform the rendered HTML. +After the Angular application renders, the HTML content is passed to a **postProcessByHtml plugin** where it can be further modified. -A **render plugin** could be used to transform a page containing markdown into a page that renders it. +A **postProcessByHtml plugin** could be used to transform a page containing markdown into a page that renders it. ## Interface -A **`postProcessByHtml` plugin** is a function that returns a `Promise`. The string in the promise must be the transformed +A **postProcessByHtml plugin** is a function that returns a `Promise`. The string in the promise must be the transformed HTML. The interface looks like this: ```typescript diff --git a/docs/Reference/plugins/types/render_es.md b/docs/Reference/plugins/types/render_es.md deleted file mode 100644 index 7960d8fd4..000000000 --- a/docs/Reference/plugins/types/render_es.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Complementos del tipo render -published: true -lang: es -position: 100 ---- - -# Complementos del tipo `render` - -## Visión General - -Un **complemento render** es utilizado para transformar el HTML renderizado. -Una vez que la aplicación Angular haya renderizado, el contenido HTML es pasado a un **complemento render** dónde puede ser modificado aún más. - -Un **complemento render** puede ser usado para transformar el contenido markdown que tenga página y así renderizarlo. - -## Interfaz - -un **complemento `render`** es una función que devuelve un `Promise`. El string dentro de la promesa debe ser HTML transformado. -La interfaz de la función luce así: - -```typescript -function exampleContentPlugin( - HTML: string, - route: HandledRoute -): Promise { - // Must return a promise -} -``` - -## Creando un Complemento `render` - -El siguiente ejemplo de un **complemento `render`** agrega un titulo en el header de la página si es que no lo encuentra. - -```typescript -const { registerPlugin } = require('@scullyio/scully'); - -function defaultTitlePlugin(html, route) { - // If no title in the document - if (html.indexOf('The Truth Is Out There!`; - return Promise.resolve(`${begin}${defaultTitle}${splitter}${end}`); - } - return Promise.resolve(html); -} - -// DON NOT FORGET REGISTER THE PLUGIN -const validator = async (conf) => []; -registerPlugin( - 'postProcessByHtml', - 'defaultTitle', - defaultTitlePlugin, - validator -); - -module.exports.defaultTitlePlugin = defaultTitlePlugin; -``` - -En el ejemplo anterior, el contenido HTML de la aplicación Angular es transformado para incluir un título porque se encontró a alguien. - -El siguiente ejemplo reemplaza cualqueir coincidencia de `:)`por un emoji sonriente. - -```typescript -const { registerPlugin } = require('@scullyio/scully'); - -function smileEmojiPlugin(html, route) { - return Promise.resolve(html.replace(/\:\)/g, '😊')); -} -// DON NOT FORGET REGISTER THE PLUGIN -const validator = async (conf) => []; -registerPlugin('postProcessByHtml', 'smiles', smileEmojiPlugin, validator); - -module.exports.smileEmojiPlugin = smileEmojiPlugin; -``` diff --git a/docs/Reference/plugins/types/routeRenderer.md b/docs/Reference/plugins/types/routeRenderer.md new file mode 100644 index 000000000..d53bdd68a --- /dev/null +++ b/docs/Reference/plugins/types/routeRenderer.md @@ -0,0 +1,19 @@ +--- +title: the routeRenderer plugin +published: true +lang: en +position: 100 +--- + +# `routeRenderer` Plugin + +The `routeRenderer` is a scullySystem plugin that can be swapped out to use a different way to render the pages. +It receives a [handledRoute](/docs/concepts/handled-routes.md), and should return a string containing the entire contents of the page. + +Its interface is: +```ts + (route:HandledRoute) => Promise +``` + +### responisilities. +This plugin is responsible for rendering the actual content from the Angular app. When it throws, it will be retried 3 times before failure diff --git a/docs/Reference/plugins/types/system.md b/docs/Reference/plugins/types/system.md index a8ac6d01f..72a2a1181 100644 --- a/docs/Reference/plugins/types/system.md +++ b/docs/Reference/plugins/types/system.md @@ -7,4 +7,5 @@ title: System Plugins # The Scully system plugins. -Scully has a category of system plugins. Unlike the other plugin catagories those plugins don't have a set interface, and do use a symbol for their name. +Scully has a category of system plugins. Unlike the other plugin catagories those plugins don't have a set interface. Those are used by Scully internally. +It is possible to replace any of the plugins, including system plugins. This gives you an easy way to extend the functionality of Scully diff --git a/docs/Reference/routRenders/overview.md b/docs/Reference/routRenders/overview.md new file mode 100644 index 000000000..1a2d643d9 --- /dev/null +++ b/docs/Reference/routRenders/overview.md @@ -0,0 +1,19 @@ +--- +title: RouteRender plugins +published: true +lang: en +position: 120 +--- + +# routeRender plugins. + +The `routeRenderer` is responsible for creating an HTML string from a `handledRoute`. +It receives a [handledRoute](/docs/concepts/handled-routes.md), and should return a string containing the entire contents of the page. + +There are currently 3 different types. +1. Puppteer. The default. comes from the package [`@scullyio/scully-plugin-puppeteer`](https://github.com/scullyio/scully/tree/main/libs/plugins/scully-plugin-puppeteer) +Uses Puppteer to control Chrome, and retreives the pages HTML +2. Playwright. Comes from the package [`@scullyio/scully-plugin-playwright`](https://github.com/scullyio/scully/tree/main/libs/plugins/scully-plugin-playwright) +Uses MS-Playwright to render the pages to HTML +3. SPS (Scully Platform Server Renderer). Is installed by default. +Uses Angular platform server to render the pages to HTML diff --git a/docs/Reference/routRenders/sps.md b/docs/Reference/routRenders/sps.md new file mode 100644 index 000000000..8570355d6 --- /dev/null +++ b/docs/Reference/routRenders/sps.md @@ -0,0 +1,93 @@ +--- +title: SPS Scully Platform Server +published: true +lang: en +position: 10 +--- + +# SPS Scully Platform Server (Preview/Beta) + +The SPS renderer is utilizing the [Angular platform server](https://angular.io/api/platform-server) to render your pages. + +To get started you need to install a few packages into your project. + +```bash +npm i @angular/platform-server +npm i @scullyio/platform-server +``` + +Then next to your `app.module` create an new module, we recommend naming it with an `.sps.` indentifier. + +So: `app.sps.module.ts` will contain: +```ts +import { enableProdMode, NgModule } from '@angular/core'; +import { AppComponent } from './app.component'; +import { AppModule } from './app.module'; +import { ScullyPlatformServerModule } from '@scullyio/platform-server' +import { BrowserModule } from '@angular/platform-browser'; + + +/** + * the platform server should be running in production mode. + */ +enableProdMode(); + + +@NgModule({ + imports: [ + BrowserModule.withServerTransition({ appId: 'serverApp' }), + AppModule, + ScullyPlatformServerModule, + ], + providers: [], + bootstrap: [AppComponent], +}) +export default class AppSPSModule {} +``` +(PS, for most apps, a copy-paste of the above will work!) + +> Note: the Scully SPS renderer is using the default export, so make sure you don't forget to add `default` to your module. + +> Note: Make sure to add your `AppComponent` to the bootstrap, otherwise SPS will render a load of empty pages. Also, be sure to import your `AppModule` otherwise it will error out. + +What this module does, is wiring up all the needed parts that are needed to run your application in a nodeJs environment. the SPS render will simulate a browser environment, but not all 3rth party libraries are suited for a setup like this. Part of our beta program is finding out the limits. Please let us know when you run into this. +On our roadmap is an hybrid render approach that will use this first, an then fall-back to Puppeteer dynamically. + +Now in your `scully..config.ts` you should link to the above module, and enable SPS. (also, you might want to remove the import for other renderers, but this is optional) + +```ts +/** + * enables the Scully Platrom Server + * (disables puppeteer, and uses Angular Platform-server to render the pages ) + */ +enableSPS(); + +export const config: ScullyConfig = { + projectName: 'sps-sample', + outDir: './dist/static/sps-sample', + defaultPostRenderers, + /** path to the module you created above */ + spsModulePath: './apps/sps-sample/src/app/app.sps.module.ts', + /** this seems the optimal for SPS */ + maxRenderThreads: cpus().length * 3, + routes: { + /** no change **/ + } +``` +> Note: `enableSPS()` will activate the SPS renderer + +> Note: the `spsModulePath` is mandatory now, this might change in the future. + +Now you can start the render process the same way as you are used too +```bash +# first build your app, as Scully still needs the static artifacts +npx ng build +# run Scully +npx scully +``` + +Our renderer will create `./scully/tsconfig..json` if its not there, and use that to compile your application. Your compiled application will end up in the folder `./scully/runtime`. Under the hood it utilizes the ANgular compiler to do this. + +> Note: When there is an error while compiling your application please fix this before trying again. We can't render an application that doesn't compile. + +After that is done, we will start [maxRenderThreads](/docs/Reference/config.md) processes in the background. This number is by default the ammount of CPU-cores in your system. Depending on your app a higher, (or lower) number can have better perfromance. It is really depending on your application. If its CPU-bound a lower number will be better, If its IO-bound, a higher number will be better. Some of our tests show that `3*cpu-cores` is optimal for an average app. diff --git a/docs/learn/create-a-blog/generate-new-blog-posts.md b/docs/learn/create-a-blog/generate-new-blog-posts.md index 98b71405f..98f3a127c 100644 --- a/docs/learn/create-a-blog/generate-new-blog-posts.md +++ b/docs/learn/create-a-blog/generate-new-blog-posts.md @@ -66,6 +66,8 @@ Next you want to build Scully to generate the route. Type the following in the t npx scully ``` +> ### Note: When you added or removed routes to your angular app(not a blog post, a new route) you do need to run `npx scully --scanRoutes`. That will make Scully find the new route(s) you just added + The above will start a process that will generate pages. Have a look at your `angular-tutorial.md` file again, it has changed. Now the file contains the following: ```markdown diff --git a/docs/roadmap.md b/docs/roadmap.md index 095706078..2cdad81e4 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -14,7 +14,7 @@ There are an couple of new optional render plugins in the list. Those will all b - release V2 of Scully - ~~Deprecate support for Angular before version 12.~~ - ~~V2 will require Angular v12 and up~~ - - V2 will switch over to the new Ivy library structure soon + - ~~V2 will switch over to the new Ivy library structure soon~~ - V1 will remain available for Angular versions 9/10/11 - support for versions before V9 is completely dropped. - Better control over server-start-stop. @@ -44,4 +44,4 @@ There are an couple of new optional render plugins in the list. Those will all b - static pages will be prerendered, and served fully static - dynamic-session pages will be rendered on demand. -When you want us to give any of those priority, check our [consultancy page](./consutancy.md). The team at HeroDevs will gladly help you. +When you want us to give any of those priority, check our [consultancy page](/getHelp). The team at HeroDevs will gladly help you. From 8af4d74881f7c8eaf00091b63d879a46b9528f49 Mon Sep 17 00:00:00 2001 From: sanderelias Date: Tue, 23 Nov 2021 11:20:36 +0100 Subject: [PATCH 2/3] fix(docsWeb): fix false positive on headers test --- docs/Reference/routRenders/sps.md | 4 ++-- scully.scully-docs.config.ts | 4 +++- tests/jest/src/__tests__/docsThere.spec.ts | 8 +++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/Reference/routRenders/sps.md b/docs/Reference/routRenders/sps.md index 8570355d6..c6de6d539 100644 --- a/docs/Reference/routRenders/sps.md +++ b/docs/Reference/routRenders/sps.md @@ -80,9 +80,9 @@ export const config: ScullyConfig = { Now you can start the render process the same way as you are used too ```bash -# first build your app, as Scully still needs the static artifacts + # first build your app, as Scully still needs the static artifacts npx ng build -# run Scully + # run Scully npx scully ``` diff --git a/scully.scully-docs.config.ts b/scully.scully-docs.config.ts index c00c9b27c..acf0016bd 100644 --- a/scully.scully-docs.config.ts +++ b/scully.scully-docs.config.ts @@ -147,11 +147,13 @@ function getHeadings(content: string): [string, string][] { // '# angular tutorial', // 'overview', // 'my blog post', + `first build your app,`, + `run scully`, '#heading 1 ### subheading 1 ## heading 2 ### subheading 2', ].map((e) => e.trim().toLowerCase()); return content .split('\n') - .filter((line) => line.startsWith('#') && !exceptions.some((exception) => line.toLowerCase().includes(exception))) + .filter((line) => line.startsWith('#') && !exceptions.some((exception) => line.toLowerCase().includes(exception.toLowerCase().trim()))) .map((line) => { const outer = document.createElement('div'); outer.innerHTML = marked(line.trim()); diff --git a/tests/jest/src/__tests__/docsThere.spec.ts b/tests/jest/src/__tests__/docsThere.spec.ts index db32bf5ff..6e8d2ea39 100644 --- a/tests/jest/src/__tests__/docsThere.spec.ts +++ b/tests/jest/src/__tests__/docsThere.spec.ts @@ -141,7 +141,13 @@ function checkFM(prettyFile, mdContent) { * exclude ones that have exception in them */ function getHeadings(content: string) { - const exceptions = ['# angular tutorial', 'my blog post', 'heading 1 ### subheading 1 ## heading 2 ### subheading 2'].map((e) => + const exceptions = [ + '# angular tutorial', + 'my blog post', + 'heading 1 ### subheading 1 ## heading 2 ### subheading 2', + '# first build your app, as Scully still needs the static artifacts', + '# run Scully' + ].map((e) => e.trim().toLowerCase() ); return content From 0e30f55ba272f749a22808e6f394f382f9011c68 Mon Sep 17 00:00:00 2001 From: sanderelias Date: Tue, 23 Nov 2021 11:24:09 +0100 Subject: [PATCH 3/3] docs(docsWeb): fix link --- docs/roadmap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/roadmap.md b/docs/roadmap.md index 2cdad81e4..3ce157cca 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -44,4 +44,4 @@ There are an couple of new optional render plugins in the list. Those will all b - static pages will be prerendered, and served fully static - dynamic-session pages will be rendered on demand. -When you want us to give any of those priority, check our [consultancy page](/getHelp). The team at HeroDevs will gladly help you. +When you want us to give any of those priority, check our [consultancy page](./consutancy.md). The team at HeroDevs will gladly help you.