PageSourceSearch

https://farm-nightly.netlify.app/assets/js/3773b03c.c0cb03d7.js

js farm-nightly.netlify.app collected 2026-10-03 10:44:41 UTC 10,516 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkfarm_docs=self.webpackChunkfarm_docs||[]).push([[2723],{48418:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>t,contentTitle:()=>o,default:()=>a,frontMatter:()=>l,metadata:()=>s,toc:()=>c});var d=i(49214),r=i(36906);const l={},o="Runtime Plugin API",s={id:"api/runtime-plugin-api",title:"Runtime Plugin API",description:"Plugin hook definition:",source:"@site/docs/api/runtime-plugin-api.md",sourceDirName:"api",slug:"/api/runtime-plugin-api",permalink:"/docs/api/runtime-plugin-api",draft:!1,unlisted:!1,editUrl:"https://github.com/farm-fe/farm-fe.github.io/tree/main/docs/api/runtime-plugin-api.md",tags:[],version:"current",frontMatter:{},sidebar:"apiSidebar",previous:{title:"Rust Plugin Api",permalink:"/docs/api/rust-plugin-api"},next:{title:"Javascript Api",permalink:"/docs/api/javascript-api"}},t={},c=[{value:"Writing Runtime Plugin",id:"writing-runtime-plugin",level:2},{value:"Hooks",id:"hooks",level:2},{value:"name",id:"name",level:3},{value:"bootstrap",id:"bootstrap",level:3},{value:"moduleCreated",id:"modulecreated",level:3}
1,{value:"moduleInitialized",id:"moduleinitialized",level:3},{value:"readModuleCache",id:"readmodulecache",level:3},{value:"moduleNotFound",id:"modulenotfound",level:3},{value:"loadResource",id:"loadresource",level:3}];function u(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.header,{children:(0,d.jsx)(n.h1,{id:"runtime-plugin-api",children:"Runtime Plugin API"})}),"\n",(0,d.jsx)(n.p,{children:"Plugin hook definition:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"export interface FarmRuntimePlugin {\n  // plugin name\n  name: string;\n  // invoked when the module system is bootstrapped\n  bootstrap?: (moduleSystem: ModuleSystem) => void | Promise<void>;\n  // invoked after new module instances are created\n  moduleCreated?: (module: Module) => void | Promise<void>;\n  // invoked after module initialization functions are called\n  moduleInitialized?: (module: Module) => void | Promise<void>;\n  // invoked after module caches are read, return true to skip cache reading\n  readModuleCache?: (module: Module) => boolean | Promise<boolean>;\n  // called when module is not found\n  moduleNotFound?: (moduleId: string) => void | Promise<void>;\n  // called when loading resources, custom your resource loading in this hook.\n  // return { success: true } to indicate that this resources have been loaded successfully.\n  // return { success: false, retryWithDefaultResourceLoader: true } to indicate that this resources have not been loaded successfully and should be retried with the default resource loader.\n  loadResource?: (\n    resource: Resource,\n    targetEnv: 'browser' | 'node'\n  ) => Promise<ResourceLoadResult>;\n}\n"})}),"\n",(0,d.jsx)(n.h2,{id:"writing-runtime-plugin",children:"Writing Runtime Plugin"}),"\n",(0,d.jsxs)(n.p,{children:["See ",(0,d.jsx)(n.a,{href:"/docs/plugins/writing-plugins/runtime-plugin",children:"Writing Runtime Plugin"})]}),"\n",(0,d.jsx)(n.h2,{id:"hooks",children:"Hooks"}),"\n",(0,d.jsx)(n.p,{children:"Then are 2 kind of execution orders when calling Farm runtime plugin hooks:"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.code,{children:"serial"}),": The hook is called ono by one by the order of plugins. All plugins would be called serially."]}),"\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.code,{children:"first"}),":  Skip all left plugins once ",(0,d.jsx)(n.code,{children:"truthy"})," value is returned."]}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"Hook execution order:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-text",children:"          for each module                     true                         true                     return false\nbootstrap  -----------\x3e   module registered? ------\x3e module initialized?  ----\x3e readModuleCache -------------------------\x3e done\n           |                   |              false            |false              | return true                            | \n           |                   |                               |--------------\x3e moduleCreated   ------\x3e moduleInitialized --|\n           |                   |-------------------\x3e moduleNotFound\n           |\n           | dynamic import\n           | ---------------\x3e loadResource                         \n"})}),"\n",(0,d.jsx)(n.h3,{id:"name",children:"name"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"type"})}),": ",(0,d.jsx)(n.code,{children:"string"})]}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"The name of your runtime plugin."}),"\n",(0,d.jsx)(n.h3,{id:"bootstrap",children:"bootstrap"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"hook type"})}),": ",(0,d.jsx)(n.code,{children:"serial"})]}),"\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"type"})}),": ",(0,d.jsx)(n.code,{children:"(moduleSystem: ModuleSystem) => void | Promise<void>"})]}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"Invoked once when the module system is bootstrapped. Setup your plugin in this hook. Example:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"export default <Plugin>{\n  name: 'farm-runtime-hmr-client-plugin',\n  // define hooks\n  bootstrap(moduleSystem) {\n    hmrClient = new HmrClient(moduleSystem);\n    hmrClient.connect();\n  },\n};\n"})}
1),"\n",(0,d.jsx)(n.h3,{id:"modulecreated",children:"moduleCreated"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"hook type"})}),": ",(0,d.jsx)(n.code,{children:"serial"})]}),"\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"type"})}),": ",(0,d.jsx)(n.code,{children:"(module: Module) => void | Promise<void>"})]}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"Invoked after new module instances are created. You can read or update property of the new created module."}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"export default <Plugin>{\n  name: 'farm-runtime-hmr-client-plugin',\n  moduleCreated(module) {\n    // create a hot context for each module\n    module.meta.hot = createHotContext(module.id, hmrClient);\n  }\n};\n"})}),"\n",(0,d.jsx)(n.admonition,{type:"note",children:(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.code,{children:"moduleCreated"})," is called ",(0,d.jsx)(n.strong,{children:"BEFORE"})," the module is executed, so ",(0,d.jsx)(n.code,{children:"module.exports"})," is always empty, use ",(0,d.jsx)(n.code,{children:"moduleInitialized"})," instead if you want to access ",(0,d.jsx)(n.code,{children:"module.exports"}),"."]})}),"\n",(0,d.jsx)(n.h3,{id:"moduleinitialized",children:"moduleInitialized"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"hook type"})}),": ",(0,d.jsx)(n.code,{children:"serial"})]}),"\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"type"})}),": ",(0,d.jsx)(n.code,{children:"(module: Module) => void | Promise<void>"})]}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"Invoked after module initialization functions are called."}),"\n",(0,d.jsx)(n.admonition,{type:"note",children:(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.code,{children:"moduleCreated"})," is called ",(0,d.jsx)(n.strong,{children:"AFTER"})," the module is executed, so ",(0,d.jsx)(n.code,{children:"module.exports"})," is available is this hook."]})}),"\n",(0,d.jsx)(n.h3,{id:"readmodulecache",children:"readModuleCache"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"hook type"})}),": ",(0,d.jsx)(n.code,{children:"serial"})]}),"\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"type"})}),": ",(0,d.jsx)(n.code,{children:"(module: Module) => boolean | Promise<boolean>"})]}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"Invoked after module caches are read, return true to skip cache reading and re-executed the module."}),"\n",(0,d.jsx)(n.h3,{id:"modulenotfound",children:"moduleNotFound"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"hook type"})}),": ",(0,d.jsx)(n.code,{children:"serial"})]}),"\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"type"})}),": ",(0,d.jsx)(n.code,{children:"(module: Module) => void | Promise<void>"})]}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"Called when module is not registered."}),"\n",(0,d.jsx)(n.h3,{id:"loadresource",children:"loadResource"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"hook type"})}),": ",(0,d.jsx)(n.code,{children:"first"})]}),"\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.strong,{children:(0,d.jsx)(n.code,{children:"type"})}),": ",(0,d.jsx)(n.code,{children:"(resource: Resource, targetEnv: 'browser' | 'node') => Promise<ResourceLoadResult>"})]}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"called when loading resources, custom your resource loading in this hook."}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:["return ",(0,d.jsx)(n.code,{children:"{ success: true }"})," to indicate that this resources have been loaded successfully."]}),"\n",(0,d.jsxs)(n.li,{children:["return ",(0,d.jsx)(n.code,{children:"{ success: false, retryWithDefaultResourceLoader: true }"})," to indicate that this resources have not been loaded successfully and should be retried with the default resource loader."]}),"\n"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"import { Plugin } from '@farmfe/runtime';
1\n\nexport default <Plugin>{\n  name: 'runtime-plugin-example',\n  loadResource: (resource, targetEnv) => {\n    // override default resource loading\n    // load the resource from different location\n    return import('./replaced.js').then(() => {\n      return {\n        success: true\n      };\n    });\n  }\n};\n\n"})})]})}function a(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(u,{...e})}):u(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.