瀏覽代碼

feat(docs): Add docs on plugin lifecycle

Michael Bromley 5 年之前
父節點
當前提交
b600b8dc66

+ 2 - 2
docs/content/docs/_index.md

@@ -5,9 +5,9 @@ weight: 0
 
 # Vendure Documentation
 
-{{% alert "warning" %}}
+{{< alert "warning" >}}
 **Note**: Vendure is currently in beta and as such, the information and APIs documented here are subject to change.
-{{% /alert %}}
+{{< /alert >}}
 
 ## What is Vendure?
 

+ 2 - 2
docs/content/docs/developer-guide/importing-product-data.md

@@ -54,9 +54,9 @@ If you have [CustomFields]({{< relref "customizing-models" >}}) defined on your
 * `product:<customFieldName>`: The value of this column will populate `Product.customFields[customFieldName]`. 
 * `variant:<customFieldName>`: The value of this column will populate `ProductVariant.customFields[customFieldName]`. 
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
   For a real example, see the [products.csv file used to populate the Vendure demo data](https://github.com/vendure-ecommerce/vendure/blob/master/packages/core/mock-data/data-sources/products.csv)
-{{% /alert %}}
+{{< /alert >}}
 
 ## Initial Data
 

+ 2 - 2
docs/content/docs/developer-guide/job-queue/index.md

@@ -38,8 +38,8 @@ It is also possible to implement your own JobQueueStrategy to enable other persi
 
 If you create a [Vendure plugin]({{< relref "/docs/plugins" >}}) which involves some long-running tasks, you can also make use of the job queue. See the [JobQueue plugin example]({{< relref "plugin-examples" >}}#using-the-jobqueueservice) for a detailed annotated example.
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
 Note: The [JobQueueService]({{< relref "job-queue-service" >}}) combines well with the [WorkerService]({{< relref "worker-service" >}}).
 
 A real example of this can be seen in the [EmailPlugin source](https://github.com/vendure-ecommerce/vendure/blob/07e1958f1ad1766e6fd3dae80f526bb688c0288e/packages/email-plugin/src/plugin.ts#L201-L210)
-{{% /alert %}}
+{{< /alert >}}

+ 2 - 2
docs/content/docs/developer-guide/payment-integrations.md

@@ -7,9 +7,9 @@ showtoc: true
 
 Vendure can support many kinds of payment workflows, such as authorizing and capturing payment in a single step upon checkout or authorizing on checkout and then capturing on fulfillment. 
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
   For a complete working example of a real payment integration, see the [real-world-vendure Braintree plugin](https://github.com/vendure-ecommerce/real-world-vendure/tree/master/src/plugins/braintree)
-{{% /alert %}}
+{{< /alert >}}
 
 ## Creating an integration
 

+ 6 - 6
docs/content/docs/developer-guide/testing.md

@@ -9,9 +9,9 @@ Vendure plugins allow you to extend all aspects of the standard Vendure server.
 
 The `@vendure/testing` package gives you some simple but powerful tooling for creating end-to-end tests for your custom Vendure code.
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
   For a working example of a Vendure plugin with e2e testing, see the [real-world-vendure Reviews plugin](https://github.com/vendure-ecommerce/real-world-vendure/tree/master/src/plugins/reviews)
-{{% /alert %}}
+{{< /alert >}}
 
 ## Usage
 
@@ -42,9 +42,9 @@ registerInitializer('postgres', new PostgresInitializer());
 registerInitializer('mysql', new MysqlInitializer());
 ```
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
 Note re. the `sqliteDataDir`: The first time this test suite is run with the `SqljsInitializer`, the populated data will be saved into an SQLite file, stored in the directory specified by this constructor arg. On subsequent runs of the test suite, the data-population step will be skipped and the initial data directly loaded from the SQLite file. This method of caching significantly speeds up the e2e test runs. All the .sqlite files created in the `sqliteDataDir` can safely be deleted at any time.
-{{% /alert %}}
+{{< /alert >}}
 
 ### Create a test environment
 
@@ -66,9 +66,9 @@ describe('my plugin', () => {
 
 Notice that we pass a [`VendureConfig`]({{< relref "vendure-config" >}}) object into the `createTestEnvironment` function. The testing package provides a special [`testConfig`]({{< relref "test-config" >}}) which is pre-configured for e2e tests, but any aspect can be overridden for your tests. Here we are configuring the server to load the plugin under test, `MyPlugin`. 
 
-{{% alert "warning" %}}
+{{< alert "warning" >}}
 **Note**: If you need to deeply merge in some custom configuration, use the [`mergeConfig` function]({{< relref "merge-config" >}}) which is provided by `@vendure/core`.
-{{% /alert %}}
+{{< /alert >}}
 
 ### Initialize the server
 

+ 2 - 2
docs/content/docs/developer-guide/vendure-worker.md

@@ -41,8 +41,8 @@ There is an option `runInMainProcess` which, if set to `true` will cause the Wor
 
 If you are authoring a [Vendure plugin]({{< relref "/docs/plugins" >}}) to implement custom functionality, you can also make use of the worker process in order to handle long-running or computationally-demanding tasks. See the [Plugin Examples]({{< relref "plugin-examples" >}}#running-processes-on-the-worker) page for an example of this.
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
 Note: The [WorkerService]({{< relref "worker-service" >}}) combines well with the [JobQueueService]({{< relref "job-queue-service" >}}).
 
 A real example of this can be seen in the [EmailPlugin source](https://github.com/vendure-ecommerce/vendure/blob/07e1958f1ad1766e6fd3dae80f526bb688c0288e/packages/email-plugin/src/plugin.ts#L201-L210)
-{{% /alert %}}
+{{< /alert >}}

+ 8 - 8
docs/content/docs/getting-started.md

@@ -22,25 +22,25 @@ The recommended way to get started with Vendure is by using the [@vendure/create
 npx @vendure/create my-app
 ```
 
-{{% alert primary %}}
+{{< alert primary >}}
 [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) comes with npm 5.2+ and higher.
-{{% /alert %}}
+{{< /alert >}}
 {{% /tab %}}
 {{% tab "npm init" %}}
 ```sh
 npm init @vendure my-app
 ```
-{{% alert primary %}}
+{{< alert primary >}}
 `npm init <initializer>` is available in npm 6+
-{{% /alert %}}
+{{< /alert >}}
 {{% /tab %}}
 {{% tab "yarn create" %}}
 ```sh
 yarn create @vendure my-app
 ```
-{{% alert primary %}}
+{{< alert primary >}}
 `yarn create` is available in Yarn 0.25+
-{{% /alert %}}
+{{< /alert >}}
 {{% /tab %}}
 
 *For other installation options see the [@vendure/create documentation](https://github.com/vendure-ecommerce/vendure/blob/master/packages/create/README.md).*
@@ -63,12 +63,12 @@ Assuming the default config settings, you can now access:
 * The Vendure Shop GraphQL API: [http://localhost:3000/shop-api](http://localhost:3000/shop-api)
 * The Vendure Admin UI: [http://localhost:3000/admin](http://localhost:3000/admin)
 
-{{% alert primary %}}
+{{< alert primary >}}
 Log in with the superadmin credentials:
 
 * **username**: superadmin
 * **password**: superadmin
-{{% /alert %}}
+{{< /alert >}}
 
 ## Next Steps
 

+ 1 - 1
docs/content/docs/graphql-api/_index.md

@@ -12,5 +12,5 @@ The API is split into two distinct endpoints: *Shop* and *Admin*. The Shop API i
 
 {{% alert %}}
 All documentation in this section is auto-generated from the Vendure GraphQL schema.
-{{% /alert %}}
+{{< /alert >}}
 

+ 1 - 1
docs/content/docs/graphql-api/admin/_index.md

@@ -10,4 +10,4 @@ The Admin API is primarily used by the included Admin UI web app to perform admi
 
 {{% alert %}}
 Explore the interactive GraphQL Admin API at [demo.vendure.io/admin-api](https://demo.vendure.io/admin-api)
-{{% /alert %}}
+{{< /alert >}}

+ 1 - 1
docs/content/docs/graphql-api/shop/_index.md

@@ -10,4 +10,4 @@ The Shop API is used by storefront applications. It provides all the necessary q
 
 {{% alert %}}
 Explore the interactive GraphQL Shop API at [demo.vendure.io/shop-api](https://demo.vendure.io/shop-api)
-{{% /alert %}}
+{{< /alert >}}

+ 2 - 2
docs/content/docs/plugins/extending-the-admin-ui/_index.md

@@ -9,9 +9,9 @@ When creating a plugin, you may wish to extend the Admin UI in order to expose a
 
 This is possible by defining [AdminUiExtensions]({{< ref "admin-ui-extension" >}}). 
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
 For a complete working example of a Vendure plugin which extends the Admin UI, see the [real-world-vendure Reviews plugin](https://github.com/vendure-ecommerce/real-world-vendure/tree/master/src/plugins/reviews)
-{{% /alert %}}
+{{< /alert >}}
 
 ## How It Works
 

+ 6 - 6
docs/content/docs/plugins/extending-the-admin-ui/using-angular/_index.md

@@ -7,9 +7,9 @@ weight: 0
 
 Writing your UI extensions with Angular results in the best-optimized and most seamless UI extensions, since you can re-use shared components exported by the `@vendure/admin-ui/core` library, and the Angular framework itself is already present in the app.
 
-{{% alert warning %}}
+{{< alert warning >}}
 **Note:** an understanding of [Angular](https://angular.io/) is necessary for successfully working with Angular-based UI extensions. Try [Angular's "Getting Started" guide](https://angular.io/start) to learn more.
-{{% /alert %}}
+{{< /alert >}}
 
 ## 1. Install `@vendure/ui-devkit`
 
@@ -66,10 +66,10 @@ import { GreeterComponent } from './greeter.component';
 export class GreeterModule {}
 ```
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
 **Note:** The `SharedModule` should, in general, always be imported by your extension modules. It provides the basic Angular
 directives and other common functionality that any extension would require.
-{{% /alert %}}
+{{< /alert >}}
 
 ## 4. Pass the extension to the `compileUiExtensions` function
 
@@ -110,9 +110,9 @@ The `compileUiExtensions()` function returns a `compile()` function which will b
 
 Next, these source files will be run through the Angular compiler, the output of which will be visible in the console.
 
-{{% alert "warning" %}}
+{{< alert "warning" >}}
 **Note:** The first time the compiler is run, an additional step ([compatibility compiler](https://angular.io/guide/ivy#ivy-and-libraries)) is run to make sure all dependencies work with the latest version of Angular. This step can take up to a few minutes.
-{{% /alert %}}
+{{< /alert >}}
 
 Now go to the Admin UI app in your browser and log in. You should now be able to manually enter the URL `http://localhost:3000/admin/extensions/greet` and you should see the component with the "Hello!" header:
 

+ 4 - 4
docs/content/docs/plugins/extending-the-admin-ui/using-other-frameworks/_index.md

@@ -7,9 +7,9 @@ weight: 1
 
 Although the Admin UI is an Angular app, it is possible to create UI extensions using any web technology - React, Vue, plain JavaScript, etc.
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
 For working examples of a UI extensions built with **Vue** and **React**, see the [real-world-vendure ui extensions](https://github.com/vendure-ecommerce/real-world-vendure/tree/master/src/ui-extensions)
-{{% /alert %}}
+{{< /alert >}}
 
 There is still a small amount of Angular "glue code" needed to let the compiler know how to integrate your extension, so let's take a look at how this is done.
 
@@ -128,9 +128,9 @@ The `compileUiExtensions()` function returns a `compile()` function which will b
 
 Next, these source files will be run through the Angular compiler, the output of which will be visible in the console.
 
-{{% alert "warning" %}}
+{{< alert "warning" >}}
 **Note:** The first time the compiler is run, an additional step ([compatibility compiler](https://angular.io/guide/ivy#ivy-and-libraries)) is run to make sure all dependencies work with the latest version of Angular. This step can take up to a few minutes.
-{{% /alert %}}
+{{< /alert >}}
 
 Now go to the Admin UI app in your browser and log in. You should now be able to manually enter the URL `http://localhost:3000/admin/extensions/react-ui` and you should see the default Create React App demo page:
 

+ 7 - 7
docs/content/docs/plugins/plugin-examples.md

@@ -1,6 +1,6 @@
 ---
 title: "Plugin Examples"
-weight: 3
+weight: 4
 showtoc: true
 ---
  
@@ -8,9 +8,9 @@ showtoc: true
 
 Here are some simplified examples of plugins which serve to illustrate what can be done with Vendure plugins. *Note: implementation details are skipped in these examples for the sake of brevity. A complete example with explanation can be found in [Writing A Vendure Plugin]({{< relref "writing-a-vendure-plugin" >}}).*
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
   For a complete working example of a Vendure plugin, see the [real-world-vendure Reviews plugin](https://github.com/vendure-ecommerce/real-world-vendure/tree/master/src/plugins/reviews)
-{{% /alert %}}
+{{< /alert >}}
 
 ## Modifying the VendureConfig
 
@@ -88,9 +88,9 @@ class TopSellersResolver {
 
 }
 ```
-{{% alert "primary" %}}
+{{< alert "primary" >}}
   **Note:** The `@Ctx` decorator gives you access to [the `RequestContext`]({{< relref "request-context" >}}), which is an object containing useful information about the current request - active user, current channel etc.
-{{% /alert %}}
+{{< /alert >}}
 ```TypeScript
 // top-sellers.service.ts
 import { Injectable } from '@nestjs/common';
@@ -159,9 +159,9 @@ import { ProductsController } from './products.controller';
 export class RestPlugin {}
 ```
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
   **Note:** [The `PluginCommonModule`]({{< relref "plugin-common-module" >}}) should be imported to gain access to Vendure core providers - in this case it is required in order to be able to inject `ProductService` into our controller.
-{{% /alert %}}
+{{< /alert >}}
 
 Side note: since this uses no Vendure-specific metadata, it could also be written using the Nestjs `@Module()` decorator rather than the `@VendurePlugin()` decorator.
 

+ 64 - 0
docs/content/docs/plugins/plugin-lifecycle/index.md

@@ -0,0 +1,64 @@
+---
+title: "Plugin Lifecycle"
+weight: 3
+---
+
+# Plugin Lifecycle
+
+A VendurePlugin can make use of a number pre-defined "hooks", which allow the plugin to execute code at specific points during the lifecycle of the application. 
+
+## Nestjs Lifecycle Hooks
+
+Since a VendurePlugin is built on top of the Nestjs module system, any plugin can make use of any of the [Nestjs lifecycle hooks](https://docs.nestjs.com/fundamentals/lifecycle-events).
+
+{{< alert "warning" >}}
+Note that since a Plugin will typically be instantiated in _both_ the main process _and_ the worker, any logic defined in a Nestjs lifecycle hook will be executed **twice**. 
+
+To run logic _only_ in the main process or worker process, use the Vendure-specific hooks below, or inject the [`ProcessContext`]({{< relref "process-context" >}}) provider.
+{{< /alert >}}
+
+## Vendure-specific hooks
+
+Vendure defines some additional hooks which allow you to target logic depending on the context (main process or worker), as well as letting you run code _prior_ to the bootstrap process.
+
+The available Vendure-specific lifecycle hooks are:
+
+* [`beforeVendureBootstrap`]({{< relref "plugin-lifecycle-methods" >}}#beforevendurebootstrap) (static method)
+* [`beforeVendureWorkerBootstrap`]({{< relref "plugin-lifecycle-methods" >}}#beforevendureworkerbootstrap) (static method)
+* [`onVendureBootstrap`]({{< relref "plugin-lifecycle-methods" >}}#onvendurebootstrap)
+* [`onVendureWorkerBootstrap`]({{< relref "plugin-lifecycle-methods" >}}#onvendureworkerbootstrap)
+* [`onVendureClose`]({{< relref "plugin-lifecycle-methods" >}}#onvendureclose)
+* [`onVendureWorkerClose`]({{< relref "plugin-lifecycle-methods" >}}#onvendureworkerclose)
+
+### Example 
+
+```TypeScript
+import { OnVendureBootstrap, VendurePlugin } from '@vendure/core';
+
+@VendurePlugin({
+  // ...
+})
+export class MyPlugin implements OnVendureBootstrap {
+
+  static beforeVendureBootstrap(app) {
+    // An example use-case for this hook is to add 
+    // global middleware as described in 
+    // https://docs.nestjs.com/middleware#global-middleware
+    app.use(/* ... */);
+  }
+  
+  async onVendureBootstrap() {
+    // setup logic here. If retuning a Promise, 
+    // app initialization will wait until the Promise resolves.
+    await myAsyncInitFunction();
+  }
+
+}
+```
+
+## Full Lifecycle Diagram
+
+This diagram illustrates how the Nestjs & Vendure lifecycle hooks relate to one another:
+
+{{< figure src="./plugin_lifecycle.png" >}}
+

二進制
docs/content/docs/plugins/plugin-lifecycle/plugin_lifecycle.png


+ 5 - 5
docs/content/docs/plugins/writing-a-vendure-plugin.md

@@ -7,9 +7,9 @@ weight: 2
 
 This is a complete example of how to implement a simple plugin step-by-step.
 
-{{% alert "primary" %}}
+{{< alert "primary" >}}
   For a complete working example of a Vendure plugin, see the [real-world-vendure Reviews plugin](https://github.com/vendure-ecommerce/real-world-vendure/tree/master/src/plugins/reviews)
-{{% /alert %}}
+{{< /alert >}}
 
 ## Example: RandomCatPlugin
 
@@ -61,12 +61,12 @@ export class CatFetcher {
 
 {{% alert %}}
 The `@Injectable()` decorator is part of the underlying [Nest framework](https://nestjs.com/), and allows us to make use of Nest's powerful dependency injection features. In this case, we'll be able to inject the `CatFetcher` service into the resolver which we will soon create.
-{{% /alert %}}
+{{< /alert >}}
 
 
-{{% alert "warning" %}}
+{{< alert "warning" >}}
 To use decorators with TypeScript, you must set the "emitDecoratorMetadata" and "experimentalDecorators" compiler options to `true` in your tsconfig.json file.
-{{% /alert %}}
+{{< /alert >}}
 
 ### Step 3: Define the new mutation
 

+ 2 - 2
docs/content/docs/storefront/shop-api-guide.md

@@ -8,9 +8,9 @@ showtoc: true
 
 This is an overview of the GraphQL Shop API, which is used when implementing a storefront application with Vendure. 
 
-{{% alert "warning" %}}
+{{< alert "warning" >}}
 This guide only lists some of the more common operations you'll need for your storefront. Please consult [the Shop API reference]({{< relref "/docs/graphql-api/shop" >}}) for a complete guide.
-{{% /alert %}}
+{{< /alert >}}
 
 ## Universal Parameters
 

+ 1 - 1
docs/content/docs/typescript-api/_index.md

@@ -10,4 +10,4 @@ The Vendure TypeScript API is used when configuring the server (via the [`Vendur
 
 {{% alert %}}
 All documentation in this section is auto-generated from the TypeScript source of the Vendure server.
-{{% /alert %}}
+{{< /alert >}}

+ 31 - 0
docs/diagrams/plugin-lifecycle.puml

@@ -0,0 +1,31 @@
+@startuml
+!include theme.puml
+title Vendure Plugin Lifecycle
+hide footbox
+skinparam SequenceBoxBorderColor #efefef
+skinparam SequenceDividerBorderThickness 1
+skinparam BoxPadding 100
+participant VendurePlugin #13b7f3
+box "Vendure Server" #efefef
+participant "Server (NestApplication)" as NestApplication
+participant "Worker (NestMicroservice)" as NestMicroservice
+end box
+
+VendurePlugin -> NestApplication: static beforeVendureBootstrap
+VendurePlugin -> NestMicroservice: static beforeVendureWorkerBootstrap
+||50||
+== Nestjs onModuleInit ==
+VendurePlugin -> NestApplication: onVendureBootstrap
+VendurePlugin -> NestMicroservice: onVendureWorkerBootstrap
+== Nestjs onApplicationBootstrap ==
+||50||
+note over NestApplication, NestMicroservice #ccffcc: Vendure server running...
+||50||
+note over NestApplication, NestMicroservice #ffcccc: Termination signal received
+== Nestjs onModuleDestroy ==
+VendurePlugin -> NestApplication: onVendureClose
+VendurePlugin -> NestMicroservice: onVendureWorkerClose
+== Nestjs beforeApplicationShutdown ==
+== Nestjs onApplicationShutdown ==
+
+@enduml

+ 1 - 1
docs/layouts/shortcodes/alert.html

@@ -1,3 +1,3 @@
 <div class='alert {{ index .Params 0 | default "primary" }}'>
-    {{ .Inner }}
+    <p>{{ .Inner | markdownify }}</p>
 </div>