Plugins
This chapter will introduce how to use plugins and how to develop plugins.
If you want to see a list of all plugins and their documentation, please visit plugins list.
How to use§
The plugin is configured in pagic.config.ts through plugins, its type is string[].
According to the level of the plugin, plugins can be divided into built-in plugins, official plugins and third-party plugins.
Built-in plugins§
Built-in plugins (also called default plugins) are the most important plugins, they make up the entire Pagic build process, in other words, the entire Pagic build process is split into built-in plugins.
The built-in plugins include ['clean','init','md','tsx','script','layout','out'], the construction process of Pagic also follows this order:
- clean: Empty the- distdirectory
- init: Initialize intermediate variables (- pagePropsMap)
- md: Parse the- mdfile and update the intermediate variables
- tsx: Parse- tsxfiles and update intermediate variables
- script: Compile- tsxfiles to generate- pagic.config.js,- index.js,- *_props.js,- *_content.jsand other files
- layout: Parse the- _layout.tsxfile and use the- Layoutcomponent to render
- out: Generate HTML files, copy static resources
In fact, there are some steps before step 1: parsing
pagic.config.ts, scanning the project directory, finding page files and template files. However, due to some operating mechanisms, they cannot be split into plugins.
The built-in plugin is enabled by default, you don't need to add configuration to enable it.
By configuring items beginning with -, you can delete the default plugins, such as:
export default {
  plugins: ['-script'],
};
This configuration will delete the script plugin in the default plugins, so that the generated website does not have the React-related <script> tag, and it also loses the SPA ability when jumping between pages.
But for very simple websites, such as one-page-website, this configuration is very suitable.
If you delete the default plugin and then add a third-party plugin, we can even completely change Pagic's build process. For example, we can delete the md plugin, and then add a third-party plugin that parses markdown to replace the process of parsing markdown files.
Official plugins§
In addition to built-in plugins, we also provide some commonly used official plugins, including:
- sidebar: Used to parse the- sidebarconfigured in- pagic.config.ts, the theme will render sidebar after the parse is completed
- prev_next: Will get the link of previous page and the next page according to the configuration of- sidebar, the theme will render it to the bottom of the article
- ga: Google Analytics plugin, the plugin will generate a- ReactElement, the theme will inserted it into the page's- <head>
- gitalk: Add comment function to the page, the plugin will generate a- ReactElement, the theme will insert it into the bottom of the page
- blog: Parse the- md/tsxfile as a post in the specified directory
- i18n: Internationalization plugin, which make the website support multiple languages
The configuration of these plugins can be viewed in the Config chapter.
Official plugins can be added by configuring plugins.
It should be noted that the user-configured plugins will not replace the default plugins, but will be inserted into the default plugins according to a rule.
Take pagic.org config file as an example:
export default {
  plugins: ['sidebar', 'prev_next', 'ga'],
};
The inserted plugins are:
export default {
  plugins: ['clean', 'init', 'md', 'tsx', 'sidebar', 'prev_next', 'ga', 'script', 'layout', 'out'],
};
So what is the rules?§
It turns out that every non-built-in plugin will have an insert attribute, which describes the position when it is inserted, and its value is before:xxx or after:xxx, where xxx is one The name of the plugin. such as:
- The insertattribute ofsidebarisafter:tsx, so it will be inserted aftertsx
- The insertattribute ofprev_nextisafter:sidebar, so it will be inserted aftersidebar
- The insertattribute ofgaisbefore:script, so it will be inserted beforescript
Thanks to Pagic's splitting of the build process into built-in plugins, non-built-in plugins can be flexibly inserted into any position of the build. This design is more flexible and easier to understand than creating some "hook functions".
Third-party plugins§
When using third-party plugins, the items in the array should be an entry file URL:
export default {
  plugins: ['https://raw.githubusercontent.com/xcatliu/pagic_plugin_custom/master/mod.ts'],
};
How to develop a plugin§
Plugin structure§
A plugin must have a default export, the type is as follows:
interface PagicPlugin {
  name: string;
  insert?: string;
  fn: (ctx: Pagic) => Promise<void>;
}
Among them:
- nameis the name of the plugin. This name will be used when other plugins need to be inserted before or after this plugin
- insertis the position where the plugin is inserted, the value is- before:xxxor- after:xxx, where- xxxis a plugin name
- The fnfunction is the core logic of the plugin, and it accepts a parameterpagic, which is an instance ofPagic
This naming rule refers to Deno Testing's design
fn function§
The fn function is the core logic of the plugin. Since its parameter pagic is the currently running instance of Pagic, it can do almost anything, including but not limited to:
- Get configuration in pagic.config.ts
- Get the list of static resources
- Get page list
- Modify the propsof the page
- Write files to the distdirectory
- Import and run third-party modules
For example, we can create a plugin that adds a prefix to the title of all pages:
import { PagicPlugin } from 'https://deno.land/x/pagic@v1.6.3/mod.ts';
const prependTitle: PagicPlugin = {
  name: 'prepend_title',
  insert: 'after:tsx',
  fn: async (pagic) => {    for (const pagePath of pagic.pagePaths) {      const pageProps = pagic.pagePropsMap[pagePath];      pagic.pagePropsMap[pagePath] = {        ...pageProps,        title: `Prefix ${pageProps.title}`,      };    }  },};
export default prependTitle;
In the above example,
- pagic.pagePathsis the temporary[1] path of all scanned pages
- pagic.pagePropsMapis the- propsof all pages
We loop through pagic.pagePaths through for of, and re-assign the props of each page, so that we can add a prefix to all pages.
In addition to these two attributes, pagic has many other attributes. The commonly used pagic attributes are listed below:
| Properties | Type | Description | 
|---|---|---|
| config | PagicConfig | Pagic runtime[2] configuration | 
| pagePaths | string[] | Temporary[1] all scanned page paths | 
| layoutPaths | string[] | All scanned templates (including themes) | 
| staticPaths | string[] | Temporary[1] all scanned static resources (including themes) | 
| pagePropsMap | Record<string, any> | propsfor all pages | 
| writeFiles | Record<string, string> | Will be written to the distdirectory in theoutplugin | 
| rebuilding | boolean | truemeans rebuilding,falsemeans incremental building | 
Note that
Reference official plugin§
The best reference for developing a plugin is the official plugin, you can directly view the source code of the official plugin.
Annotations§
-  pagePathsandstaticPathsare both temporary, that is to say, they only contain incremental during incremental builds (--watchmode)
-  The runtime configuration of Pagic is slightly different from the configuration in pagic.config.ts