├── .eslintrc
├── config
├── config.local.js
└── config.default.js
├── test
├── fixtures
│ └── apps
│ │ └── view-vue-test
│ │ ├── package.json
│ │ ├── config
│ │ ├── config.default.js
│ │ ├── config.test.js
│ │ └── config.prod.js
│ │ ├── public
│ │ ├── static
│ │ │ └── img
│ │ │ │ └── loading.gif
│ │ └── vue-ssr-client-manifest.json
│ │ └── app
│ │ ├── view
│ │ ├── layout.html
│ │ ├── renderString.js
│ │ └── test.js
│ │ ├── router.js
│ │ ├── controller
│ │ └── view.js
│ │ └── mocks
│ │ └── article
│ │ └── list.js
├── view-vue.test.js
└── view-vue.cache.test.js
├── app.js
├── .gitignore
├── .eslintignore
├── History.md
├── .travis.yml
├── app
└── extend
│ └── application.js
├── lib
├── view.js
└── engine.js
├── .autod.conf.js
├── .github
└── PULL_REQUEST_TEMPLATE.md
├── LICENSE
├── package.json
└── README.md
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint-config-egg"
3 | }
4 |
--------------------------------------------------------------------------------
/config/config.local.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.vue = {
4 | cache: false,
5 | };
6 |
--------------------------------------------------------------------------------
/test/fixtures/apps/view-vue-test/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "view-vue-test",
3 | "version": "1.0.0"
4 | }
--------------------------------------------------------------------------------
/test/fixtures/apps/view-vue-test/config/config.default.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.keys = '123456';
4 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = app => {
4 | app.view.use('vue', require('./lib/view'));
5 | };
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | logs/
2 | npm-debug.log
3 | node_modules/
4 | coverage/
5 | .idea/
6 | .DS_Store
7 | *.swp
8 | logs
9 | run
10 | *.iml
11 | .github
12 | .vscode
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | test/fixtures/apps/view-vue-test/public
2 | test/fixtures/apps/view-vue-test/app/public
3 | test/fixtures/apps/view-vue-test/app/view
4 | coverage
5 |
--------------------------------------------------------------------------------
/test/fixtures/apps/view-vue-test/public/static/img/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eggjs/egg-view-vue/HEAD/test/fixtures/apps/view-vue-test/public/static/img/loading.gif
--------------------------------------------------------------------------------
/History.md:
--------------------------------------------------------------------------------
1 |
2 | 1.0.0 / 2017-06-44
3 | ==================
4 |
5 | * feat: disable cache on local & improve cov (#5)
6 | * feat: first version (#4)
7 | * feat: init project
8 |
--------------------------------------------------------------------------------
/test/fixtures/apps/view-vue-test/config/config.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.vue = {
4 | cache: {
5 | max: 1000,
6 | maxAge: 1000 * 3600 * 24 * 7,
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | node_js:
4 | - '6'
5 | - '7'
6 | - '8'
7 | install:
8 | - npm i npminstall && npminstall
9 | script:
10 | - npm run ci
11 | after_script:
12 | - npminstall codecov && codecov
--------------------------------------------------------------------------------
/app/extend/application.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const Engine = require('../../lib/engine');
4 | const VUE_ENGINE = Symbol('Application#vue');
5 |
6 | module.exports = {
7 |
8 | get vue() {
9 | if (!this[VUE_ENGINE]) {
10 | this[VUE_ENGINE] = new Engine(this);
11 | }
12 | return this[VUE_ENGINE];
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/test/fixtures/apps/view-vue-test/config/config.prod.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = () => {
4 | const config = {};
5 | const cacheObject = {};
6 | config.vue = {
7 | cache: {
8 | set(name, value) {
9 | cacheObject[name] = value;
10 | },
11 | get(name) {
12 | return cacheObject[name];
13 | },
14 | },
15 | };
16 |
17 | return config;
18 | };
19 |
--------------------------------------------------------------------------------
/lib/view.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | class View {
4 | constructor(ctx) {
5 | this.app = ctx.app;
6 | }
7 |
8 | render(name, locals, options) {
9 | return this.app.vue.renderBundle(name, { state: locals }, options || /* istanbul ignore next */ {});
10 | }
11 |
12 | renderString(tpl, locals) {
13 | return this.app.vue.renderString(tpl, locals);
14 | }
15 | }
16 |
17 | module.exports = View;
18 |
--------------------------------------------------------------------------------
/.autod.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | write: true,
5 | plugin: 'autod-egg',
6 | prefix: '^',
7 | exclude: [
8 | './test/fixtures',
9 | './docs',
10 | './coverage',
11 | ],
12 | devdep: [
13 | 'autod',
14 | 'autod-egg',
15 | 'egg-bin',
16 | 'egg-mock',
17 | 'eslint',
18 | 'eslint-config-egg'
19 | ],
20 | keep: [
21 | ],
22 | semver: [
23 | ]
24 | };
25 |
--------------------------------------------------------------------------------
/test/fixtures/apps/view-vue-test/app/view/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | vue server render error, client template
6 |
7 |
8 |
9 | vue server render error, client template
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/test/fixtures/apps/view-vue-test/app/view/renderString.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const Vue = require('vue');
3 | module.exports = new Vue({
4 | template: [
5 | '',
6 | '- {{item.name}}
',
7 | '
',
8 | ].join(''),
9 | data: {
10 | model: [
11 | {
12 | id: 1,
13 | first: true,
14 | name: 'sky',
15 | },
16 | {
17 | id: 2,
18 | first: false,
19 | name: 'carl',
20 | },
21 | ],
22 | },
23 | });
24 |
--------------------------------------------------------------------------------
/test/fixtures/apps/view-vue-test/app/router.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = app => {
4 | app.get('/', function* () {
5 | this.body = 'hi, ' + app.plugins.view.name;
6 | });
7 | app.get('/renderString', 'view.renderString');
8 | app.get('/renderStringError', 'view.renderStringError');
9 | app.get('/render', 'view.render');
10 | app.get('/renderError', 'view.renderError');
11 | app.get('/app/api/article/list', 'view.list');
12 | app.get('/app/api/article/:id', 'view.detail');
13 | app.get('/app(/.+)?', 'view.renderJSONBundle');
14 | };
15 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
10 |
11 | ##### Checklist
12 |
13 |
14 | - [ ] `npm test` passes
15 | - [ ] tests and/or benchmarks are included
16 | - [ ] documentation is changed or added
17 | - [ ] commit message follows commit guidelines
18 |
19 | ##### Affected core subsystem(s)
20 |
21 |
22 |
23 | ##### Description of change
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Alibaba Group Holding Limited and other contributors.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/config/config.default.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = () => {
4 | const config = {};
5 |
6 | config.view = {
7 | defaultViewEngine: 'vue',
8 | mapping: {
9 | '.js': 'vue',
10 | },
11 | };
12 |
13 | /**
14 | * vue view options
15 | * @property {Object|Boolean} [cache] support LRU cache or custom cache(implement set and get method)
16 | * - Boolean: default true, use LRU cache
17 | * - Object: support set LRU or custom cache(implement set and get method)
18 | * @property {Object} [renderOptions] @see https://ssr.vuejs.org/en/api.html#renderer-options
19 | * @example property [cache]
20 | * use default LRU cache:
21 | * cache: true
22 | * disable default LRU cache:
23 | * cache: false
24 | * use LRU cache and set LRU:
25 | * cache:{
26 | * max: 1000,
27 | * maxAge: 1000 * 3600 * 24 * 7,
28 | * }
29 | * custom cache(implement set and get method):
30 | * cache: {
31 | * get: (key, cb) => {
32 | * return ...;
33 | * },
34 | * set: (key, val) => {
35 | * ...
36 | * }
37 | * }
38 | *
39 | */
40 | config.vue = {
41 | cache: true,
42 | // renderOptions: {
43 | // template: ``,
44 | // ......
45 | // },
46 | };
47 |
48 | return config;
49 | };
50 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "egg-view-vue",
3 | "version": "1.0.0",
4 | "description": "egg view plugin for vue",
5 | "eggPlugin": {
6 | "name": "vue",
7 | "dependencies": [
8 | "view"
9 | ]
10 | },
11 | "keywords": [
12 | "egg",
13 | "eggPlugin",
14 | "egg-plugin",
15 | "egg-view",
16 | "vue",
17 | "ssr"
18 | ],
19 | "dependencies": {
20 | "lru-cache": "^4.1.1",
21 | "vue": "^2.3.4",
22 | "vue-server-renderer": "^2.3.4"
23 | },
24 | "devDependencies": {
25 | "autod": "^2.8.0",
26 | "autod-egg": "^1.0.0",
27 | "axios": "^0.16.2",
28 | "egg": "^1.4.0",
29 | "egg-bin": "^3.6.0",
30 | "egg-mock": "^3.7.2",
31 | "eslint": "^4.0.0",
32 | "eslint-config-egg": "^4.2.1",
33 | "vue-router": "^2.5.3",
34 | "vuex": "^2.3.1",
35 | "vuex-router-sync": "^4.2.0",
36 | "webstorm-disable-index": "^1.0.11"
37 | },
38 | "engines": {
39 | "node": ">=6.0.0"
40 | },
41 | "ci": {
42 | "version": "6, 7, 8"
43 | },
44 | "scripts": {
45 | "test": "npm run lint -- --fix && npm run test-local",
46 | "test-local": "egg-bin test",
47 | "cov": "egg-bin cov",
48 | "lint": "eslint .",
49 | "ci": "npm run lint && npm run cov",
50 | "autod": "autod"
51 | },
52 | "files": [
53 | "index.js",
54 | "app.js",
55 | "agent.js",
56 | "config",
57 | "app",
58 | "lib"
59 | ],
60 | "repository": {
61 | "type": "git",
62 | "url": "git+https://github.com/eggjs/egg-view-vue.git"
63 | },
64 | "bugs": {
65 | "url": "https://github.com/eggjs/egg/issues"
66 | },
67 | "homepage": "https://github.com/eggjs/egg-view-vue#readme",
68 | "author": "hubcarl@126.com",
69 | "license": "MIT"
70 | }
71 |
--------------------------------------------------------------------------------
/test/fixtures/apps/view-vue-test/app/controller/view.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const path = require('path');
3 | const Model = require('../mocks/article/list');
4 |
5 | exports.renderString = function* (ctx) {
6 | ctx.body = yield ctx.renderString('name:{{name}},desc:{{desc}}
', {
7 | name: 'egg-vue-view',
8 | desc: 'egg view plugin for vue',
9 | });
10 | };
11 |
12 | exports.renderStringError = function* (ctx) {
13 | try {
14 | ctx.body = yield ctx.renderString('name:{{user.name}},desc:{{user.desc}}
', {
15 | name: 'egg-vue-view',
16 | desc: 'egg view plugin for vue',
17 | });
18 | } catch (e) {
19 | ctx.status = 500;
20 | ctx.body = e.toString();
21 | }
22 | };
23 |
24 | exports.render = function* (ctx) {
25 | yield ctx.render('test.js', { message: 'egg-view-vue#vue server side render!' });
26 | };
27 |
28 | exports.renderJSONBundle = function* (ctx) {
29 | const manifest = path.join(ctx.app.baseDir, 'public/vue-ssr-client-manifest.json');
30 | const url = ctx.url.replace(/\/app/, '') || '/';
31 | yield ctx.render('vue-ssr-server-bundle.json', { url }, {
32 | renderOptions: {
33 | template: '',
34 | clientManifest: require(manifest),
35 | },
36 | });
37 | };
38 |
39 | exports.list = function* (ctx) {
40 | const pageIndex = ctx.query.pageIndex;
41 | const pageSize = ctx.query.pageSize;
42 | ctx.body = Model.getPage(pageIndex, pageSize);
43 | };
44 |
45 | exports.detail = function* (ctx) {
46 | const id = ctx.query.id;
47 | ctx.body = Model.getDetail(id);
48 | };
49 |
50 | exports.renderError = function* (ctx) {
51 | try {
52 | yield ctx.render('error.js', {
53 | data: {
54 | name: 'vue render',
55 | description: 'egg view plugin for swig',
56 | },
57 | });
58 | } catch (e) {
59 | ctx.status = 500;
60 | ctx.body = e.toString();
61 | }
62 | };
63 |
--------------------------------------------------------------------------------
/test/view-vue.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const assert = require('assert');
3 | const mm = require('egg-mock');
4 |
5 | describe('test/view-vue.test.js', () => {
6 |
7 | describe('default view engine', () => {
8 | let app;
9 | before(() => {
10 | app = mm.app({
11 | baseDir: 'apps/view-vue-test',
12 | });
13 | return app.ready();
14 | });
15 |
16 | after(() => app.close());
17 | afterEach(mm.restore);
18 |
19 | it('should GET /', () => {
20 | return app.httpRequest()
21 | .get('/')
22 | .expect('hi, view')
23 | .expect(200);
24 | });
25 |
26 | it('should GET /renderString', () => {
27 | return app.httpRequest()
28 | .get('/renderString')
29 | .expect('name:egg-vue-view,desc:egg view plugin for vue
')
30 | .expect(200);
31 | });
32 |
33 | it('should GET /renderString error', () => {
34 | return app.httpRequest()
35 | .get('/renderStringError')
36 | .expect(500);
37 | });
38 |
39 | it('should GET /render error', () => {
40 | return app.httpRequest()
41 | .get('/renderError')
42 | .expect(500);
43 | });
44 |
45 | it('should GET /render', () => {
46 | return app.httpRequest()
47 | .get('/render')
48 | .expect(200)
49 | .expect(res => {
50 | assert(res.text.includes('data-server-rendered="true"'));
51 | assert(res.text.includes('