Skip to content

Commit

Permalink
chore: add hmr api and js plugin api
Browse files Browse the repository at this point in the history
  • Loading branch information
wre232114 committed Feb 1, 2024
1 parent 6e54026 commit 062a590
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 84 deletions.
64 changes: 64 additions & 0 deletions docs/api/hmr-api.md
Original file line number Diff line number Diff line change
@@ -1 +1,65 @@
# Hmr Api
:::note
The HMR API is compatible with [Vite's HMR API](https://vitejs.dev/guide/api-hmr.html).
:::

Farm exposes its manual HMR API via the special import.meta.hot object(the same as Vite):
```ts
export interface ViteHotContext {
readonly data: any;

accept(): void;
accept(cb: (mod: ModuleNamespace | undefined) => void): void;
accept(dep: string, cb: (mod: ModuleNamespace | undefined) => void): void;
accept(
deps: readonly string[],
cb: (mods: Array<ModuleNamespace | undefined>) => void
): void;

// acceptExports is not supported in Farm for now
// acceptExports(
// exportNames: string | readonly string[],
// cb?: (mod: ModuleNamespace | undefined) => void
// ): void;

dispose(cb: (data: any) => void): void;
prune(cb: (data: any) => void): void;
invalidate(message?: string): void;

on<T extends string>(
event: T,
cb: (payload: InferCustomEventPayload<T>) => void
): void;
off<T extends string>(
event: T,
cb: (payload: InferCustomEventPayload<T>) => void
): void;
send<T extends string>(event: T, data?: InferCustomEventPayload<T>): void;
}
```

## Required Conditional Guard

## IntelliSense for TypeScript

## hot.accept()

## hot.accept(cb)

## hot.accept(deps, cb)

## hot.dispose(cb)

## hot.prune(cb)

## hot.data

## hot.decline()

## hot.invalidate(message?: string)

## hot.on(event, cb)

## hot.off(event, cb)

## hot.send(event, data)
151 changes: 102 additions & 49 deletions docs/api/js-plugin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,80 +15,133 @@ If your plugin is only applicable to a specific framework, its name should follo
- `farm-plugin-vue-`: Prefix as a Vue plugin
- `farm-plugin-react-`: Prefix as a React plugin
- `farm-plugin-svelte-`: Prefix as a svelte plugin
- ...

## Plugins config
## Configuring Js Plugins

```ts
// farm.config.js
Adding JS plugins by `plugins` option:

```ts title="farm.config.ts" {3,7}
import { defineConfig } from "@farmfe/core";
import farmPlugin from "farm-plugin";
import vitePlugin from "vite-plugin";
import rollupPlugin from "roll-plugin";
// import a js plugin
import farmPluginFoo from "farm-plugin-foo";

export default defineConfig({
plugins: [farmPlugin(), vitePlugin(), rollupPlugin()],
// configuring it in plugins
plugins: [farmPluginFoo()],
});
```

Plugins can also accept `multiple plugins` as presets for a single element.
## Writing Js Plugins
A Farm Js Plugin is a plain javascript object which exposes a set of `hook`s. for example:

```ts
import framework1 from "farm-plugin-framework1";
import framework2 from "farm-plugin-framework2";
```ts title="my-farm-plugin.ts"
// Create a plugin file that exports a plugin function which returns a `JsPlugin` Object:

import type { JsPlugin } from '@farmfe/core';

export default function framework(config) {
return [framework1(config), framework2(config)];
// Plugin Options
export interface PluginOptions {
test: boolean;
}
```
// export a Plugin Function
export default function MyPlugin(options: PluginOptions): JsPlugin {
// reading options
const { test } = options;

```ts
// return a object that exposes hook
return {
name: 'my-farm-plugin',
// using load hook to load custom modules
load: {
filters: {
resolvedPaths: ['\\.test$'] // filter files to improve performance
},
executor({ resolvedPath }) {
if (test && resolvedPath.endsWith('.test')) {
return {
content: 'test file',
sourceMap: null
}
}
}
}
}
}
```
then using the plugin in `farm.config.ts`:
```ts title="farm.config.ts" {3,7}
import { defineConfig } from "@farmfe/core";
import framework from "farm-plugin-framework";
// import a js plugin
import myFarmPlugin from "./my-farm-plugin";

export default defineConfig({
plugins: [framework()],
// configuring it in plugins
plugins: [myFarmPlugin({
test: true
})],
});
```

## Example
:::note
For more details of writing JS plugins, refer to [Writing JS Plugins](/docs/plugins/writing-plugins/js-plugin)
:::

### transform vue suffix file
## hooks
### name
- **type: `string`**
- **required: `true`**

The name of this plugins, MUST not be empty.
```ts
export default function plugin() {
export default function MyPlugin() {
return {
name: "transform--vue-file",
load: {
filters: {
resolvedPaths: [".vue$"],
},
async executor(params) {
const { resolvedPath } = params;
const content = await tryToReadFileSync(resolvedPath);
return {
content,
moduleType: "vue",
};
},
},
transform: {
filter: {
moduleTypes: ["vue"],
},
async executor(params) {
const { resolvedPath, content } = params;
ctx.handleTransform(resolvedPath);
return {
content,
moduleType: "js",
};
},
},
};
name: 'my-plugin',
// ...
}
}
```

## hook
### priority
### name
- **type: `number`**
- **required: `false`**
- **default: `100`**

The priority of this plugins, default to `100`. `priority` controls the execution order of plugins, the larger the value, the earlier the plugin is executed.

```ts
export default function MyPlugin() {
return {
name: 'my-plugin',
priority: 1000, // make this plugins execute bebore all other plugins
// ...
}
}
```
:::note
Note that the priority of most farm internal plugins like `plugin-script`, `plugin-resolve` is `99`, which means your plugins is always executed before the internal plugins. If your want to make your plugin executed after farm internal plugins, set `priority` to a value that smaller than `99`, for example: `98`. Also the priority value can be negative, you can set it to `-9999` to make sure it is always executed at last.
:::

### config
### configResolved
### configureDevServer
### configureCompiler
### buildStart
### resolve
### load
### transform
### buildEnd
### renderStart
### renderResourcePot
### argumentResourceHash
### finalizeResources
### transformHtml
### writeResources
### pluginCacheLoaded
### writePluginCache
### finish
### updateModules

```ts
export interface JsPlugin {
Expand Down
32 changes: 0 additions & 32 deletions docs/config/environment-variable.md

This file was deleted.

33 changes: 32 additions & 1 deletion docs/features/env.md
Original file line number Diff line number Diff line change
@@ -1 +1,32 @@
# Enviroment Variables and Modes
# Enviroment Variables and Modes

`Farm` distinguishes between development and production environments through `Farm` process.env.NODE\_ ENV`.

In different environments, environment variables are replaced statically, so use static constants to represent environment variables instead of dynamic expressions.

## `.env` file

`Farm` uses `dotenv` to load your additional environment variables, such as `.env` files.

```js
// .env
FARM_APP_SECRET=secret
Farm_APP_PASSWORD=password
APP_VERSION=1.0.0
```

`Farm` loads the file `.env` via dotenv, and loads it into `process.env` and finally injects it into define.

:::warning
In order to ensure the security of the client, preventing the environment variables in the current system from being exposed to the client `Farm` will only identify some important environment variables that start with `Farm`.
:::

`Farm` expands environment variables through dotenv-expand

If you want to customize the prefix of env variables, you can configure `envPrefix`.

## envPrefix

- **default value**: `FARM_`

Customize the prefix of the `env` variable by configuring `envPrefix`.
3 changes: 1 addition & 2 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const sidebars = {
{
type: "category",
label: "Features",
collapsed: true,
collapsed: false,
items: [
"features/dev-server",
"features/html",
Expand Down Expand Up @@ -82,7 +82,6 @@ const sidebars = {
"config/compilation-options",
"config/dev-server",
"config/shared",
"config/environment-variable",
"config/plugins-options",
],
},
Expand Down

0 comments on commit 062a590

Please sign in to comment.