Skip to content

Commit

Permalink
docs: YAML plugin lesson updates (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
patak-dev authored Jul 22, 2024
1 parent b8f5a67 commit 8863dde
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
type: lesson
title: Defining custom plugin
title: Defining a custom plugin
focus: /vite.config.ts
---

# Defining custom plugin
# Defining a custom plugin

Plugins can have various properties that are listed in [Plugin API | Vite](https://vitejs.dev/guide/api-plugin.html) documentation. The only **required property** is `name`.
A plugin is a plain object that defines hooks to modify the way Vite resolves ids, loads and transforms modules, and more. It can have various properties that are listed in the [Plugin API | Vite](https://vitejs.dev/guide/api-plugin.html) documentation. The only **required property** is `name`.

Let's start by adding a custom plugin in our Vite configuration. To do this, add a new `plugins` property into the Vite configuration. The `plugins` should be an array.
Let's start by adding a custom plugin in our Vite config file. To do this, add a new `plugins` array property in the exported config object.

Inside the `plugins` array, define a new object with `name` `'yaml-plugin'`.
Then, let's add a new object with `name` `'yaml-plugin'` inside the `plugins` array.

Successfully defined plugin should be reported in the Preview tab:
A successfully defined plugin should be reported in the Preview tab:

> Loaded Vite plugins: yaml-plugin ✅
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
type: lesson
title: Defining load hook
title: Defining the load hook
focus: /vite.config.ts
---

# Defining load hook
# Defining the load hook

Next we'll need to intercept loading of `.yaml` files. Let's start by adding a [`load`](https://rollupjs.org/plugin-development/#load) hook in our Vite plugin.

Expand All @@ -16,7 +16,7 @@ Next we'll need to intercept loading of `.yaml` files. Let's start by adding a [
}
```

Vite will call this hook with all the loaded files. As our plugin is only interested in `.yaml` files, we can check `id` for this extension.
Vite will call the load hook of every plugin for each resolved id to the load the module code. A load hook can return custom code for an id, or skip it by to let other plugins handle it. As our plugin is only interested in `.yaml` files, we can check `id` for this extension.

```js
{
Expand All @@ -29,7 +29,7 @@ Vite will call this hook with all the loaded files. As our plugin is only intere
}
```

Our `load` function should return an object with `code` property. This property should contain the actual code that importing this specific `.yaml` file should produce. As we don't yet know how to convert `.yaml` files into Javascript, we can return something simpler here.
Our `load` function should return an object with a `code` property for these ids. This property should contain the actual code that importing this specific `.yaml` file should produce. As we don't yet know how to convert `.yaml` files into JavaScript, let's return a simple module that exports a default string first:

```js
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ title: Importing YAML files
focus: /index.js
---

# Welcome to Vite Plugin tutorial
# Welcome to the Vite Plugin API tutorial

Hey there, and welcome to Vite Plugin tutorial 👋!
Hey there, and welcome to the Vite Plugin API tutorial 👋!

In this tutorial we'll go through steps for creating custom Vite plugins. We'll start by creating a custom Vite plugin for loading `.yaml` files.
We'll create custom Vite plugins step by step, starting with a custom Vite plugin for loading `.yaml` files.

Our goal is to be able to import `content.yaml` file in a Javascript file and use it as plain Javascript object.
Our goal is to be able to import a `content.yaml` file in a module and use it as plain JavaScript object:

```js [index.js]
import content from "./content.yaml";
Expand All @@ -19,7 +19,7 @@ console.log(content);
// > [{ employees: [{ id: 1, ... }, ...], projects: [{ id: 101, ...}, ...] }]
```

Try doing this in `index.js`:
Starting with the content as a variable in `index.js`, try changing the code to import it from the YAML file instead:

```js [index.js] add={1} del={2}
import content from "./content.yaml";
Expand All @@ -28,4 +28,4 @@ const content = ["Initial content"];
export default content;
```

At this point we should run into error when Vite fails to load `.yaml` file. 
We should run into an error when Vite fails to load `.yaml` file. 
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ focus: /vite.config.ts

# Processing YAML files

Our Vite plugin can now recognize `.yaml` files that are being loaded. Next we'll need to add logic for converting the `.yaml` files into Javascript and pass the output from `load` hook.
Our Vite plugin can now properly intercept `.yaml` files that are being loaded. Next we'll need to add logic for converting the `.yaml` files into JavaScript and return that as the output of our `load` hook.

To get the content of requested file we'll need to use [`readFileSync`](https://nodejs.org/api/fs.html#fsreadfilesyncpath-options) method from `node:fs`.
We can convert the YAML content into Javascript using [`yaml`](https://www.npmjs.com/package/yaml) package. It has a `parse()` function that takes YAML content as `string`.
To get the content of requested file we can use [`readFileSync`](https://nodejs.org/api/fs.html#fsreadfilesyncpath-options) method from `node:fs`.
We can convert the YAML content into JavaScript using the [`yaml`](https://www.npmjs.com/package/yaml) npm package. It has a `parse()` function that takes YAML content as `string` and returns a JavaScript object.

```ts
import { readFileSync } from "node:fs";
Expand All @@ -20,18 +20,18 @@ const yaml = parse(content);
// ^^^^ [{ employees: [{ id: 1, ...}, ...], projects: [{ id: 101, ...}] }]
```

The `yaml` variable now holds a Javascript object that represents our `content.yaml` contents. To return this from `load` hook, we'll need to serialize it to string with [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify):
The `yaml` variable now holds an object that represents our `content.yaml` contents. To return this from the `load` hook, we'll need to serialize it to a string with [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify):

```ts
return {
code: `export default ${JSON.stringify(yaml)}`
};
```

Add required logic to Vite plugin's load hook:
Add the required logic to Vite plugin's load hook:

- Read requested file from file system using `readFileSync` (filename is in `id` variable)
- Convert contents of `.yaml` file into Javascript using `parse` from `yaml` package
- Serialize the Javascript object into `string` and return it as default export from the `load` hook
- Read requested file from file system using `readFileSync` (the filename is the `id` parameter).
- Convert contents of `.yaml` file into Javascript using `parse` from `yaml` package.
- Serialize the JavaScript object into a `string` and return it as the default export of a module from the `load` hook.

Contents of `content.yaml` should appear in preview as JSON. 
The contents of `content.yaml` should appear in the preview as JSON. 
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ focus: /vite.config.ts

# Summary

Our custom Vite plugin can now intercept `*.yaml` file imports and convert them into Javascript.
Our custom Vite plugin can now intercept `*.yaml` file imports and load them as JavaScript modules.

Before you head on to create your own plugins for loading some other non-Javascript files, let's summarize what we've done:

Expand All @@ -25,3 +25,5 @@ Before you head on to create your own plugins for loading some other non-Javascr
</ol>

📚 Homework: Build a Vite plugin that can import [`.csv` files](https://en.wikipedia.org/wiki/Comma-separated_values) directly into Javascript. You can even build your own minimal CSV-parser!

Tip: Before creating your own plugin, search for popular Vite or compatible Rollup plugins. For YAML support, you can directly add the official [@rollup/plugin-yaml](https://www.npmjs.com/package/@rollup/plugin-yaml) to your Vite config.

0 comments on commit 8863dde

Please sign in to comment.