Skip to content

Combining Hitchy with Vue v3

Prerequisites

First, a local installation of Node.js is required.

We suggest installing git and docker on your computer for best developer experience.

Create a Vue project

If you haven't created Vue project with Vite before, start with that now:

bash
npm create vue@latest myapp
npm create vue@latest myapp

This will ask questions about features and tools you like to use with your application named myapp before creating a new project in sub-folder myapp.

Enter project folder:

bash
cd myapp
cd myapp

Install its dependencies:

bash
npm install
npm install

Configure git integration

Edit file .gitignore for appending these lines:

data
server/public
server/config/local.js
data
server/public
server/config/local.js

Add Hitchy

Hitchy gets integrated with your Vue application's project. Its code is going to reside in sub-folder named server:

bash
mkdir server
mkdir server

Additional dependencies are required:

bash
npm install @hitchy/core @hitchy/plugin-static @hitchy/plugin-odem @hitchy/plugin-odem-rest
npm install -D @hitchy/plugin-proxy
npm install @hitchy/core @hitchy/plugin-static @hitchy/plugin-odem @hitchy/plugin-odem-rest
npm install -D @hitchy/plugin-proxy
  • @hitchy/core is the core of Hitchy capable of handling requests and processing routing tables.
  • @hitchy/plugin-static is extending Hitchy for statically exposing files in a local folder. It will be used in a production setup for serving files of your application as built by Vite.
  • @hitchy/plugin-proxy is another extension to Hitchy implementing a basic reverse proxy. It is used to expose Vite's development server instead of the built files during development.

Actually, the following plugins aren't required for Hitchy's integration. However, they are commonly useful in most applications:

  • @hitchy/plugin-odem is adding a simple ODM for managing data on server-side.
  • @hitchy/plugin-odem-rest is an addition to that ODM feature exposing all models over REST API without any extra line of code.

See the list of official plugins for additional options here.

Adjust the file package.json for adding scripts named start and start:dev in scripts section:

json
{
	...
	"scripts": {
		...
		"start": "hitchy --project=server --plugins=. --ip=0.0.0.0",
		"start:dev": "hitchy --project=server --plugins=. --ip=0.0.0.0 --development --debug"
	},
	...
}
{
	...
	"scripts": {
		...
		"start": "hitchy --project=server --plugins=. --ip=0.0.0.0",
		"start:dev": "hitchy --project=server --plugins=. --ip=0.0.0.0 --development --debug"
	},
	...
}

Wrap Vue in Hitchy

Eventually, Hitchy is meant to deliver output of Vue. This is mostly to enable a single interaction pattern between Vue-based frontend and Hitchy-based backend in development and production setup as well as to prevent CORS issues in development setup.

Development setup

When developing Vue applications, there is a local development server included with Vite presenting current state of your application as a live preview. For proper integration with Hitchy, its configuration must be adjusted. Make sure port numbers are fixed in file vite.config.js:

javascript
...
export default defineConfig( {
    ...
    server: {
        port: 8080,
        hmr: {
            port: 8080
        }
    },
} )
...
...
export default defineConfig( {
    ...
    server: {
        port: 8080,
        hmr: {
            port: 8080
        }
    },
} )
...

First definition makes sure the development server is operating on fixed port 8080 every time. Second one is enforcing to use that port for the websocket connection used to support HMR.

After that, Vite's development server is ready for start with

bash
npm run dev
npm run dev

During development, you must start this server in addition to Hitchy yourself.

Next, Hitchy must be configured accordingly. Create folder myapp/server/config. Then create a file named proxy.js in that folder with this content:

javascript
module.exports = function (options) {
	return {
		proxy: options.arguments.development ? [{
			prefix: "/",
			target: "http://127.0.0.1:8080/",
			filters: {
				response: {
					header( res, req ) {
						if ( req.path.endsWith( ".json" ) ) {
							// eslint-disable-next-line no-param-reassign
							res.headers["content-type"] = "application/javascript";
						}

						return res;
					}
				}
			},
		}] : [],
	};
};
module.exports = function (options) {
	return {
		proxy: options.arguments.development ? [{
			prefix: "/",
			target: "http://127.0.0.1:8080/",
			filters: {
				response: {
					header( res, req ) {
						if ( req.path.endsWith( ".json" ) ) {
							// eslint-disable-next-line no-param-reassign
							res.headers["content-type"] = "application/javascript";
						}

						return res;
					}
				}
			},
		}] : [],
	};
};

