mkungla / webxr-webpack-boilerplate

Starter Kit for building rich, immersive WebXR prototype projects (featuring A-Frame) PWA with Webpack and SASS
https://mkungla.github.io/webxr-webpack-boilerplate/
MIT License
54 stars 21 forks source link
aframe aframe-boilerplate aframe-vr aframevr aframexr boilerplate boilerplate-application pwa sass service-workers starter-kit webpack webpack-boilerplate webvr webxr webxr-boilerplate

WebXR Webpack Boilerplate

Starter Kit for building rich, immersive WebXR projects (featuring A-Frame) PWA with Webpack, Handlebars and SASS

Project License A-Frame Version

Introduction

The goal of WebXR Webpack Boilerplate is to provide a high-quality, high-performance code base to accelerate WebXR development and specially prototyping. It is designed to be flexible in order to support rapid implementation and customization within your project. — take a look at demo

Personally I use this boilerplate mostly for quick prototyping WebXR ideas,
while final product going to production may require major refactoring the code base.
@mkungla

Project build status

Linux macOS Windows
TravisCI Build Status CircleCI Build Status AppveyorCI Build Status

Grade Badge Coverage Badge Dependencies Dev Dependencies

Overview

Here is overview of WebXR Webpack Boilerplate project and what's included.

Custom A-Frame Theme

red blue green yellow
Theme red Theme blue Theme -green Theme yellow

You can change A-Frame themes by modifying ./app.json sassTheme property which sets SASS configuration $theme variable

// Color themes red !default, yellow, green, blue
{
    "sassTheme": "red"
}

if that property is not set then default theme is used in src/style/_theme-vars.scss

// Color themes red !default, yellow, green, blue
$theme: red !default;

Project structure

Project ./src contains some unnecessary files which are included for demo and example purposes. You can remove all of these files and associated references and imports from your project.


Getting Started

instructions to set up your project

Setup project based on this repository

Follow one of the 3 options below which suits best for your needs. Options below are shown for github.com public and private repositories, so if your project will be hosted elsewhere you know your self what you have to change.

Create fork to contribute back to this repository

(option 1)

First Fork this repository in github.com

Next navigate to directory where you keep your projects and set following temporary environment variables

cd <your-projects>
GITHUB_USERNAME="<github-username>"

Next clone full copy of this repository and set remotes to be able to sync your repository with upstream

git clone --origin github/"$GITHUB_USERNAME" git@github.com:$GITHUB_USERNAME/webxr-webpack-boilerplate.git
cd webxr-webpack-boilerplate
git remote add github/digaverse git@github.com:digaverse/webxr-webpack-boilerplate.git

and start hacking.

Create new project based on this repository and keep commit history

(option 2)

First navigate to directory you keep your projects and set following temporary environment variables

cd <your-projects>
GITHUB_USERNAME="<github-username>"
# PROJECT_NAME should be valid github repository name
PROJECT_NAME="<your-new-project-name>"

Next go and create new public or private repository under $GITHUB_USERNAME and set project name same as $PROJECT_NAME. While creating the repository make sure that no default files are created,

Next

git clone --bare git@github.com:digaverse/webxr-webpack-boilerplate.git
cd webxr-webpack-boilerplate.git
git push --mirror git@github.com:$GITHUB_USERNAME/$PROJECT_NAME.git
cd ..
rm -rf webxr-webpack-boilerplate.git
git clone --origin github/"$GITHUB_USERNAME" git@github.com:$GITHUB_USERNAME/$PROJECT_NAME.git

and start hacking.

Create new project based on this repository without commit history

(option 3)

First navigate to directory you keep your projects and set following temporary environment variables

cd <your-projects>
GITHUB_USERNAME="<github-username>"
# PROJECT_NAME should be valid github repository name
PROJECT_NAME="<your-new-project-name>"

Next go and create new public or private repository under $GITHUB_USERNAME and set project name same as $PROJECT_NAME. While creating the repository make sure that no default files are created,

git clone --depth=1 git@github.com:digaverse/webxr-webpack-boilerplate.git $PROJECT_NAME
cd "$PROJECT_NAME"
rm -rf .git
git init
git add -A && git commit -m"initial commit"
git remote add github/"$GITHUB_USERNAME" git@github.com:$GITHUB_USERNAME/$PROJECT_NAME.git
git push -u github/"$GITHUB_USERNAME" master

and start hacking.


Build and development server configuration

Most of build and configuration options can be set in ./app-dev.json, but if you need more control or customization look into config files in ./devel directory.


First run

make sure you have yarn installed, alternately you can use npm command instead yarn

