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

webui: demonstrate building a standalone page based on Vue.js implementation #2172

Closed
mr-tz opened this issue Jun 26, 2024 · 3 comments
Closed
Assignees
Labels
gsoc Work related to Google Summer of Code project. webui related to capa results web visualization

Comments

@mr-tz
Copy link
Collaborator

mr-tz commented Jun 26, 2024

Let's show how easy/hard it is to build a standalone offline webpage to display capa results.

@mr-tz mr-tz added gsoc Work related to Google Summer of Code project. webui related to capa results web visualization labels Jun 26, 2024
@s-ff
Copy link
Collaborator

s-ff commented Jun 27, 2024

To start off, we need to first create a Vue application named capa-webui, we will use vite as a build tool for this purpose.

$ npm create vite@latest capa-webui -- --template vue

Note: we can use any package manager: npm, yarn, pnpm, ... etc.

This will create a template Hello World web application, next we need to install our library of choice PrimeVue and its peer dependencies:

$ cd capa-webui
$ npm install
$ npm install primevue primeicons

The entry point of the application is found in src/App.vue, this is where the core HTML templates and Javascript live. To build the project, simply:

$ npm run build       # or npm run dev, to spin a local developement server

When the build is done, a ./dist folder is created which contains the source to be deployed on Github Pages.

We can ship this dist folder as part of capa releases, and users would simply need to spin a server to use the application offline.

However, if we want to create a seperate release, for users who want to use capa offline without having to spin local server we need to add a plugin for this purpose (we cannot simply download the./dist release and browse to file:///path/to/index.html because of CORS error, see explanation here)

To solve this, we need to use vite-plugin-singlefile: it is a plugin to create a standalone dist/index.html - that bundles the entire JS/CSS/HTML - into a signle file. See documentation.

$ npm install vite-plugin-singlefile --save-dev       # install the plugin

The ./dist file will now contain a single index.html that can be used a standalone page. I have pre-built a sample that you can test run here.

Note: the resulting file is not meant to be edited manually. You should edit src/App.vue, then compile (npm run build) to generate a new dist/index.html release.

@mr-tz
Copy link
Collaborator Author

mr-tz commented Jun 27, 2024

Neat, thanks for the details and documentation. The resulting standalone HTML looks good and is exactly what I had in mind.
Should we continue to automate the build steps you've documented here via GitHub Actions?

As next step, I'd suggest to either:

  1. automate the build via GH Actions Research and briefly document deployment of github.io page #2088
  2. move all previous functionality to use Vue.js Implement existing capa explorer webui using Vue.js #2179

@s-ff
Copy link
Collaborator

s-ff commented Jul 9, 2024

Building a standalone index.html using Github workflows

In a vite-based project, we specify how we'd like to build the web app using the vite.config.js file.

The default template of vite.config.js used by npm run build is:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  base: '/capa-webui',
  plugins: [vue()]
})

However, for our use case, we'd like to add a conditional build step to use a the vite-plugin-singlefile plugin to build the app as a standalone offline app. To achieve this, we need to adjust vite.config.js as follows:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { viteSingleFile } from 'vite-plugin-singlefile'

export default defineConfig(({ command, mode }) => {
  const isBundle = mode === 'bundle'

  return {
    base: isBundle ? '/' : '/capa-webui',
    plugins: isBundle ? [vue(), viteSingleFile()] : [vue()]
  }
})

Here, we introuce a new step which will be used to decide if this a normal build (i.e. npm run build) or a bundle build (i.e. npm run build:bundle)

Finally we need add the new build step in our package.json:

{
  "scripts": {
    "build": "vite build",
    "build:bundle": "vite build --mode bundle",
  }
}
  • The build step npm run build will be used by the deploy workflow to deploy the dist folder to Github Pages.
  • The build step npm run build:bundle will be used by the create-release workflow to create dist/index.html release. (See example release here)

PS: @williballenthin I looked into monolith, but couldn't get it to work. Will investigate more. For now, this approach works.

@s-ff s-ff closed this as completed Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gsoc Work related to Google Summer of Code project. webui related to capa results web visualization
Projects
Status: Done
Development

No branches or pull requests

2 participants