1. Project Overview & Quickstart (unplugin/LICENSE)
LICENSE
Open-source repository unplugin/LICENSE
Repository Details
- Repository: unplugin/LICENSE
- Primary Language: Code
Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.
2. Official Technical Reference & Guides (unplugin/docs)
File: README.md
[!IMPORTANT]
Docs has been move to unjs/unplugin. This repository is now archived.
Unplugin
Development
This project use GitHub GraphQL API to generate the showcase data. So you need to create a GitHub Personal Access Token first.
cp .env.example .env# .env
GITHUB_TOKEN=<YOUR_TOKEN>Generate files
pnpm gen-filesContributing
Please refer to https://github.com/antfu/contribute
File: guide/index.md
outline: deep lastUpdated: false
Getting Started
Overview
Unplugin is a library that offers an unified plugin system for various build tools. It extends the excellent Rollup plugin API to serve as the standard plugin interface, and provides a compatibility layer based on the build tools employed.
Unplugin current supports:
Trying It Online
You can try Unplugin in your browser directly.
Creating an Unplugin package
npx degit unplugin/unplugin-starter unplugin-starterCheck the unplugin-starter repository for more details.
Plugin Installation
Pre-requisites
- Node.js 14.0.0 or later
::: warning
We will discontinue support for Node.js v14 & v16 in the next major release.
Please consider upgrading to Node.js v18 or higher.
:::
Install package
::: code-group
npm install unplugin-starter --save-devyarn add unplugin-starter -Dpnpm add unplugin-starter -Dbun add unplugin-starter -D:::
Bundler & Framework Integration
::: code-group
// vite.config.ts
import Starter from 'unplugin-starter/vite'
export default defineConfig({
plugins: [
Starter({ /* options */ }),
],
})// rollup.config.js
import Starter from 'unplugin-starter/rollup'
export default {
plugins: [
Starter({ /* options */ }),
],
}// webpack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-starter/webpack')({ /* options */ })
]
}// rspack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-starter/rspack')({ /* options */ })
]
}// esbuild.config.js
import { build } from 'esbuild'
import Starter from 'unplugin-starter/esbuild'
build({
plugins: [Starter()],
})// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
require('unplugin-starter/webpack')({ /* options */ }),
],
},
}// nuxt.config.ts
export default defineNuxtConfig({
modules: [
['unplugin-starter/nuxt', { /* options */ }],
],
})// astro.config.mjs
import { defineConfig } from 'astro/config';
import Starter from 'unplugin-turbo-console/astro'
// https://astro.build/config
export default defineConfig({
integrations: [
Starter()
]
});Supported Hooks
| Hook | Rollup | Vite | webpack 4 | webpack 5 | esbuild | Rspack |
|---|---|---|---|---|---|---|
enforce |
โ 1 | โ | โ | โ | โ 1 | โ |
buildStart |
โ | โ | โ | โ | โ | โ |
resolveId |
โ | โ | โ | โ | โ | โ |
loadInclude2 |
โ | โ | โ | โ | โ | โ |
load |
โ | โ | โ | โ | โ 3 | โ |
transformInclude2 |
โ | โ | โ | โ | โ | โ |
transform |
โ | โ | โ | โ | โ 3 | โ |
watchChange |
โ | โ | โ | โ | โ | โ |
buildEnd |
โ | โ | โ | โ | โ | โ |
writeBundle4 |
โ | โ | โ | โ | โ | โ |
::: details Notice
- Rollup and esbuild do not support using
enforceto control the order of plugins. Users need to maintain the order manually. - webpack's id filter is outside of loader logic; an additional hook is needed for better perf on webpack. In Rollup and Vite, this hook has been polyfilled to match the behaviors. See for the following usage examples.
- Although esbuild can handle both JavaScript and CSS and many other file formats, you can only return JavaScript in
loadandtransformresults. - Currently,
writeBundleis only serves as a hook for the timing. It doesn't pass any arguments.
:::
Usage
import type { UnpluginFactory } from 'unplugin'
import { createUnplugin } from 'unplugin'
export interface Options {
// define your plugin options here
}
export const unpluginFactory: UnpluginFactory<Options | undefined> = options => ({
name: 'unplugin-starter',
// webpack's id filter is outside of loader logic,
// an additional hook is needed for better perf on webpack
transformInclude(id) {
return id.endsWith('main.ts')
},
// just like rollup transform
transform(code) {
return code.replace(/<template>/, '<template>Injected')
},
// more hooks coming
})
export const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)
export default unplugin
export const vitePlugin = unplugin.vite
export const rollupPlugin = unplugin.rollup
export const webpackPlugin = unplugin.webpack
export const rspackPlugin = unplugin.rspack
export const esbuildPlugin = unplugin.esbuildSupported Context
| Context | Rollup | Vite | webpack 4 | webpack 5 | esbuild | Rspack |
|---|---|---|---|---|---|---|
this.parse |
โ | โ | โ | โ | โ | โ |
this.addWatchFile |
โ | โ | โ | โ | โ | โ |
this.emitFile1 |
โ | โ | โ | โ | โ | โ |
this.getWatchFiles |
โ | โ | โ | โ | โ | โ |
this.warn |
โ | โ | โ | โ | โ | โ |
this.error |
โ | โ | โ | โ | โ | โ |
::: info Notice
- Currently,
this.emitFileonly supports theEmittedAssetvariant.
:::
Nested Plugins
Since v0.10.0, Unplugin supports constructing multiple nested plugins to behave like a single one.
Bundler Supported
| Rollup | Vite | webpack 4 | webpack 5 | Rspack | esbuild |
|---|---|---|---|---|---|
โ
>=3.11 |
โ | โ | โ | โ | โ (v1.8.0+) |
::: details Notice
- Rollup supports nested plugins since v3.1.0. Plugin author should ask users to have a Rollup version of
>=3.1.0when using nested plugins. For single plugin format, Unplugin works for any version of Rollup.
:::
Usage
import type { UnpluginFactory } from 'unplugin'
import { createUnplugin } from 'unplugin'
export interface Options {
// define your plugin options here
}
export const unpluginFactory: UnpluginFactory<Options | undefined> = options => (
[
{
name: 'plugin-a',
transform(code) {
return code.replace(/<template>/, '<template>Injected')
},
},
{
name: 'plugin-b',
resolveId(id) {
return id
},
},
]
)
export const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)
export default unpluginBundler-Specific Logic
While Unplugin provides compatible layers for some hooks, the functionality of it is limited to the common subset of the build's plugins capability. For more advanced bundler-specific usages, Unplugin provides an escape hatch for that.
Hooks
import type { UnpluginFactory } from 'unplugin'
import { createUnplugin } from 'unplugin'
export interface Options {
// define your plugin options here
}
export const unpluginFactory: UnpluginFactory<Options | undefined> = (options, meta) => {
console.log(meta.framework) // vite rollup webpack esbuild rspack
return {
name: 'unplugin-starter',
transform(code) {
return code.replace(/<template>/, '<template>Injected')
},
transformInclude(id) {
return id.endsWith('main.ts')
},
vite: {
// Vite plugin
configureServer(server) {
// configure Vite server
},
},
rollup: {
// Rollup plugin
},
webpack(complier) {
// Configure webpack compiler
},
rspack(complier) {
// Configure webpack compiler
},
esbuild: {
// Change the filter of onResolve and onLoad
// onResolveFilter?: RegExp,
// onLoadFilter?: RegExp,
// Tell esbuild how to interpret the contents. By default Unplugin tries to guess the loader
// from file extension (eg: .js -> "js", .jsx -> 'jsx')
// loader?: (Loader | (code: string, id: string) => Loader)
// Or you can completely replace the setup logic
// setup?: EsbuildPlugin.setup,
},
}
}
export const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)
export default unpluginPlugins
The package exports a set of functions in place of createUnplugin that allow for the creation of plugins for specific bundlers.
Each of the function takes the same generic factory argument as createUnplugin.
import {
createEsbuildPlugin,
createRollupPlugin,
createRspackPlugin,
createVitePlugin,
createWebpackPlugin
} from 'unplugin'
const vitePlugin = createVitePlugin({ /* options */ })
const rollupPlugin = createRollupPlugin({ /* options */ })
const esbuildPlugin = createEsbuildPlugin({ /* options */ })
const webpackPlugin = createWebpackPlugin({ /* options */ })
const rspackPlugin = createRspackPlugin({ /* options */ })File: guide/plugin-conventions.md
aside: false lastUpdated: false
Plugin Conventions
To have a better community and ecosystem, we encourage plugin authors to follow these conventions when creating unplugins.
- Plugins powered by Unplugin should have a clear name with
unplugin-prefix. - Include
unpluginkeyword inpackage.json. - To provide better DX, packages could export 2 kinds of entry points:
Default export: the returned value of
createUnpluginfunctiontsimport UnpluginFeature from 'unplugin-feature'Subpath exports: properties of the returned value of
createUnpluginfunction for each bundler userstsimport VitePlugin from 'unplugin-feature/vite'Refer to unplugin-starter for more details about this setup.