Awesome
Vue-class-component vite
Demo vue3-vite-vue-class-component.akoidan.com
Get started
-
Use specific node version specified in .nvmrc:
nvm use
-
Install package libraries with yarn package manager
yarn install --frozen-lockfile
-
Copy build configuration:
cp build/example.json build/local.json
. -
To start dev server use
yarn start
. The app should be available on http://localhost:8080 -
To lint and test use
yarn test
andyarn lint
. To fix eslint errors useyarn lint:es:fix
-
To start cypress test locally halt the vite devserver and run
yarn test
. -
For developing cypress test it's easier to the vite dev server
yarn start
and runyarn cypress open
. In this configuration filesbuild/local.json
andbuild/test.json
should be alike.
Configuring local system
Variables variables
BACKEND_ADDRESS
- Full url for the backend. E.g. https://localhost:8082IS_DEBUG
- turn on logging and other features that are helfull for debugPUBLIC_PATH
- string, e.g.https://s3.amazonaws.com/
, url for images/js/css/fonts instead of relative path like './main.js. Can be used if you're using CDN that's on a different domain thanindex.html
PORT
- e.g. 8080 only for dev server to serve a port. If you run cypress against vite dev server instead of servor PORT should be the same as inbuild/test.json
BASE_URL
used in cypress test to determine which site to open
Configuration files
- .eslintrc.json is a configuration for ts linting
- .stylelintrc is a configuration for sass linting
- cypress.config.ts is a configuration for cypress e2e testing
- package.json is a configuration for yarn (npm), since it doesn't have versions of sublibs they are stored in yarn.lock
- tsconfig.json is a configuration for typescript. While this files is used to build static files for FE, cypress/tsconfig is used to build files that would run test in cypress.
- tsconfig.eslint.json ts configuration used in eslint to ignore checks in node_modules types that are broken.
- vite.config.ts is vite configurations. tsconfig.node.json Is used for transpiling vite config, since it's in TS.
- patches directory is used by patch-package to fix issues in current version of libs atm (which is 09/2022)
- build/development.json configuration for build for development environment, same is for staging.json, production.json. If VITE_BUILD_ENV is not specified, build/local.json would be used.
Get familiar with stack
typescript
Typescript (or ts shortly) allows to write typesafe code:
const a: number = 3;
- To get started with ts I would recommend watching this 10 minutes video
- To get started with decorators I recommend this video
- For advanced learning I recommend checking what's new in every version of typescript. You may find a lot of interesting things.
vue
Vue allows to write SFC that would generate html to the page. Vue is only responsible for UI layer, this is not an MVC framework. The only thing that it does is creates <div></div>
codeblocks. Everything else is handled by libraries below .
vuex
Vuex is a state management pattern. It allows multiple vue components to have single model/data (source of truth). So if you have a user object like {age: 3, name: 'eric'}
it can be accessible in multiple places. This is redux/mobx analogue for React.
vueRouter
Vue router allows navigation across pages in vue, w/o sending get request to the server. And produces access to URL parameters. The examples of routes is here:
new VueRouter({
routes: [{
path: '/posts', // this is url address
component: PostsPage // this is vue component
}]
});
sass
Sass allows to write code that would be compiled into css
$font-stack: Helvetica, sans-serif
body
font: 100% $font-stack
a
display: block
vue-class-component
Vue class component allows to write vue component in class manner instead of object:
export default class App extends Vue {
// initial data
msg = 123
// use prop values for initial data
helloMsg = 'Hello, ' + this.propMessage
// lifecycle hook
mounted () {
this.greet()
}
// computed
get computedMsg () {
return 'computed ' + this.msg
}
// method
greet () {
alert('greeting: ' + this.msg)
}
}
vue-property-decorator
Since vue-class-component forces you to have decorators above the class like this:
@Component({
props: {
propMessage: String
}
})
export default class App extends Vue {}
the following construction can be used instead:
import { Vue, Component, Prop, Watch, Emit, Ref } from 'vue-property-decorator'
@Component
export class MyComp extends Vue {
@Ref
button: HTMLInputElement;
@Prop() readonly propA!: number;
@Watch('child')
onChildChanged(val: string, oldVal: string) { }
@Emit()
changedProps() {}
}
vuex-module-decorators.
This is a wrapper with static getters for vuex. Check store/users instead of writing vuex modules as a dict, for instance:
import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'
@Module
export default class UserState extends VuexModule {
count = 0
@Mutation
increment(delta: number) {
this.count += delta
}
// action 'decr' commits mutation 'increment' when done with return value as payload
@Action({ commit: 'increment' })
decr() {
return 5
}
}
State can be injected into the vue component this way:
class A extends Vue {
@UserState
public readonly count!: number;
}
vuetify
Vuetify provides sets of UI components with animations, colors and visually pleasant following Material Design specification. Instead of building lots of customization, you can just plug something like below and it will have all the neats.
<template>
<v-btn/>
</template>
lines-logger
This wrapper provides a single interface to console.log and displays the origin source file location:
logger.log('Hello world')(); // pay attention to () in the end.
cypress
A testing framework that allows running test-cases directly in chrome (alternative to Selenium, that runs it on server) That part you've already seen on mocha above can be appended with cypress assertions and helpers:
it("should contain 5 elements", (): void => {
cy.get("[data-cy=filtered-users-container]").children().should("have.length", 1);
});
Cypress policies are:
- We mock every 3rd party dependnency, including backend and images for every test
- Every single page (item imported to vue-router) should have at least one screenshot tests, one assertion for text it contains (e.g. cy.contains('home page'), one default action behaviour (e.g. login action resulting being logged in), if there are any and a few failed steps (e.g. incorrect password during login)
- Screenshot match library has the fixed resolution defined in the figma which is 1280x720. If you run cyress in development mode, set chrome zoom exactly to 100% and iframe window with the app should fit it wihout scale as well (another zoom is specified in the right top corner and it should be 1280x928 wihtout percentage symbol)
Development tips
How to ignore linting errors
- Exclude from coverage:
/* istanbul ignore if */
guide - ignore tslint error:
// tslint:disable-next-line:variable-name
guide - ignore eslint error:
// eslint-disable-line no-prototype-builtins
guide - ignore typescript error:
// @ts-ignore: next-line
guide - ignore stylelint error:
/* stylelint-disable-line */
guide
Debugging
- Take a look at vue.js devtools
- window has many useful objects like
consts
,vue
,store
,router
,api
, so you can do things likestore.dispatch('alertError', 'Hello')
directly from chrome dev console
Logging
Every vue component has injected .$logger
object, to log something to console use this.logger.log('Hello {}', {1:'world'})();
Note calling function again in the end. Logger is disabled for production. For more info visit lines-logger