Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/tatsuukraine/vue-ssr-example

Ready for use Example for Vue + Vuex + TS + SSR + Jest
https://github.com/tatsuukraine/vue-ssr-example

hot-reload javascript jest js server-side-rendering ssr typescript vue vue-router vue-ssr vue-vuex vuejs vuex

Last synced: about 1 month ago
JSON representation

Ready for use Example for Vue + Vuex + TS + SSR + Jest

Awesome Lists containing this project

README

        

# Ready for use Example for Vue + Vuex + TS + SSR + Jest

Inspired by [Vue SSR](https://ssr.vuejs.org/en) and [Evan You example](https://github.com/vuejs/vue-hackernews-2.0)

## API

This project uses [JSON API](http://jsonapiplayground.reyesoft.com/) playground that was made according to [JSON API Spec](http://jsonapi.org/)
API layer is placed in **/src/api** folder (according to suggestions from Vuex doc)

API layer uses Axios (implementation is in **/src/service**) transport to make requests over HTTP

## Vuex

Store is split on modules in **/src/store**

## SSR (Server Side Rendering)

This project is configured with Webpack + Express.

```vue

export default {
waitAsyncData: false, //default: true

asyncData () {
return new Promise((res, rej) => res())
}
}

```

During server rendering, App will find matching Components by requested URL that has asyncData method.

### Highly resomended
Make API requests to fetch data, that will be used in child components or layouts,
in `asyncData` - to prepare all needed data, that you are going to use. It will prevent you
from problems when SSR rendered page and Client rendered page will be contains different result.

`asyncData` should return Promise, that should be resolved after fetched data are ready for rendering.

Server won't continue rendering until all asyncData will be resolved

For client build this method will be used on route change.

By default component won't be mounted (route won't be proceeded) until all asyncData methods
from all matched components will be resolved. As a result this will prevent user from navigation, until all data will
be loaded for new route

As an option it can be switched off, but only for Client app with help of **waitAsyncData** flag.

If **waitAsyncData** will be **FALSE** asyncData won't block app from navigation. It still will
stop rendering until Promise will be resolved.

## .ENV

You can modify environment variables, that will be exported in
`process.env`.

Default file `.env` should be placed in root folder. If needed path can be changed
in `/build/env-loader.js`

Variables in default file can be changed with `.env.{environent}`, where
`environment` defines based on NODE_ENV. For example,
if NODE_ENV='development' builder will try to load `.env.development`
after `.env` file

Properties `VUE_ENV` and `NODE_ENV` in `.env` files will be ignored

Also you can create files with `.local` postfix (`.env.local`, `.env.{environent}.local`). Such files will be loaded last.
They are added to GitIgnore so you can use them as local config files

Alongside with custom variables in .env file you can also specify
variables for server build. Default server target is **localhost:8080**
even, if variables in `.env` files wasn't defined

```
PORT=8080
HOST=localhost
```

Default `process.env` object that will be available in you app after build

```typescript
NODE_ENV: 'development'
VUE_ENV: 'client' // or 'server'
```

## TypeScript

In this example you can use ES6 style in `*.vue` alongside
with `*.ts` imports. TS support was configured to prevent using regular
`*.js` files inside TS files (you still can import `.vue` components inside TS files).
But it can be changed easily in `tsconfig.json`
file. In same time `*.ts` files can be imported anywhere (JS or Vue file)

Vue components doesn't use TS since it's overcomplicated in my opinion.
But it can be changed if needed just with [Vue Class Component](https://github.com/vuejs/vue-class-component) package

## Jest

This example uses Jest for testing. In general it was used, just to get full stack example of project)
Test files are placed in `/test` folder. You can run tests with

``` bash
npm run test
```

This test example was built based on `@vue/cli`

## SEO (page headers)

If you're using SSR then you probably need it for SEO. Question is - how to manage page headers (title, meta and etc.)

For this purpose you can use mixin `DocumentHeaderMixin`. It's a raw example, probably you will want to use
other packages that Vue

```vue

import {DocumentHeaderMixin} from "@/mixin"

export default {
metaInfo: {
title: 'BookTitle',
},
mixins: [DocumentHeaderMixin.getProperties()]
}

```

or with using `mapMixins`

```vue

import {DocumentHeaderMixin} from "@/mixin"
import {mapMixins} from "@/util"

export default {
metaInfo: {
title: 'BookTitle',
},
mixins: mapMixins(
DocumentHeaderMixin
)
}

```

Based on `VUE_ENV` will be exported or `ClientDocumentHeaderMixin` or `SSRDocumentHeaderMixin`

Preferable to use this mixin on Component that attached to route in router config, to prevent
misunderstanding with Head info set. Depends on build (server or client) there is a different approach how to manage
head information. During SSR render each component will have `$ssrContext` property,
which can be used to set up variables in `index.template.html` during server render.

For Client build - you can operate with DOM itself

## Build setup

**Requires Node.js 7+**

``` bash
# install dependencies
npm install # or yarn

# serve in dev mode, with hot reload at localhost:8080
npm run dev

# build for production
npm run build

# serve in production mode
npm start

# run tests
npm run test
```

## License

MIT