Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOCS: Add Readme's for neos-ui-extensibility #3445 #3467

Merged
merged 1 commit into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions packages/neos-ui-extensibility-webpack-adapter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# @neos-project/neos-ui-extensibility-webpack-adapter

> Zero¹ configuration, highly opinionated Webpack 4 + Babel plugin buildstack for the Neos CMS UI.
mhsdesign marked this conversation as resolved.
Show resolved Hide resolved

## Installation
```bash
yarn add -D @neos-project/neos-ui-extensibility-webpack-adapter
```

## Alternative: Esbuild, vanilla Webpack5 (or any buildsystem with alias resolution)
If you prefer a less opinionated and modern build stack - or better, just want to choose and fully configure the bundler yourself - visit [@neos-project/neos-ui-extensibility](https://github.com/neos/neos-ui/blob/8.3/packages/neos-ui-extensibility) to use the Neos UI plugin API directly.

Note that this adapter uses a build stack created some time ago (Webpack4 + Babel) and exists mostly for convenience/backwards-compatibility, but is not state of the art and might never be again. So in case you're thinking about patching a new loader/option into the `webpack.config.js` you might as well just use Webpack directly or try out esbuild ;).

## Migrating from Neos =< 8.2 `@neos-project/neos-ui-extensibility`

Previously - before Neos 8.3 - the functionality of this package was provided via `@neos-project/neos-ui-extensibility`. Now `@neos-project/neos-ui-extensibility` is a code-only repo and does not ship any build system.
To migrate your plugin, just reference this package as a dependency:

```diff
"devDependencies": {
- "@neos-project/neos-ui-extensibility": "~8.2.0",
- "@neos-project/build-essentials": "~8.2.0"
+ "@neos-project/neos-ui-extensibility-webpack-adapter": "~8.3.0"
}
```

## Features

You don't need to recompile the Neos UI to integrate your own Plugins. Many Core functionalities are accessible through the `@neos-project/neos-ui-extensibility` API.
This package provides an opinionated Webpack build stack to access the bespoken API.

All available aliases are listed here: [@neos-project/neos-ui-extensibility/extensibilityMap.json](https://github.com/neos/neos-ui/blob/8.3/packages/neos-ui-extensibility/extensibilityMap.json).
You only need to import the modules, and they will work as if you installed those packages.
So `import React from "react"` will import React at runtime from the Neos UI host and you don't need to install it. (Also the same instance is used, which is important)


## Usage / Technial Neos Ui plugin setup
¹ well we need one configuration ;)

Creating a basic UI plugin package:

You have free choice about the directory structure (except that the `"buildTargetDirectory"` must point to the `Resources/Public` folder)

<details>
<summary>Example File structure</summary>

```
- My.CoolPlugin
- Configuration
- Settings.yaml
- Resources
- Private
- NeosUserInterface
- src
- index.js
- manifest.js
- package.json

# created on build ...
- Public
- NeosUserInterface
- Plugin.js
- Plugin.js.map
```

</details>

We place the plugin in `Resources/Private/NeosUserInterface`:

`package.json`
```json
{
"description": "my-coolplugin",
"scripts": {
"build": "NODE_ENV=production neos-react-scripts build",
"watch": "neos-react-scripts watch"
},
"main": "./src/index.js",
"neos": {
"buildTargetDirectory": "../../Public/NeosUserInterface"
},
"devDependencies": {
"@neos-project/neos-ui-extensibility-webpack-adapter": "~8.3.0"
}
}
```

In the folder `Resources/Public/NeosUserInterface` we will gather the build artifacts, which can be created by running `yarn build`. Keep in mind to set `NODE_ENV=production` as, otherwise the build files will not be minified.

The build stack will create `Resources/Public/NeosUserInterface/Plugin.js` and also `Resources/Public/NeosUserInterface/Plugin.css`, if you used any CSS.

To include these files in the Neos UI, you need to register your plugin in the YAML configuration:

`Settings.yaml`
```yaml
Neos:
Neos:
Ui:
resources:
javascript:
'My.CoolPlugin':
resource: 'resource://My.CoolPlugin/Public/Plugin/NeosUserInterface/Plugin.js'
# optional if youre using css
stylesheets:
'My.CoolPlugin':
resource: 'resource://My.CoolPlugin/Public/Plugin/NeosUserInterface/Plugin.css'
```

Now you can get started with your plugin.

By convention your `src/index.js` will import the manifest:
```js
import './manifest.js'
```

In the manifest `src/manifest.js` we will register our plugin with access to the globalRegistry:
```js
import manifest from '@neos-project/neos-ui-extensibility';

manifest('My.CoolPlugin', {}, (globalRegistry) => {
// ...
});
```

## Advanced concepts

If you're importing CSS files, they will be treated as CSS modules - to avoid any preprocessing, use `.vanilla-css` as a suffix.

We strongly suggest looking into creating your own build stack as described in [@neos-project/neos-ui-extensibility](https://github.com/neos/neos-ui/blob/8.3/packages/neos-ui-extensibility) as this gives you great leverage about your tooling.

## Documentation of the Neos UI extensibility API mechanics

For a deeper dive into concepts of Neos UI plugins, visit the [documentation](https://docs.neos.io/guide/manual/extending-the-user-interface/react-extensibility-api)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@neos-project/neos-ui-extensibility-webpack-adapter",
"version": "8.2.6",
"description": "Webpack extensibility mechanisms for the Neos CMS UI",
"description": "Zero configuration, highly opinionated Webpack extensibility mechanisms for the Neos Ui",
"repository": "neos/neos-ui",
"bugs": "https://github.com/neos/neos-ui/issues",
"homepage": "https://github.com/neos/neos-ui/blob/master/README.md",
Expand Down
200 changes: 200 additions & 0 deletions packages/neos-ui-extensibility/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
# @neos-project/neos-ui-extensibility

> Core of the extensibility mechanisms for the Neos UI

## Installation
```bash
yarn add @neos-project/neos-ui-extensibility
```

## Alternative
If you're here looking for the previously original shipped webpack build stack see [@neos-project/neos-ui-extensibility-webpack-adapter](https://github.com/neos/neos-ui/tree/8.3/packages/neos-ui-extensibility-webpack-adapter)

## Features

You don't need to recompile the Neos UI to integrate your own Plugins. Many core functionalities are accessible through the `@neos-project/neos-ui-extensibility` API.
This package provides the shims to access to the bespoken API and the alias map: `extensibilityMap.json` to be used for building a plugin.

All aliases are listed here: [@neos-project/neos-ui-extensibility/extensibilityMap.json](https://github.com/neos/neos-ui/blob/8.3/packages/neos-ui-extensibility/extensibilityMap.json).
You only need to import the modules, and they will work as if you installed those packages.
So `import React from "react"` will import react at runtime from the Neos UI host, and you don't need to install it. (Also the same instance is used, which is important)


## General usage and Concept

A Neos UI plugin must get access to certain important objects and methods like React, CKEditor, and also the bootstrap function.

**Concept**
To access the same instance f.x. of React that the Neos UI Host is using, we technically want to do something like: `const {React} = window.NeosUiPluginApi`. The problem being: when we use 3rd party NPM packages in our plugin, they will import React as usual `import React from "react"` which will fail.
To solve this issue and also make creating plugins a bit more fancy ✨ we make use of your bundlers import alias feature.
mhsdesign marked this conversation as resolved.
Show resolved Hide resolved

The alias resolution will match any imported path against the `extensibilityMap.json` and redirect it to a shim. The shim will then access the Neos UI plugin API at runtime.

**Using alias with esbuild webpack and co**

Technically, any bundler, which has support for alias, _should_ work.

- [esbuild](https://esbuild.github.io/api/#alias)
- [webpack](https://webpack.js.org/configuration/resolve/#resolvealias)
- [rollup](https://www.npmjs.com/package/@rollup/plugin-alias)

## Opinionated usage with esbuild / Technical Neos UI plugin setup

The following instructions will guide you to create a plugin with esbuild.
The plugin will be backwards compatible with Neos 7.3 too!

<details>
<summary>Advantages vs @neos-project/neos-ui-extensibility-webpack-adapter</summary>

```diff
+ Use Esbuild
- Cannot use Webpack
- Code splitting is more advanced in webpack
+ No need for Babel
+ Use latest ES Syntax
+ Fully controll the build process
+ Speeeeed
+ Way less dev dependencies -> faster installation.
```

</details>

Creating a basic UI plugin package:

You have free choice about the directory structure (except that the `"buildTargetDirectory"` must point to the `Resources/Public` folder)

<details>
<summary>Example File structure</summary>

```
- My.CoolPlugin
- Configuration
- Settings.yaml
- Resources
- Private
- NeosUserInterface
- src
- index.js
- manifest.js
- package.json

# created on build ...
- Public
- NeosUserInterface
- Plugin.js
- Plugin.js.map
```

</details>

We place the plugin in `Resources/Private/NeosUserInterface`:

`package.json`
```json
{
"name": "my-coolplugin",
"version": "1.0.0",
"scripts": {
"build": "node build.js",
"watch": "node build.js --watch"
},
"devDependencies": {
"@neos-project/neos-ui-extensibility": "~8.3.0",
"esbuild": "~0.17.18"
}
}
```

now we create our own build script:
`build.js`
```js
const esbuild = require('esbuild');
const extensibilityMap = require("@neos-project/neos-ui-extensibility/extensibilityMap.json");
const isWatch = process.argv.includes('--watch');

/** @type {import("esbuild").BuildOptions} */
const options = {
logLevel: "info",
bundle: true,
target: "es2020",
entryPoints: { "Plugin": "src/index.js" },
// add this loader mapping,
// in case youre "missusing" javascript files as typescript-react files
// - eg with `@neos` or `@connect` decorators
loader: { ".js": "tsx" },
outdir: "../../Public/NeosUserInterface",
alias: extensibilityMap
}

if (isWatch) {
esbuild.context(options).then((ctx) => ctx.watch())
} else {
esbuild.build(options)
}
```

In the folder `Resources/Public/NeosUserInterface` we will gather the build artifacts, which can be created by running `yarn build`.

The build stack will create `Resources/Public/NeosUserInterface/Plugin.js` and also `Resources/Public/NeosUserInterface/Plugin.css`, if you imported any CSS¹.

To include these files in the Neos UI, you need to register your plugin in the YAML configuration:

`Settings.yaml`
```yaml
Neos:
Neos:
Ui:
resources:
javascript:
'My.CoolPlugin':
resource: 'resource://My.CoolPlugin/Public/Plugin/NeosUserInterface/Plugin.js'
# esm support²
# in case you want to use esbuild's code splitting (ESM only)
# or just reference an ESM Plugin, set the type to module
# attributes:
# type: module

# optional if youre using css
stylesheets:
'My.CoolPlugin':
resource: 'resource://My.CoolPlugin/Public/Plugin/NeosUserInterface/Plugin.css'
```

Now you can get started with your plugin.

By convention your `src/index.js` will import the manifest:
```js
import './manifest.js'
```

In the manifest `src/manifest.js` we will register our plugin with access to the `globalRegistry`:
```js
import manifest from '@neos-project/neos-ui-extensibility';

manifest('My.CoolPlugin', {}, (globalRegistry) => {
// ...
});
```

### ¹CSS handling in esbuild

In case you're writing a new plugin and want to use CSS-Modules, or want to migrate a plugin from the webpack-adapter to esbuild, then we recommend using this css-modules loader for esbuild:
[esbuild-plugin-lightningcss-modules](https://github.com/mhsdesign/esbuild-plugin-lightningcss-modules). The loader is the same used for building the Neos UI and thus provides the same features. Be aware, though, that by default only `.module.css` files are processed instead of all `.css` files, but it's recommended to quickly rename those.

### ²ESM plugin (ecmascript module in the browser)

In case you want to leverage for example esbuild's [code splitting](https://esbuild.github.io/api/#splitting) - which requires using `format: "esm"` you need to load the plugin as module `<src type=module`.
This is achievable via the attributes map:

```
resources:
javascript:
'My.CoolPlugin':
resource: '...'
attributes:
type: module
```

## Documentation of the Neos UI extensibility api mechanics

For a deeper dive into the concepts of Neos UI plugins, visit the [documentation](https://docs.neos.io/guide/manual/extending-the-user-interface/react-extensibility-api)
2 changes: 1 addition & 1 deletion packages/neos-ui-extensibility/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@neos-project/neos-ui-extensibility",
"version": "8.2.9",
"description": "Code only extensibility mechanisms for the Neos CMS UI",
"description": "Core of the extensibility mechanisms for the Neos Ui",
"repository": "neos/neos-ui",
"bugs": "https://github.com/neos/neos-ui/issues",
"homepage": "https://github.com/neos/neos-ui/blob/master/README.md",
Expand Down