User:Saul/Realtime app
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.
Contents
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.
Server
Services
To generate a feathers js service run:
feathers generate service # Creates the feathers.js service
# Example: Mongoose, channels, /channels, mongodb://localhost:27017/chat
To generate the authentication service run:
feathers generate authentication # Creates the feathers.js authentication service
If you have issues with a service check what the service name is.