Please use vue3-vite-vue-class-component for vue3 vite setup.
Vue-webpack-typescript project starterThis project is generated via vue-webpack-minimal and features:
yarn install --frozen-lockfile
. You can fall back to npm
if you still use it.nvm use
. In total you need yarn and nvmThis runs the development server w/o a linter on.
There're multiple things you can do with test:
The command bellow builds static files with coverage babel plugin information, creates a http server and runs cypress (e2e) tests located in the integrationFolder against that server in headless mode.
You can check reports in nyc
directory, including coverage information.
This command is useful during development. You can click and inspect in live mode in cypress, and just develop while your tests are being ran automatically on file save. I usually have cypress test on one display, IDE on another one, and browser on 3rd one. So I instantly see which changes my code introduces.
yarn start
won't work, cause of missing coverage info and some other polyfills and tweaks required.yarn run test:cypress:debug
To check the styleguide use:
Build for productions to static files:APP_TEST
- true
/false
, adds required code for testing to output files when set to True (istanbul coverage, XHR polyfill for cypress)APP_API_URL
- url e.g. https://jsonplaceholder.typicode.com
, public http API urlAPP_PUBLIC_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 than index.html
APP_VERSION
- string, e.g. build-v378
, some unique string which identifies your souce code. I usually pass git version or git tag to this variable in Continuous Integration.APP_FILE_MODE
- true
/false
, sets whether static files should be built for file mode (dragging index.html to browser) or not. By setting to true, this turns off history mode in browser and removes crossOriginLoading links..$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$.api
object. You should do http calls with $this.$api
. If you prefer redux style you can call http in vuex actions.window.APP_VERSION
will be exported to global scope.Set indentation to 2
2
4
for html, sass, js, ts in settings -> editor -> code style
<template> <div>#[[$END$]]#</div> </template> <script lang="ts"> import {Component, Prop, Vue, Watch, Ref} from "vue-property-decorator"; @Component export default class ${COMPONENT_NAME} extends Vue { } </script> <!-- eslint-disable --> <style lang="sass" scoped> </style>
Tslint is not used for files, since it's deprecated. Use eslint instead and disable tslint
To avoid mixing warnings from eslint and jetbrains, you can turn them off by default
Mark nyc
and dist
directories ex excluded. Mouse 2 on the directory in the project explorer tree -> mark directory as -> excluded
Typescript (or ts shortly) allows to write typesafe code:
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 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.
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 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 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) } }
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() {} }
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; }
This test library: allows to write
describe('console', () => { it('should print', () => { console.log('Hello world') }) })
Those are assertion libraries that adds bdd assertions:
expect([1, 2]).to.be.an('array').that.does.not.include(3);
This is mocking library that allows you to write:
const myAPI = { method: function () {} }; const spy = sinon.spy(); const mock = sinon.mock(myAPI); mock.expects("method").once().throws();
To to write tests in BDD-like:
expect(mySpy).to.have.been.calledWith("foo");
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.
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); });
entry: ['./src/user.ts']
. Since webpack can only handle .js
files, to let webpack know about everything else we should pass the code through a corresponding loader. Everything is imported in this files are being processed by section loaders
.APP_PUBLIC_PATH
and run yarn run buiild:prod
. This generates static files in ./dist
directory.Typescript is compiled via babel, this means that it doesn't have typechecks, this speeds up build a lot! But since we still want to take advantages of typechecks we run typescript compiler runs in a separate process, giving errors to stdout.
<template
in vue SFC.This project has support for continuous integration servers:
You don't need to have all of them. So I recommend leave only 1. I would pick github actions since it doesn't require any setup.
In order to setup continuous delivery via github:
mkdir /tmp/sshkey; ssh-keygen -t rsa -b 4096 -C "github actions" -f /tmp/sshkey/id_rsa
/tmp/sshkey/id_rsa.pub
to your server last line of file ~/.ssh/authorized_keys
where ~
is the home for ssh user to use ( I used http
)HOST
-ssh host (your domain)PORT
- ssh port (22)SSH_USER
- ssh user, if you used my setup it's http
ID_RSA
- what ssh-keygen has generated in step above to/tmp/sshkey/id_rsa
/etc/sudoers
withCmnd_Alias RESTART_TORNADO = /usr/bin/systemctl restart tornado
http ALL=(ALL) NOPASSWD: RESTART_TORNADO
How to ignore linting errors
/* istanbul ignore if */
guide// tslint:disable-next-line:variable-name
guide// eslint-disable-line no-prototype-builtins
guide// @ts-ignore: next-line
guide/* stylelint-disable-line */
guideRepo uses material desing icons (mdi). Check materialdesignicons.com. And node_modules/@mdi/font/scss/_variables.scss
directory, this vars are prefixed with mdi-
, like mdi-home
.
For example:
import VueRouter, {RawLocation, Route, RouteRecord} from "vue-router"; // Multiple imports with `VueRouter` that starts with an UpperCase letter import {globalLogger, jwtStorage} from "@/utils/singletons"; // multiple imports start with lowercase `globalLogger` import DemoPage from "@/components/pages/DemoPage.vue"; // single import with lowercase import HomePage from "@/components/pages/HomePage.vue"; // single import with lowercase but alphabetically next import {ROUTER_HISTORY_MODE} from "@/utils/consts"; // this is still a single import from a capital letter import {defaultModule} from "@/store/default"; // this is a single import with a lower letter
consts
, vue
, store
, router
, api
, so you can do things like store.dispatch('alertError', 'Hello')
directly from chrome dev consoleRetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4