0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-16 21:56:25 -05:00
verdaccio/website/versioned_docs/version-6.x/plugin-theme.md
2023-10-10 18:54:30 +02:00

182 lines
6 KiB
Markdown

---
id: plugin-theme
title: 'Theme Plugin'
---
## What's a theme plugin? {#whats-a-theme-plugin}
Verdaccio uses by default a [custom UI](https://www.npmjs.com/package/@verdaccio/ui-theme) that provides a good set of feature to visualize the packages, but might be case your team needs some custom extra features and here is where a custom theme is an option. The plugin store static assets that will be loaded in the client side when the page is being rendered.
### How a theme plugin load phase works?
```mermaid
stateDiagram-v2
state if_loads <<choice>>
state if_load_fails <<choice>>
start : Verdaccio start
Yes: Loading custom plugin
No: Custom plugin not found
Yes_loads: Plugin loads successfully
No_loads: Plugin fails on load
load_default: Load default theme (@verdaccio/theme-ui)
Crash: Verdaccio stops
[*] --> start
start --> if_loads
if_loads --> No: false
if_loads --> Yes : true
Yes --> if_load_fails
No --> load_default
if_load_fails --> No_loads: false
if_load_fails --> Yes_loads : true
No_loads --> Crash
```
### How the assets of the theme loads? {#loads}
:::caution
By default the application loads on `http://localhost:4873`, but in cases where a resverse proxy with custom domain are involved the assets are loaded based on the property `__VERDACCIO_BASENAME_UI_OPTIONS.base` and `__VERDACCIO_BASENAME_UI_OPTIONS.basename`, thus only one domain configuration can be used.
:::caution
The theme loads only in the client side, the application renders HTML with `<script>` tags to render the application, the bundler takes care of load any other assets as `svg`, `images` or _chunks_ associated with it.
### The `__VERDACCIO_BASENAME_UI_OPTIONS` object
The `window.__VERDACCIO_BASENAME_UI_OPTIONS` is available in the browser global context, the shape is documented is defined by the [here](https://verdaccio.org/docs/next/api/types/modules/#templateuioptions) at the `TemplateUIOptions` types definitions.
```js
// output example
{
"darkMode": false,
"basename": "/",
"base": "https://registry.my.org/",
"primaryColor": "#4b5e40",
"version": "5.20.1",
"pkgManagers": [
"yarn",
"pnpm",
"npm"
],
"login": true,
"logo": "",
"title": "Verdaccio Registry",
"scope": "",
"language": "es-US"
}
```
### Theme Configuration {#theme-configuration}
By default verdaccio loads the `@verdaccio/ui-theme` which is bundled in the main package, if you want to load your custom plugin has to be installed where could be found.
```bash
$> npm install --global verdaccio-theme-dark
```
:::caution
The plugin name prefix must start with `verdaccio-theme-xxx`, otherwise the plugin will be ignored.
:::caution
You can load only **one theme at a time (if more are provided the first one is being selected)** and pass through options if you need it.
```yaml
theme:
dark:
option1: foo
option2: bar
```
These options will be available
### Plugin structure {#build-structure}
If you have a custom user interface theme has to follow a specific structure:
```
{
"name": "verdaccio-theme-xxxx",
"version": "1.0.0",
"description": "my custom user interface",
"main": "index.js",
}
```
The main file `index.js` file should contain the following content.
```
module.exports = () => {
return {
// location of the static files, webpack output
staticPath: path.join(__dirname, 'static'),
// webpack manifest json file
manifest: require('./static/manifest.json'),
// main manifest files to be loaded
manifestFiles: {
js: ['runtime.js', 'vendors.js', 'main.js'],
},
};
};
```
If any of the following properties are not available, the plugin won't load, thus follow this structure.
- `staticPath`: is the absolute/relative location of the statics files, could be any path either with `require.resolve` or build your self, what's important is inside of the package or any location that the Express.js middleware is able to find, behind the scenes the [`res.sendFile`](https://expressjs.com/en/api.html#res.sendFile) is being used.
- `manifest`: A Webpack manifest object.
- `manifestFiles`: A object with one property `js` and the array (order matters) of the manifest id to be loaded in the template dynamically.
- The `manifestFiles` refers to the main files must be loaded as part of the `html` scripts in order to load the page, you don't have to include the _chunks_ since are dynamically loaded by the bundler.
#### Manifest file {#manifest-and-webpack}
Verdaccio requires a [manifest](https://webpack.js.org/concepts/manifest/) object to render the html dynamically, in combination with the `manifestFiles` the application understand what to render.
> Currently only support `js` but if you also need `css`, we are open to discuss it and further improvements.
```
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
plugins: [
...
new WebpackManifestPlugin({
// this is optional depends of your implementation
removeKeyHash: true,
}),
...
],
```
#### Manifest with other bundlers
There is no feedback with other bundlers being used with theme plugins, but with `esbuild` could be possible generate manifests.
Alternatives:
- https://www.npmjs.com/package/esbuild-plugin-manifest
## Components UI {#components}
:::note
The components UI is an experimental feature can be used since verdccio@5.x, it's open to changes and **feedback is welcome**.
:::note
Create a new user interface from scratch is big effort, to facilitate the task exist the [@verdaccio/ui-components](https://www.npmjs.com/package/@verdaccio/ui-components) package. The components are based on the **React** library and **Material UI**.
The package export parts of the user interface that could be reused:
- React Hooks
- Providers (React Context API)
- Components
- Sections: **(Sidebar, Detail, Header, Home Page and Footer)**
https://ui-components.verdaccio.org
<iframe src="https://ui-components.verdaccio.org" height="900"></iframe>