Remarks

This configuration file complies with a special pattern to configure server in different ways depending on argument --development provided on command line or not.

This is setting up reverse proxy plugin to forward all requests not matching any more specific route to the Vite development server configured above. In addition, it's using a filter to fix the lack of properly indicating content type in responses to requests for JSON documents as it causes browsers to reject the processing of those files otherwise.

Production Setup

In production setup, there are static files built with Vite, only. No extra server exists to expose them. THus, Hitchy is required to serve those files instead.

Create a file myapp/server/config/static.js containing

javascript
module.exports = function (options) {
	return {
		static: options.arguments.development ? [] : [{
			prefix: "/",
			folder: "public",
			fallback: "index.html"
		}],
	};
};
module.exports = function (options) {
	return {
		static: options.arguments.development ? [] : [{
			prefix: "/",
			folder: "public",
			fallback: "index.html"
		}],
	};
};

This causes Hitchy to statically expose all files in the folder myapp/server/public and deliver myapp/server/public/index.html whenever some actually requested file is missing.

Adjust Vite to put build output there by editing its configuration file myapp/vue.config.js. Make sure option build.outDir is set like this:

javascript
...
export default defineConfig( {
    ...
    build: {
        outDir: "server/public"
    }
} )
...
export default defineConfig( {
    ...
    build: {
        outDir: "server/public"
    }
} )

Test Your Setup

Development Setup

Invoke

bash
npm run dev
npm run dev

for starting Vite's development server and

bash
npm run start:dev
npm run start:dev

for starting Hitchy. Observe the latter script's output for picking URL to open in a browser. This should present home screen of Vue skeleton created before.

Manually open preview

Due to related script setup the presented URL might be http://0.0.0.0:3000. Clicking it won't work for the browser can't process 0.0.0.0 as a server's address.

In this case, replace 0.0.0.0 with 127.0.0.1 in presented URL and use that one in browser to open the application.

Production Setup

Build application files with

bash
npm run build
npm run build

On exit, build output files have been written to folder myapp/server/public.

This time, start Hitchy by invoking

bash
npm run start
npm run start

Just like in development setup, open URL presented after a few moments in your browser. It will display the same home screen of Vue as before.

Customize Hitchy

Use persistent data backend

In case you have opted to include Hitchy's ODM before, its data is maintained in runtime memory by default and thus gets lost on every restart of Hitchy backend. By configuring a different default adapter, that data can be saved persistently.

Create a file myapp/server/config/database.js with following content:

javascript
const Path = require( "path" );

module.exports = function() {
	return {
		database: {
			default: new this.runtime.services.OdemAdapterFile( {
				dataSource: Path.resolve( __dirname, "../../data" ),
			} ),
		},
	};
};
const Path = require( "path" );

module.exports = function() {
	return {
		database: {
			default: new this.runtime.services.OdemAdapterFile( {
				dataSource: Path.resolve( __dirname, "../../data" ),
			} ),
		},
	};
};

This is selecting another ODM backend shipped with ODM plugin itself for storing data in local file system. The configured folder will be myapp/data and that's why it has been listed in .gitignore file created earlier.

Production Use

Using this backend might be an option for production setup, as well.

  • You shouldn't use it if you expect a huge number of records and/or a lot of requests accessing them.

  • You can't use it on running single instance of your application in a cluster unless it has reliable and exclusive access on a particular filesystem at any point in time (like a network share or similar).

  • Eventually, you can't use it on running multiple instances of your application in a cluster even though all instances are accessing the same set of files.

Please refer to @hitchy/plugin-odem-etcd for using an etcd cluster instead of local files.