# copy app-dev.json
cp example.app-dev.json app-dev.json
# copy  app.json
cp example.app.json app.json
# install and setup
yarn install
yarn run setup # first time run generates SSL certificates so we can serve https and http2 locally
yarn build # creates static assets under ./build directory

to start the dev server run

yarn start

You may need to update/rebuild static assets sometimes then just run yarn run build before yarn start.

And now open your browser https://localhost:9000 and accept self signed certificates.


Development

application configuration file is ./app.json all properties will be available within both in handlebars templates and PROJECT.{property} and in application/addon level this.session.get('config').{property} while most of webpack config is set in ./app-dev.json. Keep in mind when you edit these files you have to restart development server in order these changes to take effect.

Minimal example of app js

Here is minimal Example for ./src/js/app.js

/* global PROJECT */

import Application from './application/core'
// import application addons you want to register
// import yourAddon from './application/addons/your-addon'

const app = new Application(PROJECT)

// Reqister all application addons by calling registerAddon
// app.registerAddon(yourAddon, addonConfigObject)

// Start the application as soon as possible
app.start().then((log) => {
  log.debug('webapp is running callback')
}).catch((err) => {
  console.error(err)
})

Project is shipped with example adding controls to start/stop/play/pause application. NOTE that application start/stop/play/pause does not affect A-Frame scene. If you wich to do so then you have to set {"ppaframe": true} in ./app.json. Also when you have page which does not have A-Frame scene but in header template you load lib-aframe.js then application will not play since A-Frame core system is paused when <a-scene> is not found, so you may better create different header file wich you include in pages which do not have a A-Frame scene so that application falls back to using window.requestAnimationFrame.


Example Addon

Most of application logic is added to application by creating and registering Addons. bellow is outline of how to define your Addon.

/* ./application/addons/your-addon */
export default {
  name: 'your-addon',
  // this addon will not be reqistered if aframe is not present on loaded page
  // default false
  aframeRequired: true,
  // You can set configuration defaults to your Addon here
  // or set that object as second parameter when you register
  // your Addon by calling app.registerAddon()
  data: {},

  setup() {
    // Called once when you register the Addon
    // Sets the data to values passed to registerAddon 2 param

    // Within addon following properties are set
    //
    // this.aframeRequired  - is aframe required
​    // this.enabled         - is addon enabled
​    // this.isPlaying       - is addon playing
    // this.name            - addon given name
    // this.data            - addon configuration  
​    // this.app             - reference to app
    //   this.app.session   - access application session
    //   this.app.store     - app localStorage
    //   this.app.addons['addon-name'] - access other registered addons
    //     ``
    // this.log             - gives named logger for current addon.
    //      Displaying these messages depends on
    //      your ./app.json setting which logLevel is set
    //        this.log.debug(args...)
    //        this.log.info(args...)
    //        this.log.ok(args...)
    //        this.log.warn(args...)
    //        this.log.error(args...)
  },

  start() {
    // Called every time when you start the application
    // and everytime when you call application start after stoping it.
  },

  play() {
    // Called every time when application play is called
  },

  pause() {
    // Called every time when application pause is called
  },

  tick() {
    // Called in every render loop when application is playing
  },

  dispose() {
    // Called when application stop is called.
    // Currently dispose does not delete this Addon
    // so calling application start after stop will call
    // this objects .start again, but not .setup .
    // This behavior may change in this project skeleton
    // in the future allowing you to dispose Addons on
    // run time and re register Addons on demand.
    // Therefore the name dispose instead of stop
    // which it is right now by behavior.
  }
}

Add A-Frame components

yarn add <some-aframe-component>

add import statement to ./src/js/lib-aframe.js


Add 3rd party libraries

yarn add <some-library>

if needed add import statement to ./src/js/vendors.js if you want to bundle that dependency together with other 3rd party libraries or sass import statment to ./src/style/vendors/vendors-style.scss when adding 3rd party styles.


Build and deploy

Static app

To build static site just run

# (not required): do sign version git tags
yarn config set version-sign-git-tag true
# (not required): to remove "v" version-tag-prefix
yarn config set version-tag-prefix ""
# (not required): do update version
yarn version
# build everything into ./build directory
yarn build
# git push to remote
git push && git push --tags

Contents of ./build directory are ready to be served just copy contents of ./build directory to your webserver root. e.g. demo is hosted with github pages, take a look at gh-pages branch for example

Build and run Docker image

requires yarn build before

yarn run build:docker

and fire up your docker image

yarn run start:docker

And now open your browser https://localhost:8080