mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
183 lines
6 KiB
Markdown
183 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>
|