"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8847],{50431:(n,e,s)=>{s.r(e),s.d(e,{data:()=>l});const l={key:"v-642f061e",path:"/vuepress-next/advanced/plugin.html",title:"Writing a Plugin",lang:"en-US",frontmatter:{},excerpt:"",headers:[{level:2,title:"Create a Plugin",slug:"create-a-plugin",children:[]},{level:2,title:"Publish to NPM",slug:"publish-to-npm",children:[{level:3,title:"Plugin Entry",slug:"plugin-entry",children:[]},{level:3,title:"package.json",slug:"package-json",children:[]}]}],git:{updatedTime:1635758933e3,contributors:[{name:"shentuzhigang",email:"shentuzhigang@moresec.cn",commits:1}]},filePathRelative:"vuepress-next/advanced/plugin.md",content:'# Writing a Plugin\n\n::: tip\nBefore reading this guide, you\'d better learn the VuePress [architecture](./architecture.md) first.\n:::\n\n## Create a Plugin\n\nA VuePress plugin is a plain JavaScript object that satisfies the [Plugin API](../reference/plugin-api.md), which is called a *Plugin Object*.\n\nIf a plugin wants to receive user options, it could be a function that returns a *Plugin Object*, which is called a *Plugin Function*.\n\n<CodeGroup>\n  <CodeGroupItem title="Plugin Object" active>\n\n```js\nconst fooPlugin = {\n  name: \'vuepress-plugin-foo\',\n  // ...\n}\n```\n\n  </CodeGroupItem>\n\n  <CodeGroupItem title="Plugin Function">\n\n```js\nconst fooPlugin = (options, app) => {\n  return {\n    name: \'vuepress-plugin-foo\',\n    // ...\n  }\n}\n```\n\n  </CodeGroupItem>\n</CodeGroup>\n\n## Publish to NPM\n\nThe typical structure of a plugin package is as follow:\n\n```bash\nvuepress-plugin-foo\n├─ lib\n│  └─ index.js\n└─ package.json\n```\n\n### Plugin Entry\n\nThe `lib/index.js` file is the plugin entry, which should export the plugin directly:\n\n<CodeGroup>\n  <CodeGroupItem title="CJS" active>\n\n```js\nmodule.exports = fooPlugin\n```\n\n  </CodeGroupItem>\n\n  <CodeGroupItem title="ESM">\n\n```js\nexport default fooPlugin\n```\n\n  </CodeGroupItem>\n</CodeGroup>\n\n::: tip\nNotice that the plugin entry will be loaded in Node, so it should be in CommonJS format.\n\nIf you are using ESM format, you\'ll need to use [babel](https://babeljs.io/) or [typescript](https://www.typescriptlang.org/) to transpile it into CommonJS.\n:::\n\n### package.json\n\nThe [package.json](https://docs.npmjs.com/cli/v6/configuring-npm/package-json) file is required to publish a package to NPM:\n\n```json\n{\n  "name": "vuepress-plugin-foo",\n  "version": "1.0.0",\n  "keywords": [\n    "vuepress-plugin",\n  ],\n  "main": "lib/index.js",\n  "files": [\n    "lib"\n  ]\n}\n```\n\n- Set `name` to follow the naming convention: `vuepress-plugin-xxx` or `@org/vuepress-plugin-xxx`.\n- Set `keywords` to include `vuepress-plugin`, so that users can search your plugin on NPM.\n- Set `main` to the plugin entry file.\n- Set `files` to only publish those files inside `lib` directory.\n',length:290,readingTime:.97}},52099:(n,e,s)=>{s.r(e),s.d(e,{default:()=>P});var l=s(66124);const a=(0,l._)("h1",{id:"writing-a-plugin",tabindex:"-1"},[(0,l._)("a",{class:"header-anchor",href:"#writing-a-plugin","aria-hidden":"true"},"#"),(0,l.Uk)(" Writing a Plugin")],-1),o={class:"custom-container tip"},i=(0,l._)("p",{class:"custom-container-title"},"TIP",-1),t=(0,l.Uk)("Before reading this guide, you’d better learn the VuePress "),r=(0,l.Uk)("architecture"),p=(0,l.Uk)(" first."),c=(0,l._)("h2",{id:"create-a-plugin",tabindex:"-1"},[(0,l._)("a",{class:"header-anchor",href:"#create-a-plugin","aria-hidden":"true"},"#"),(0,l.Uk)(" Create a Plugin")],-1),u=(0,l.Uk)("A VuePress plugin is a plain JavaScript object that satisfies the "),d=(0,l.Uk)("Plugin API"),D=(0,l.Uk)(", which is called a "),g=(0,l._)("em",null,"Plugin Object",-1),h=(0,l.Uk)("."),y=(0,l._)("p",null,[(0,l.Uk)("If a plugin wants to receive user options, it could be a function that returns a "),(0,l._)("em",null,"Plugin Object"),(0,l.Uk)(", which is called a "),(0,l._)("em",null,"Plugin Function"),(0,l.Uk)(".")],-1),m=(0,l._)("div",{class:"language-javascript ext-js line-numbers-mode"},[(0,l._)("pre",{class:"shiki",style:{"background-color":"#1E1E1E"}},[(0,l._)("code",null,[(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#569CD6"}},"const"),(0,l._)("span",{style:{color:"#D4D4D4"}}," "),(0,l._)("span",{style:{color:"#4FC1FF"}},"fooPlugin"),(0,l._)("span",{style:{color:"#D4D4D4"}}," = {")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#D4D4D4"}},"  "),(0,l._)("span",{style:{color:"#9CDCFE"}},"name:"),(0,l._)("span",{style:{color:"#D4D4D4"}}," "),(0,l._)("span",{style:{color:"#CE9178"}},"'vuepress-plugin-foo'"),(0,l._)("span",{style:{color:"#D4D4D4"}},",")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#D4D4D4"}},"  "),(0,l._)("span",{style:{color:"#6A9955"}},"// ...")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#D4D4D4"}},"}")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"})])]),(0,l._)("div",{class:"line-numbers","aria-hidden":"true"},[(0,l._)("div",{class:"line-number"}),(0,l._)("div",{class:"line-number"}),(0,l._)("div",{class:"line-number"}),(0,l._)("div",{class:"line-number"})])],-1),_=(0,l._)("div",{class:"language-javascript ext-js line-numbers-mode"},[(0,l._)("pre",{class:"shiki",style:{"background-color":"#1E1E1E"}},[(0,l._)("code",null,[(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#569CD6"}},"const"),(0,l._)("span",{style:{color:"#D4D4D4"}}," "),(0,l._)("span",{style:{color:"#DCDCAA"}},"fooPlugin"),(0,l._)("span",{style:{color:"#D4D4D4"}}," = ("),(0,l._)("span",{style:{color:"#9CDCFE"}},"options"),(0,l._)("span",{style:{color:"#D4D4D4"}},", "),(0,l._)("span",{style:{color:"#9CDCFE"}},"app"),(0,l._)("span",{style:{color:"#D4D4D4"}},") "),(0,l._)("span",{style:{color:"#569CD6"}},"=>"),(0,l._)("span",{style:{color:"#D4D4D4"}}," {")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#D4D4D4"}},"  "),(0,l._)("span",{style:{color:"#C586C0"}},"return"),(0,l._)("span",{style:{color:"#D4D4D4"}}," {")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#D4D4D4"}},"    "),(0,l._)("span",{style:{color:"#9CDCFE"}},"name:"),(0,l._)("span",{style:{color:"#D4D4D4"}}," "),(0,l._)("span",{style:{color:"#CE9178"}},"'vuepress-plugin-foo'"),(0,l._)("span",{style:{color:"#D4D4D4"}},",")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#D4D4D4"}},"    "),(0,l._)("span",{style:{color:"#6A9955"}},"// ...")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#D4D4D4"}},"  }")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#D4D4D4"}},"}")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"})])]),(0,l._)("div",{class:"line-numbers","aria-hidden":"true"},[(0,l._)("div",{class:"line-number"}),(0,l._)("div",{class:"line-number"}),(0,l._)("div",{class:"line-number"}),(0,l._)("div",{class:"line-number"}),(0,l._)("div",{class:"line-number"}),(0,l._)("div",{class:"line-number"})])],-1),v=(0,l.uE)('<h2 id="publish-to-npm" tabindex="-1"><a class="header-anchor" href="#publish-to-npm" aria-hidden="true">#</a> Publish to NPM</h2><p>The typical structure of a plugin package is as follow:</p><div class="language-bash ext-sh line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#D4D4D4;">vuepress-plugin-foo</span></span>\n<span class="line"><span style="color:#D4D4D4;">├─ lib</span></span>\n<span class="line"><span style="color:#D4D4D4;">│  └─ index.js</span></span>\n<span class="line"><span style="color:#D4D4D4;">└─ package.json</span></span>\n<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="plugin-entry" tabindex="-1"><a class="header-anchor" href="#plugin-entry" aria-hidden="true">#</a> Plugin Entry</h3><p>The <code>lib/index.js</code> file is the plugin entry, which should export the plugin directly:</p>',5),b=(0,l._)("div",{class:"language-javascript ext-js line-numbers-mode"},[(0,l._)("pre",{class:"shiki",style:{"background-color":"#1E1E1E"}},[(0,l._)("code",null,[(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#4EC9B0"}},"module"),(0,l._)("span",{style:{color:"#D4D4D4"}},"."),(0,l._)("span",{style:{color:"#4EC9B0"}},"exports"),(0,l._)("span",{style:{color:"#D4D4D4"}}," = "),(0,l._)("span",{style:{color:"#9CDCFE"}},"fooPlugin")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"})])]),(0,l._)("div",{class:"line-numbers","aria-hidden":"true"},[(0,l._)("div",{class:"line-number"})])],-1),f=(0,l._)("div",{class:"language-javascript ext-js line-numbers-mode"},[(0,l._)("pre",{class:"shiki",style:{"background-color":"#1E1E1E"}},[(0,l._)("code",null,[(0,l._)("span",{class:"line"},[(0,l._)("span",{style:{color:"#C586C0"}},"export"),(0,l._)("span",{style:{color:"#D4D4D4"}}," "),(0,l._)("span",{style:{color:"#C586C0"}},"default"),(0,l._)("span",{style:{color:"#D4D4D4"}}," "),(0,l._)("span",{style:{color:"#9CDCFE"}},"fooPlugin")]),(0,l.Uk)("\n"),(0,l._)("span",{class:"line"})])]),(0,l._)("div",{class:"line-numbers","aria-hidden":"true"},[(0,l._)("div",{class:"line-number"})])],-1),C=(0,l.uE)('<div class="custom-container tip"><p class="custom-container-title">TIP</p><p>Notice that the plugin entry will be loaded in Node, so it should be in CommonJS format.</p><p>If you are using ESM format, you’ll need to use <a href="https://babeljs.io/" target="_blank" rel="noopener noreferrer">babel</a> or <a href="https://www.typescriptlang.org/" target="_blank" rel="noopener noreferrer">typescript</a> to transpile it into CommonJS.</p></div><h3 id="package-json" tabindex="-1"><a class="header-anchor" href="#package-json" aria-hidden="true">#</a> package.json</h3><p>The <a href="https://docs.npmjs.com/cli/v6/configuring-npm/package-json" target="_blank" rel="noopener noreferrer">package.json</a> file is required to publish a package to NPM:</p><div class="language-json ext-json line-numbers-mode"><pre class="shiki" style="background-color:#1E1E1E;"><code><span class="line"><span style="color:#D4D4D4;">{</span></span>\n<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#9CDCFE;">&quot;name&quot;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&quot;vuepress-plugin-foo&quot;</span><span style="color:#D4D4D4;">,</span></span>\n<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#9CDCFE;">&quot;version&quot;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&quot;1.0.0&quot;</span><span style="color:#D4D4D4;">,</span></span>\n<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#9CDCFE;">&quot;keywords&quot;</span><span style="color:#D4D4D4;">: [</span></span>\n<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#CE9178;">&quot;vuepress-plugin&quot;</span><span style="color:#D4D4D4;">,</span></span>\n<span class="line"><span style="color:#D4D4D4;">  ],</span></span>\n<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#9CDCFE;">&quot;main&quot;</span><span style="color:#D4D4D4;">: </span><span style="color:#CE9178;">&quot;lib/index.js&quot;</span><span style="color:#D4D4D4;">,</span></span>\n<span class="line"><span style="color:#D4D4D4;">  </span><span style="color:#9CDCFE;">&quot;files&quot;</span><span style="color:#D4D4D4;">: [</span></span>\n<span class="line"><span style="color:#D4D4D4;">    </span><span style="color:#CE9178;">&quot;lib&quot;</span></span>\n<span class="line"><span style="color:#D4D4D4;">  ]</span></span>\n<span class="line"><span style="color:#D4D4D4;">}</span></span>\n<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ul><li>Set <code>name</code> to follow the naming convention: <code>vuepress-plugin-xxx</code> or <code>@org/vuepress-plugin-xxx</code>.</li><li>Set <code>keywords</code> to include <code>vuepress-plugin</code>, so that users can search your plugin on NPM.</li><li>Set <code>main</code> to the plugin entry file.</li><li>Set <code>files</code> to only publish those files inside <code>lib</code> directory.</li></ul>',5),k={},P=(0,s(61220).Z)(k,[["render",function(n,e){const s=(0,l.up)("RouterLink"),k=(0,l.up)("CodeGroupItem"),P=(0,l.up)("CodeGroup");return(0,l.wg)(),(0,l.iD)("div",null,[a,(0,l._)("div",o,[i,(0,l._)("p",null,[t,(0,l.Wm)(s,{to:"/vuepress-next/advanced/architecture.html"},{default:(0,l.w5)((()=>[r])),_:1}),p])]),c,(0,l._)("p",null,[u,(0,l.Wm)(s,{to:"/vuepress-next/reference/plugin-api.html"},{default:(0,l.w5)((()=>[d])),_:1}),D,g,h]),y,(0,l.Wm)(P,null,{default:(0,l.w5)((()=>[(0,l.Wm)(k,{title:"Plugin Object",active:""},{default:(0,l.w5)((()=>[m])),_:1}),(0,l.Wm)(k,{title:"Plugin Function"},{default:(0,l.w5)((()=>[_])),_:1})])),_:1}),v,(0,l.Wm)(P,null,{default:(0,l.w5)((()=>[(0,l.Wm)(k,{title:"CJS",active:""},{default:(0,l.w5)((()=>[b])),_:1}),(0,l.Wm)(k,{title:"ESM"},{default:(0,l.w5)((()=>[f])),_:1})])),_:1}),C])}]])}}]);