Difference between revisions of "User:Saul/Realtime app"

From Organic Design wiki
(File Structure: Added more info on this section.)
m (Manual: Inserted link)
Line 88: Line 88:
 
</source>
 
</source>
 
=== Manual ===
 
=== Manual ===
This section does the same thing manually as LINK HERE.<br>
+
This section does the same thing manually as [[User:Saul/Realtime_app#Auto|Auto]] does.<br>
 
<br>
 
<br>
 
First create the src/store/index.js file like this:
 
First create the src/store/index.js file like this:

Revision as of 23:18, 19 March 2018

This is the documentation for the stack I use for creating a real-time application. The stack consists of node.js and feathers.js for the server, the client uses: Vue, vue-router, vuex and setup using the vue webpack.

Setup

Install And Generate Files

The following commands will setup the app:

sudo npm install -g vue @feathersjs/cli # install dependencies globally
sudo vue init webpack-simple APPNAME # create a new project using the "webpack-simple" template
mkdir APPNAME/server && cd APPNAME/server
feathers generate app # generate the feathers app

Modify Files

A few changes are need to finish connecting the app:

Copy all dependencies from server/package.json to the package.json located in the root dir. Do the same for request and request-promise from devDependencies.

Add to the scripts section in package.json (this allows the back end to be started via "npm run server"):

"server": "node server/src/",

Add to package.json:

"directories": {
	"lib": "server/src"
},

Modify the dev script in package.json to:

"cross-env NODE_ENV=development webpack-dev-server --content-base server/public --open --hot"

Modify the config/default.json file like so:

"public": "../server/public/",

Modify the webpack.config.js by changing the path and publicPath like so:

path: path.resolve(__dirname, "server", "public"),
publicPath: "/",

Modify the index.html so that the script build source is:

<script src="build.js"></script>

Fix Structure, Install, And Cleanup

These commands will finish arranging the files (make sure you are still in the server dir):

mv config ../config && mv .editorconfig ../.editorconfig && mv ../index.html public/index.html # move then files to the proper dirs
rm package.json LICENSE .gitignore .npmignore README.md .eslintrc.json package-lock.json -R test node_modules # delete the unnecessary files

And to install the dependencies and run:

cd .. # go back to the project root
npm i @feathersjs/client vuex vue-router # install additional dependencies (socket.io-client may also be needed?)
npm i # install dependencies

Run App

To run in development:

npm run dev # this launches the front-end
npm run server # this launches the back-end

To run in production:

npm build # build the front-end into the backend
npm run server # run the backend

See Also

Client

File Structure

To generate the recommended file structure, navigate to the project root directory and run the following command:

mkdir src/components src/store src/libs src/pages # generate the client end folders: components (for storing vue components), store (for storing vuex store files), and libs (for storing client side js libs)

Auto

To automatically edit the files run this one-liner or skip to manual if you would like to manually edit them. The code does the following:

  • generates the src/store/index.js file with an example included.
  • generates the src/router.js file with examples
  • rewrites App.vue to use the vue-router
  • rewrites main.js to use the vue-router and vuex
echo -e "import Vue from \"vue\"\nimport Vuex from \"vuex\"\n//import chat from \"./SOTRENAMEONE\"\n//import login from \"./SOTRENAMETWO\"\n\nVue.use(Vuex)\n\nexport default new Vuex.Store({\n\tmodules: {\n\t\t/*\n\t\t\tchat,\n\t\t\tlogin\n\t\t*/\n\t}\n})" > src/store/index.js && echo -e "import Vue from \"vue\"\nimport Router from \"vue-router\"\n//import Login from \"./pages/Login.vue\"\n//import Register from \"./pages/Register.vue\"\n//import Chat from \"./pages/Chat.vue\"\n//import auth from \"./libs/auth\"\n\nVue.use(Router)\n\nconst router = new Router({\n\tmode: \"history\",\n\troutes: [\n\t\t/*\n\t\t\t{\n\t\t\t\tpath: \"/\",\n\t\t\t\tname: \"Chat\",\n\t\t\t\tcomponent: Chat,\n\t\t\t\tbeforeEnter: auth.isLoggedIn\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/login\",\n\t\t\t\tname: \"Login\",\n\t\t\t\tcomponent: Login\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/register\",\n\t\t\t\tname: \"Register\",\n\t\t\t\tcomponent: Register\n\t\t\t},\n\t\t*/\n\t\t// If access a non-existing route, redirect to root route\n\t\t{\n\t\t\tpath: \"*\",\n\t\t\tredirect: \"/\"\n\t\t}\n\t]\n})\n\nrouter.afterEach(function (to, from){\n\t//Set the title for the pages\n\tdocument.title = to.name;\n});\n\nexport default router;" > src/router.js && echo -e "<template>\n\t<div id=\"app\">\n\t\t<router-view></router-view>\n\t</div>\n</template>\n\n<script>\n\texport default {\n\t\tname: \"app\"\n\t}\n</script>\n\n<style>\n\t#app, body, html{\n\t\tbox-sizing: border-box;\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n</style>" > src/App.vue && echo -e "import Vue from \"vue\"\nimport App from \"./App.vue\"\nimport router from \"./router\"\nimport store from \"./store\"\n\nnew Vue({\n\tel: \"#app\",\n\tstore,\n\trouter,\n\trender: h => h(App)\n})" > src/main.js

Manual

This section does the same thing manually as Auto does.

First create the src/store/index.js file like this:

import Vue from "vue"
import Vuex from "vuex"
//import chat from "./SOTRENAMEONE"
//import login from "./SOTRENAMETWO"

Vue.use(Vuex)

export default new Vuex.Store({
	modules: {
		/*
			chat,
			login
		*/
	}
})

Then create the src/router.js file with the following:

import Vue from "vue"
import Router from "vue-router"
//import Login from "./pages/Login.vue"
//import Register from "./pages/Register.vue"
//import Chat from "./pages/Chat.vue"
//import auth from "./libs/auth"

Vue.use(Router)

const router = new Router({
	mode: "history",
	routes: [
		/*
			{
				path: "/",
				name: "Chat",
				component: Chat,
				beforeEnter: auth.isLoggedIn
			},
			{
				path: "/login",
				name: "Login",
				component: Login
			},
			{
				path: "/register",
				name: "Register",
				component: Register
			},
		*/
		// If access a non-existing route, redirect to root route
		{
			path: "*",
			redirect: "/"
		}
	]
})

router.afterEach(function (to, from){
	//Set the title for the pages
	document.title = to.name;
});

export default router;

Then change the contents of App.vue like so:

<template>
	<div id="app">
		<router-view></router-view>
	</div>
</template>

<script>
	export default {
		name: "app"
	}
</script>

<style>
	#app, body, html{
		box-sizing: border-box;
		padding: 0px;
		margin: 0px;
	}
</style>

Finally change the contents main.js to use the vue-router and vuex like this:

import Vue from "vue"
import App from "./App.vue"
import router from "./router"
import store from "./store"

new Vue({
	el: "#app",
	store,
	router,
	render: h => h(App)
})

Creating Pages

For every page you would like to make create a file in src/pages/PAGENAME.vue and then add it in the src/router.js file.
Each page should have the standard vue template:

<template>
</template>

<script>
</script>

<style>
</style>

Creating Components

Components are independent pieces of code to be embedded into a page.
For every component you would like to make create a file in src/component/COMPONENTNAME.vue
Each component should have the standard vue template (like pages do).
To embed the components in a page you need to import them in the page (in the script section):

import Chat from './components/chat.vue'
import Channels from './components/channels.vue'

export default{
	components: {
		Channels,
		Chat
	}
}

Then you can use them in the template section like so:

<channels></channels>
<chat></chat>

Creating Vuex Stores

Vuex stores are ways of preserving state.
To create a vuex store for your application create the folder src/store/STORENAME
Create a index.js file in the src/store/STORENAME folder. The index.js file should contain something like:

export const state = {
	// This should contain variables that you would like to preserve
}

export const mutations = {
	// This should contain methods for modifying the state section but should not be called directly
}

export const actions = {
	// This should contain methods that do not modify the state directly
	// They may however modify the stat by calling a method in the mutations
	// This may be done via: commit("mutation_name", channel)
}

export const getters = {
	// This should contain methods for retrieving the data from the state
}

export default {
  state,
  mutations,
  actions,
  getters
}

Then you need to modify the src/store/index.js to reference it.
Then you can import it into your pages and use the data.

Using JS Librarys

To add a JS library just create the file src/libs/LIBNAME.js
Add the code into that file and import it into the relevant files.