owncloud / ocis

:atom_symbol: ownCloud Infinite Scale Stack
https://doc.owncloud.com/ocis/next/
Apache License 2.0
1.38k stars 181 forks source link

Raw list of steps for frontend extension dev with ocis #805

Closed kulmann closed 5 months ago

kulmann commented 3 years ago

Prerequisites: You have an ocis-extension defining at least one service with rpc requests in a .proto file. Goal: Your ocis-extension is now supposed to have a web UI, which can be hooked into ocis-web as a frontend extension and is able to communicate with the service(s) in your ocis-extension.

Note: All files referenced below can be copied over from ocis-hello:

Set up an empty Vue app as extension for ocis-web

  1. copy package.json, rollup.config.js, babel.config.js and .eslintrc.json
  2. adjust package.json and rollup.config.js to your project-name. This is mostly a search-and-replace from hello to your extension name.
  3. run yarn install
  4. create an empty Vue.js file ui/components/App.vue in your project. This is where your web ui lives - it will be rendered within the content area of ocis-web (just having the left sidebar and the topbar) when navigating to your extension. Looking at the same file in ocis-hello or other extensions will give you an idea of what you can do here.
  5. copy ui/app.js to your project. Again, you can just go through it and replace hello with your extension name. This file will be loaded by ocis-web and contains all the required information to make your extension available with it's own menu item and properly recognized in the ocis-web extension system. You can export a vuex-store module here if your extension works with it, but it's not required to do so.
  6. run yarn build. This will build your app and copy it to the assets folder of your extension.

TODO: store is mandatory for ocis-web extension system! needs to have a loadConfig action. TODO: include frontend drone steps for building JS assets

Result: You have an (empty) ocis-web extension that fulfils the requirements of ocis-web to be loaded as an external extension. Next step is to enable your ocis-extension to deliver the built assets.

Enable your ocis-extension to deliver the built assets

  1. your ocis-extension will not serve the generate .js bundle. Instead, we will use fileb0x to generate embeddable go assets from your .js bundle.
  2. from pkg/assets/, copy assets.go, option.go and embed.yml. Adapt import paths in assets.go and option.go to point to your extension instead of ocis-hello. Don't worry about the unresolved FS and CTX vars, they will be part of generated code later on.
  3. change the GENERATE target in your Makefile from GENERATE ?= $(PACKAGES) to GENERATE ?= $(PACKAGES) $(IMPORT)/pkg/assets
  4. run make generate. This will create the pkg/assets/embed.go file (which then also defines FS and CTX from step 1).
  5. for your ocis-extension to deliver the static assets that now live in your embed.go, you will need an http server in your ocis-extension. If you don't have one, yet, you can just copy pkg/server/http to your ocis-extension. The important part is, that the http server serves the assets with a Static middleware.
  6. compile your binary and run it (make build and then ./bin/<extension-name> server)
  7. Load your web ui in your ocis-web config file, by adding it like this: Within your top level "external_apps": [] variable inside your config.json, add a new entry:
    {
    "id": "<your-extension-name>",
    "path": "http://localhost:<your extension http port>/settings.js"
    }

Result: Your extension for ocis-web can be loaded in ocis-web (see configuration - insert docs link here). It is delivered by your ocis-extension.

More comfort with make watch

Note: this has not proven to be good DX. Needs a better solution, maybe with a webpack dev server.

  1. As your ocis-extension is serving compiled assets from a previously built javascript bundle, you need to follow these steps when you changed something in your Vue app and want to see it in the browser: a) run yarn build for an updated javascript bundle, b) run make clean generate build for having a new version of your ocis-extension available, including new compiled assets, c) start your ocis-extension, d) reload the page. In order to make this a little bit easier, we have a make watch target available for you. In order to set this up, follow these steps:
  2. copy the reflex.conf file from ocis-hello and adapt it to your extension name
  3. copy the watch target from the Makefile of ocis-hello into your Makefile
  4. run make watch

Result: Each time you save a file, your javascript app and go binary get recompiled and the new binary gets started. Note: Especially when saving files in your Vue code, this first builds your javascript app bundle and then recompiles the go binary, so it takes a few seconds until you can reload the page in ocis-web. Please wait with the page reload until you see the Starting server xyz log line.

Generate a javascript client for your API:

  1. set up generating micro-web and swagger definitions in Makefile
  2. set endpoint annotations in rpc request definitions in .proto files
  3. look at third_party folder. Depending on usages in .proto there are some .proto files that might need to be included and copied into your project
  4. run make protobuf - this will generate the files defined in step 1
  5. run mkdir -p ui/client/<your-extension-name> 6: run yarn generate-api - this will use the swagger.json file from step 1 to generate a javascript client (stored in ui/client//index.js)
  6. in pkg/server/http/server.go, register the routes of your generated micro-web handlers (look for Register<service-name>ServiceWeb in ocis-hello for how to do this)
  7. set up bearer token injection, so that your requests are authenticated.

Result: You will have a JavaScript client available at ui/client/<your-extension-name>/index.js. It is generated from your .proto file and provides functions for each endpoint you defined. Internally it uses AXIOS to make the respective requests. You can now start using it in your extension for ocis-web.

General advice for building your extension for ocis-web:

refs commented 3 years ago

@kulmann is it worth including this in the docs? Having this information on an issue I feel is not the most optimal solution

kulmann commented 3 years ago

@LukasHirt wanted to created documentation from it, together with Felix. This issue was just meant as a brain dump as input for them. Can be closed after the docs for extension development have been finished. @LukasHirt do we have an issue for the extension development docs, so that we can keep track of closing this one here?

LukasHirt commented 3 years ago

do we have an issue for the extension development docs, so that we can keep track of closing this one here?

Nope. Only the old outdated PR https://github.com/owncloud/ocis/pull/294

Not sure when I'll get to finishing it though.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 10 days if no further activity occurs. Thank you for your contributions.

kulmann commented 5 months ago

outdated