Vue rendering engine for Express.js. Use .Vue files as templates using streams

Overview

Version Build Status Dependency Status Codecov

express-vue

A Simple way of using Server Side rendered Vue.js 2.0+ natively in Express using streams

If you want to use vue.js and setup a large scale web application that is server side rendered, using Node+Express, but you want to use all the fantastic tools given to you by Vue.js. Then this is the library for you.

The idea is simple use Node+Express for your Controller and Models, and Vue.js for your Views.. you can have a secure server side rendered website without all the hassle. Your Controller will pass in the data to your View through

res.renderVue('view', {data}, [{vueOptions}]).

Table of Contents

Installation

$ npm install --save express-vue

Requirements

Requires Node V6 or greater, and Vue 2.0 or greater. (Latest Vue.js is included in this project)

ES Modules

If using ES module statments like

export default {}
//or
import foo from "foo";

Or any other ES features you will need to also install babel-core and babel-preset-env.

npm i -D babel-core babel-preset-env

Then place a .babelrc file in your root. here's an example targeting last two versions

{
  "presets": [
    ["env", {
      "targets": {
        "browsers": ["last 2 versions"]
      }
    }]
  ]
}

Example / Starter

An example / starter can be found here

Usage

This is the minimum required setup. If you don't provide a vueVersion it will use the latest one when the project was published. If there is no rootPath it will assume the root is the parent directory of node_modules.

{ //the rest of your express routes. }); ">
var expressVue = require("express-vue");
var app = express();

//pass your app through express-vue here
//expressVueOptions is optional and explained later in the docs
//this is a promise, so you can either await it or do this.
expressVue.use(app, expressVueOptions).then(() => {
    //the rest of your express routes.
});

In your route, assuming you have a main.vue

router.get('/', (req, res, next) => {
    const data: {
        otherData: 'Something Else'
    };
    req.vueOptions: {
        head: {
            title: 'Page Title',
            metas: [
                { property:'og:title', content: 'Page Title'},
                { name:'twitter:title', content: 'Page Title'},
            ]
        }
    }
    res.renderVue('main.vue', data, req.vueOptions);
})

To use Data binding into the vue files you need to pass data in through the data object as above. express-vue will automatically add anything you put here to the root element of your Vue components. You do not need to have anything in data in your .vue file, but if you did what you put in res.render will overwrite it.

Remember to always write your data objects in your .vue files as functions!

Options

key type description required? default value
rootPath string this is the path the library will use as the base for all lookups optional the directory that your ../node_modules lives in
vueVersion string or object this is where you specify which version of vue.js's library to use from the CDN optional the latest version as of publishing this
layout Object this is the object for customzing the html, body, and template tags optional has default value which is in the example below
vue Object this is the global config for vue for example you can set a global title, or a script tag in your head block everything here is global optional no default value
data Object this is the global data object, this will be merged in to your .vue file's data block on every route, you can override this per route. optional no default value

Here's an example, with the default layout config included for you to see...

const vueOptions = {
    rootPath: path.join(__dirname, '../example/views'),
    head: {
        title: 'Hello this is a global title',
        scripts: [
            { src: 'https://example.com/script.js' },
        ],
        styles: [
            { style: '/assets/rendered/style.css' }
        ]
    },
    data: {
        foo: true,
        bar: 'yes',
        qux: {
            id: 123,
            baz: 'anything you wish, you can have any kind of object in the data object, it will be global and on every route'
        }
    }
};
expressVue.use(app, vueOptions);

Components / Mixins / Etc

NOTE: Components and Mixins need to be OUTSIDE of the Pages Root folder.

When including components/mixins/etc the directory it looks is going to be relative to the file you're working in currently. assuming the below is running in a folder with a subdirectory components and a directory mixins in a parent, it would look like this. when importing .vue files and .js files from node modules you can just import them the normal way you import a module.

<script>
import messageComp from './components/message-comp.vue';
import users from './components/users.vue';
import exampleMixin from '../mixins/exampleMixin';
import externalComponent from 'foo/bar/external.vue';
export default {
    mixins: [exampleMixin],
    data: function () {
        return {
        }
    },
    components: {
        messageComp,
        users,
        externalComponent
    }
}
script>

CSS inside components/views

Please use regular CSS for now, SCSS/LESS/etc are compiled languages, and this is a runtime library for now. In the future I will be creating build tools to handle compiling the .vue files into .js files so that it runs faster, and more efficient at runtime. But for dev mode, it will compile everything at runtime, so you can edit and preview faster.

<style>
    .test {
        border: 2px;
    }
    .test a {
        color: #FFF;
    }
style>

Mixins

You can now use Mixins, lets say you have an file called exampleMixin.js and it looks like this:

examplemixin.js

module.exports {
    methods: {
        hello: function () {
            console.log('Hello');
        }
    }
}

In your route you would declare it by placing mixins: [exampleMixin] in your vue object.

<script>
import exampleMixin from '../mixins/exampleMixin';
export default {
    mixins: [exampleMixin],
    data: function () {
        return {
        }
    }
}
script>

You can now use this in your .Vue file, like so

Click me and look at console logs ">
<button @click="hello()">Click me and look at console logsbutton>

Meta

This library takes the wonderful inspiration from vue-head and adapts it to work here. Just add a meta array into your head object, with support for both content and property types. (Note we don't support shorthand here, and no support for google+ just yet, that will come soon).

const vueOptions = {
    head: {
        title: 'It will be a pleasure',
        // Meta tags
        metas: [
            { name: 'application-name', content: 'Name of my application' },
            { name: 'description', content: 'A description of the page', id: 'desc' } // id to replace intead of create element
            // ...
            // Twitter
            { name: 'twitter:title', content: 'Content Title' },
            // ...
            // Facebook / Open Graph
            { property: 'fb:app_id', content: '123456789' },
            { property: 'og:title', content: 'Content Title' },
            // ...
            // Rel
            { rel: 'icon', type: 'image/png', href: '/assets/favicons/favicon-32x32.png', sizes: '32x32' }
            // Generic rel for things like icons and stuff
        ],
        // Scripts
        scripts:[
            { src: '/assets/scripts/hammer.min.js' },
            { src: '/assets/scripts/vue-touch.min.js', charset: 'utf-8' },
            // Note with Scripts [charset] is optional defaults to utf-8
            // ...
        ],
        // Styles
        styles: [
            { style: '/assets/rendered/style.css' }
            { style: '/assets/rendered/style.css', type: 'text/css' }
            // Note with Styles, [type] is optional...
            // ...
        ],
    }
}
expressVue.use(app, vueOptions);

Structured Data

This also supports Google Structured data https://developers.google.com/search/docs/guides/intro-structured-data

const vueOptions = {
    head: {
        title: 'It will be a pleasure',
        structuredData: {
            "@context": "http://schema.org",
            "@type": "Organization",
            "url": "http://www.your-company-site.com",
            "contactPoint": [{
                "@type": "ContactPoint",
                "telephone": "+1-401-555-1212",
                "contactType": "customer service"
            }]
        }
    }
}

Template

If you want to have a custom layout you can, here is the default layout, each part is overridable.

', end: '
' } } //... }; expressVue.use(app, vueOptions); ">
const vueOptions = {
    //...
    template: {
        html: {
            start: '',
            end: ''
        },
        body: {
            start: '',
            end: ''
        }
        template: {
            start: '
  
', end: '
'
} } //... }; expressVue.use(app, vueOptions);

DevTools

To use the amazing Vue.js DevTools please set the environment variable VUE_DEV=truethis will also trigger the development version of vue to be included in the head.

Caching

Caching is now enabled by default, in dev mode hopefuly you're using something like nodemon/gulp/grunt etc, which restarts the server on file change.. otherwise you will need to stop and restart the server if you change your files.. which is normal.

Typescript support

Typescript declarations are published on NPM, so you don’t need external tools like Typings, as declarations are automatically imported with express-vue. That means all you need is a simple:

import expressVue = require('express-vue');

Sailsjs Support

This is middleware now so support for sails should just work as middleware.

Migration to Webpack Renderer

  • change rootPath to pagesPath
  • remove vueVersion
  • install webpack vue-loader and css-loader
  • remove .babelrc if you have one
  • if you're using regular babel packages switch to the @babel versions @babel/core @babel/preset-env @babel/preset-es2015
  • remove vuejs
  • move your expressVue options into a file on the root of your directory (same level as node_modules) and call it expressvue.config.js
  • Use the new init syntax expressVue.use(expressApp); this is a async function, so please either await it or use it in a promise.

V5 Migration

  • Ditched the custom parser/renderer and moved to using vue-pronto which uses Vueify
  • Re-structured the vueOptions
  • Added req.vueOptions as a global.
  • Removed the vue parent object with the child of head, this was un-needed its now just vueOptions.head instead of vueOptions.vue.head
  • When using res.renderVue the filename requires an extention now.
  • Paths are now RELATIVE to the file you're currently in ... YAAAY
  • Node Modules are supported, for both javascript and vue file imports inside .vue files ... YAAAY
  • Massive Performance gains
  • 100% compatability with vueJS
  • Migration to Vue-Pronto

Express-vue-renderer got too heavy, the architecture became too messy, and it was slow. It needed to get thrown out. Enter vue-pronto it uses vueify under the hood, and is much more modular. this will be much easier going forward to maintain.

Changes to the Vue Options Object

There's been some big changes to this object, so before it would look like this

const vueOptions = {
    vue: {
        head: {
            meta: [
                { script: 'https://unpkg.com/[email protected]/dist/vue.js'},
                { name: 'application-name', content: 'Name of my application' },
                { name: 'description', content: 'A description of the page', id: 'desc' },
                { style: '/assets/style.css' }
            ]
        }
    }
};

Now its different ..

  • We have automated getting vueJS from the CDN for you, and which version (dev/prod) it should use based on the environment variable VUE_DEV.
  • We also broke up the meta object, into metas, scripts, and styles arrays. scripts now have scriptSrc which is a string including the
Comments
  • Plugins

    Plugins

    is there a way to import or config libs/scripts like Vue.use(. . .) or Vue.prototype. . . for all pages ? in doc examples or in vue-cli it sets up in main.js before new Vue(. . .)

    opened by 0wlcat 37
  • SyntaxError: Unexpected token <

    SyntaxError: Unexpected token <

    Description of Issue

    Error when I try to import a component in another component

    Stack Trace / Console Log

    /home/samuel/Área de Trabalho/teste/vue/components/layout.vue:1
    (function (exports, require, module, __filename, __dirname) { <template>
                                                                  ^
    
    SyntaxError: Unexpected token <
        at createScript (vm.js:74:10)
        at Object.runInThisContext (vm.js:116:10)
        at Module._compile (module.js:537:28)
        at Object.Module._extensions..js (module.js:584:10)
        at Module.load (module.js:507:32)
        at tryModuleLoad (module.js:470:12)
        at Function.Module._load (module.js:462:3)
        at Module.require (module.js:517:17)
        at require (internal/module.js:11:18)
        at Object.<anonymous> (index:7:15)
    

    captura de tela_2017-09-09_00-31-39

    opened by samuelnovaes 28
  • Sails.js

    Sails.js

    opened by ram-you 23
  • import of mixins fails

    import of mixins fails

    Hi, my project is using mixins but it seems that the import of those doesnt seem to work. After the route didnt wanted to render the .vue file using a mixin in one of its components,
    it loaded forever without error message or anything. After that, I tried using the mixin in another route and in the file I render (not in one of the components, and also beeing sure I didnt get the pathing wrong) the following error message was displayed on my console:

    { Error: Cannot find module 'C:MedieninformaitkMedieninformatikProjektTextBezugeRepoNLA-Projekt
                                                                                                   iewsmixinsanalysis
                                                                                                                     iltertoken.js'
        at Function.Module._resolveFilename (module.js:542:15)
        at Function.Module._load (module.js:472:25)
        at Module.require (module.js:585:17)
        at require (internal/module.js:11:18)
        at C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\views\profile.vue:20:20
        at Object.<anonymous> (C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\views\profile.vue:53:3)
        at Module._compile (module.js:641:30)
        at requireFromString (C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\node_modules\require-from-string\index.js:28:4)
        at FindAndReplaceComponents.then.compiled (C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\node_modules\vue-pronto\lib\renderer\renderer.js:335:36)
        at <anonymous> code: 'MODULE_NOT_FOUND' }
    

    From the looks of it, it seems that the backslashes '' are not written into the path. So for my project structure: path of my rendered file: C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\views\profile.vue path of mixin: C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\views\mixins\analysis\filtertoken.js

    imported like this:

    import filtertokenwithclass from './mixins/analysis/filtertoken.js';
        export default {
            mixins:[filtertokenwithclass],
            data: function () {
                return {
    .....
    

    I also tested:

    import filtertokenwithclass from 'views/mixins/analysis/filtertoken.js';
    import filtertokenwithclass from '/views/mixins/analysis/filtertoken.js';
    import filtertokenwithclass from './views/mixins/analysis/filtertoken.js';
    

    but the first 2 will return a wrong path but with correct backslashes and the last one looks like this (yeah I know it would also be a wrong path):

    { Error: Cannot find module 'C:MedieninformaitkMedieninformatikProjektTextBezugeRepoNLA-Projekt
                                                                                                   iews
                                                                                                       iewsmixinsanalysis
                                                                                                                         iltertoken.js'
        at Function.Module._resolveFilename (module.js:542:15)
        at Function.Module._load (module.js:472:25)
        at Module.require (module.js:585:17)
        at require (internal/module.js:11:18)
        at C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\views\profile.vue:20:20
        at Object.<anonymous> (C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\views\profile.vue:53:3)
        at Module._compile (module.js:641:30)
        at requireFromString (C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\node_modules\require-from-string\index.js:28:4)
        at FindAndReplaceComponents.then.compiled (C:\Medieninformaitk\Medieninformatik\ProjektTextBezuge\Repo\NLA-Projekt\node_modules\vue-pronto\lib\renderer\renderer.js:335:36)
        at <anonymous> code: 'MODULE_NOT_FOUND' }
    
    
    bug enhancement 
    opened by telion2 22
  • Cannot read property call of null v5 maybe

    Cannot read property call of null v5 maybe

    Description of Issue

    So I'm trying to upgrade to express-vue 5.02 I'm trying to render a simple thing like this:

    router.get('/', function(req, res) {
    	res.renderVue('test.vue', {}, {});
    });
    

    test.vue

    <template lang="html">
    	<div>
    		<h1>Welcome</h1>
    	</div>
    </template>
    <script>
    export default {
    	data: function() {
    		return {
    
    		}
    	}
    }
    </script>
    
    

    and I get this in the browser console when I try to go to the page:

    TypeError: Cannot read property 'call' of null at Proxy.renderStatic (vue.js:3843) at Proxy.render ((index):1) at Vue$3.Vue._render (vue.js:4465) at Vue$3.updateComponent (vue.js:2765) at Watcher.get (vue.js:3113) at new Watcher (vue.js:3102) at mountComponent (vue.js:2772) at Vue$3.$mount (vue.js:8416) at Vue$3.$mount (vue.js:10777) at (index):1

    bug 
    opened by sidjai 20
  • callback function required

    callback function required

    Hey!

    I'm getting this error:

    throw new Error('callback function required');
    

    My code is the example code

    const http = require('http');
    const express = require('express');
    const expressVue = require('express-vue');
    
    const app = express();
    
    app.set('vue', {
        rootPath: __dirname + '/',
        layoutsDir: 'routes/',
        componentsDir: 'components/',
        defaultLayout: 'layout'
    });
    app.engine('vue', expressVue);
    app.set('view engine', 'vue');
    
    app.get('/', (req, res) => {
      res.render('main', {
          data : {
              otherData: 'Something Else'
          },
          vue: {
              meta: {
                  title: 'Page Title',
              },
              components: ['myheader', 'myfooter']
          }
    
      });
    });
    
    http.createServer(app).listen(config['http-port'], config.ipAddress);
    

    Why does express is telling me there is no callback?

    opened by ghost 18
  • Vue Plugins

    Vue Plugins

    Hello There,

    I wanted to use Vue-Socket.io but it requires me to use Vue.use() function and I'm not able to figure out how to use that in express-vue 4.

    enhancement 
    opened by 0xDaksh 17
  • My app stopped working, looks like something to do with this package?

    My app stopped working, looks like something to do with this package?

    I have this app http://apilist.fun/, didn't add anything to it just restarted the server and fetched it again from my repo and did an npm install and it doesn't work well anymore, vue mehtods are not working...you can also check by going to an inner page apilist.fun/i/algolia it gets the component but the methods don't work, also on the homepage it seems to work but only methods won't work....can be something to do with the latest updates you've been making? I also tried after to fix it to update to the latest version of your package but still won't make it work...

    also on my localhos is not working anymore wether I fetch a really old commit that used to work it is not working

    also in the chrome console I try to fetch data like app.showModal for example and returns undefined like it can't fetch any data wether I added it on the .vue file or on the express route

    I love this package by the way ! thanks for creating it!

    opened by surfer77 17
  • TypeError: Cannot read property 'rootPath' of undefined while using in SailsJS

    TypeError: Cannot read property 'rootPath' of undefined while using in SailsJS

    Description of Issue

    I know, this lib is for Express, but I am trying to make it work in the Sails framework.

    Stack Trace / Console Log

    TypeError: Cannot read property 'rootPath' of undefined
        at new Defaults (/Users/duffpod/Desktop/vue-sails-test-2/node_modules/express-vue/dist/models/defaults.js:12:41)
        at SailsView.expressVue [as engine] (/Users/duffpod/Desktop/vue-sails-test-2/node_modules/express-vue/dist/index.js:15:20)
        at SailsView.View.render (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/view.js:76:8)
        at Function.app.render (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/application.js:561:10)
        at ServerResponse.res.render (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/response.js:845:7)
        at ServerResponse.res.view (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/lib/hooks/views/res.view.js:284:16)
        at fn (/Users/duffpod/Desktop/vue-sails-test-2/config/routes.js:37:18)
        at routeTargetFnWrapper (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/lib/router/bind.js:181:5)
        at callbacks (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:164:37)
        at param (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:138:11)
        at pass (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:145:5)
        at nextRoute (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:100:7)
        at callbacks (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:167:11)
        at module.exports (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/lib/hooks/cors/clear-headers.js:14:3)
        at routeTargetFnWrapper (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/lib/router/bind.js:181:5)
        at callbacks (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:164:37)
        at param (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:138:11)
        at pass (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:145:5)
        at nextRoute (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:100:7)
        at callbacks (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/node_modules/@sailshq/express/lib/router/index.js:167:11)
        at sails.router.bind._middlewareType (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/lib/hooks/csrf/index.js:148:11)
        at routeTargetFnWrapper (/Users/duffpod/.nvm/versions/node/v7.7.2/lib/node_modules/sails/lib/router/bind.js:181:5)
    

    Additional Comments

    Tracked the error to the file at dist/models/defaults.js. Fixed by supplying the empty objects while pre-validating the options variable.

    From this:

    var Defaults = function Defaults(options) {
        _classCallCheck(this, Defaults);
    
        this.rootPath = options.settings.vue.rootPath === undefined ? options.settings.views + '/' : options.settings.vue.rootPath + '/';
        this.layoutsDir = options.settings.vue.layoutsDir === undefined ? '' : this.rootPath + options.settings.vue.layoutsDir + '/';
        this.componentsDir = options.settings.vue.componentsDir === undefined ? '' : options.settings.vue.componentsDir + '/';
        this.defaultLayout = options.settings.vue.defaultLayout === undefined ? '' : options.settings.vue.layoutsDir === undefined ? this.rootPath + options.settings.vue.defaultLayout : options.settings.vue.defaultLayout;
        this.options = options.settings.vue.options === undefined ? {} : options.settings.vue.options;
        this.backupLayout = '<template><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><script src="https://unpkg.com/vue/dist/vue.js"></script></head><body>{{{app}}}{{{script}}}</body></html></template><script></script><style></style>';
        this.layoutPath = this.layoutsDir + this.defaultLayout + '.vue';
        this.options = options;
    };
    

    To this:

    var Defaults = function Defaults(options) {
        _classCallCheck(this, Defaults);
    
        options.vue = options.vue === undefined ? {} : options.vue
        options.settings.vue = options.settings.vue === undefined ? {} : options.settings.vue;
    
        this.rootPath = options.settings.vue.rootPath === undefined ? options.settings.views + '/' : options.settings.vue.rootPath + '/';
        this.layoutsDir = options.settings.vue.layoutsDir === undefined ? '' : this.rootPath + options.settings.vue.layoutsDir + '/';
        this.componentsDir = options.settings.vue.componentsDir === undefined ? '' : options.settings.vue.componentsDir + '/';
        this.defaultLayout = options.settings.vue.defaultLayout === undefined ? '' : options.settings.vue.layoutsDir === undefined ? this.rootPath + options.settings.vue.defaultLayout : options.settings.vue.defaultLayout;
        this.options = options.settings.vue.options === undefined ? {} : options.settings.vue.options;
        this.backupLayout = '<template><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><script src="https://unpkg.com/vue/dist/vue.js"></script></head><body>{{{app}}}{{{script}}}</body></html></template><script></script><style></style>';
        this.layoutPath = this.layoutsDir + this.defaultLayout + '.vue';
        this.options = options;
    };
    
    opened by duffpod 17
  • Components require path

    Components require path

    Description of Issue

    i have get this error when i import the components to the .vue file the path i have seen was correct but the error show that the path generate from rootpath was missing the "/"

    image

    Stack Trace / Console Log

    image

    Additional Comments

    opened by lokhharry 15
  • Unable to include local css file

    Unable to include local css file

    Apologies if this is user error; I have referenced your examples and documentation, but obviously am having issues.

    Under the render => vue => meta => head array I have applied two styles:

    head: [
      // works
      {style: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'},
      // doesn't work
      {style: __dirname + '/static/css/styles.css'}
    ]
    

    The second returns an error of Not allowed to load local resource:.

    opened by OmisNomis 14
  • mounted is not working for rendered file

    mounted is not working for rendered file

    Description of Issue

    Hello. I am trying to use `express-vue` to render a .vue file in one of my route in node. I need to use the mounted lifecycle hook for some data. But I am facing some difficulties as my mount is not working when the file is rendered in the browser.

    Example vue file:

    <template>
      <div>
        {{ isMounted }}
      </div>
    </div>
    </template>
    <script>
    mounted: function() {
        console.log('hello senpai');
        this.isMounted = true;
      },
    </script>
    

    Exposed Node route:

    routes.get('/example', async (req, res) => {
      try {
        const data = {
          variableOne: await getvariableOne(httpVal),
        };
        res.renderVue('example.vue',data);
      } catch(e) {
        logger.error(`Failed to generate`, e);
        res.sendStatus(503);
      }
    })
    

    server.js:

    const vueOptions = {
      rootPath: path.join(__dirname, '../../components/view'),
      vueVersion: '2.6.14', 
    
    };
    const expressVueMiddleware = expressVue.init(vueOptions);
    
    app.use(expressVueMiddleware);
    

    The isMounted variable here is always false when rendered and also not getting the console. I cannot use created lifecycle as data is manipulated after the template is rendered. Any sort of help will be appreciated. Thanks.

    opened by rafaelragib 0
  • Add CodeQL workflow for GitHub code scanning

    Add CodeQL workflow for GitHub code scanning

    Hi express-vue/express-vue!

    This is a one-off automatically generated pull request from LGTM.com :robot:. You might have heard that we’ve integrated LGTM’s underlying CodeQL analysis engine natively into GitHub. The result is GitHub code scanning!

    With LGTM fully integrated into code scanning, we are focused on improving CodeQL within the native GitHub code scanning experience. In order to take advantage of current and future improvements to our analysis capabilities, we suggest you enable code scanning on your repository. Please take a look at our blog post for more information.

    This pull request enables code scanning by adding an auto-generated codeql.yml workflow file for GitHub Actions to your repository — take a look! We tested it before opening this pull request, so all should be working :heavy_check_mark:. In fact, you might already have seen some alerts appear on this pull request!

    Where needed and if possible, we’ve adjusted the configuration to the needs of your particular repository. But of course, you should feel free to tweak it further! Check this page for detailed documentation.

    Questions? Check out the FAQ below!

    FAQ

    Click here to expand the FAQ section

    How often will the code scanning analysis run?

    By default, code scanning will trigger a scan with the CodeQL engine on the following events:

    • On every pull request — to flag up potential security problems for you to investigate before merging a PR.
    • On every push to your default branch and other protected branches — this keeps the analysis results on your repository’s Security tab up to date.
    • Once a week at a fixed time — to make sure you benefit from the latest updated security analysis even when no code was committed or PRs were opened.

    What will this cost?

    Nothing! The CodeQL engine will run inside GitHub Actions, making use of your unlimited free compute minutes for public repositories.

    What types of problems does CodeQL find?

    The CodeQL engine that powers GitHub code scanning is the exact same engine that powers LGTM.com. The exact set of rules has been tweaked slightly, but you should see almost exactly the same types of alerts as you were used to on LGTM.com: we’ve enabled the security-and-quality query suite for you.

    How do I upgrade my CodeQL engine?

    No need! New versions of the CodeQL analysis are constantly deployed on GitHub.com; your repository will automatically benefit from the most recently released version.

    The analysis doesn’t seem to be working

    If you get an error in GitHub Actions that indicates that CodeQL wasn’t able to analyze your code, please follow the instructions here to debug the analysis.

    How do I disable LGTM.com?

    If you have LGTM’s automatic pull request analysis enabled, then you can follow these steps to disable the LGTM pull request analysis. You don’t actually need to remove your repository from LGTM.com; it will automatically be removed in the next few months as part of the deprecation of LGTM.com (more info here).

    Which source code hosting platforms does code scanning support?

    GitHub code scanning is deeply integrated within GitHub itself. If you’d like to scan source code that is hosted elsewhere, we suggest that you create a mirror of that code on GitHub.

    How do I know this PR is legitimate?

    This PR is filed by the official LGTM.com GitHub App, in line with the deprecation timeline that was announced on the official GitHub Blog. The proposed GitHub Action workflow uses the official open source GitHub CodeQL Action. If you have any other questions or concerns, please join the discussion here in the official GitHub community!

    I have another question / how do I get in touch?

    Please join the discussion here to ask further questions and send us suggestions!

    opened by lgtm-com[bot] 0
  • invalid starter link

    invalid starter link

    The example/starter link doesn't work

    I got 404 error while opening "https://github.com/express-vue/express-vue-mvc-starter" link.

    any idea where to find a starter project?!

    opened by mmRoshani 0
Releases(v5.7.0)
  • v5.7.0(Aug 28, 2018)

  • 5.5.0(Mar 16, 2018)

    It's like res.renderVue

    but instead of super cool streams.... it returns a string.

    It's blocking, and it's slower... but if you need a string instead of a stream.. here you go!

    Source code(tar.gz)
    Source code(zip)
  • 5.4.0(Mar 16, 2018)

  • 5.2.0(Feb 27, 2018)

  • 5.1.0(Feb 19, 2018)

    You now no longer need to put in any config into express-vue's init method, it's now as simple as this.

    const expressVue = require("express-vue");
    const express = require("express");
    const app = express();
    
    const expressVueMiddleware = expressVue.init();
    app.use(expressVueMiddleware);
    

    HURRAH!! 🙌

    Source code(tar.gz)
    Source code(zip)
  • v5.0.2(Feb 14, 2018)

    Summary

    • Ditched the custom parser/renderer and moved to using vue-pronto which uses Vueify
    • Re-structured the vueOptions
    • Added req.vueOptions as a global.
    • Removed the vue parent object with the child of head, this was un-needed its now just vueOptions.head instead of vueOptions.vue.head when using res.renderVue the filename requires an extention now.
    • Paths are now RELATIVE to the file you're currently in ... YAAAY
    • Node Modules are supported, for both javascript and vue file imports inside .vue files ... YAAAY
    • Massive Performance gains
    • 100% compatability with vueJS

    Migration to Vue-Pronto

    Express-vue-renderer got too heavy, the architecture became too messy, and it was slow. It needed to get thrown out. Enter vue-pronto it uses vueify under the hood, and is much more modular. this will be much easier going forward to maintain.

    Changes to the Vue Options Object

    There's been some big changes to this object, so before it would look like this

    const vueOptions = {
        vue: {
            head: {
                meta: [
                    { script: 'https://unpkg.com/[email protected]/dist/vue.js'},
                    { name: 'application-name', content: 'Name of my application' },
                    { name: 'description', content: 'A description of the page', id: 'desc' },
                    { style: '/assets/style.css' }
                ]
            }
        }
    };
    

    Now its different ..

    • We have automated getting vueJS from the CDN for you, and which version (dev/prod) it should use based on the environment variable VUE_DEV.
    • We also broke up the meta object, into metas, scripts, and styles arrays.
    • scripts now have scriptSrc which is a string including the <script> elements which will be placed in your head as is.
    • The parent vue object that wraps the head object was unneeded and removed.

    here's the same as above but newer

    const vueOptions = {
        vueOptions: "2.4.2",
        head: {
            metas: [
                { name: 'application-name', content: 'Name of my application' },
                { name: 'description', content: 'A description of the page', id: 'desc' },
            ],
            styles: [
                { style: '/assets/style.css' }
            ]
        }
    };
    

    Vue File changes

    Routes before were relative to the rootPath... now that is gone... routes for requires are relative to the file you are currently in. Also node_module paths are working for both .js and .vue includes

    Remember to look at this if you're getting errors!

    res.renderVue Changes

    res.renderVue now requires an extension for the file you're using in the route. foo/bar now foo/bar.vue

    New

    Global req.vueOptions. this is super handy for passing options around between middleware.

    Source code(tar.gz)
    Source code(zip)
  • 4.0.9(Aug 29, 2017)

  • v4.0.0(Aug 4, 2017)

    Welcome to the new express-vue

    There's a lot of features, and new things.. its a massive change, and a breaking one if you're coming from v3.

    No longer uses res.render() introducing res.renderVue()

    We had to ditch res.render since this is a sync call, and slows down your server. It requires the library to have totally rendered everything before sending to the client.

    We have replaced it with **res.renderVue() which returns a stream!

    res.renderVue('nameofVueFile', {data}, {vueOptions})
    // Note data, and vueOptions objects are optional
    

    It's mostly the same, except its now non-blocking, This improves performance, before we were seeing an average of 140 requests a second, at about 1000ms lag, now were seeing 1000 requests a second at a 0.9ms lag (this is in production mode)

    Migrated the engine into a separate project.

    This allows us to have finer control over the library, and ultimately write the engine in C++. The long term plan is to have this library do nodeJS/Express ... and then write others for Java, Golang, and Swift

    New instantiation and options

    Before you had to use this as the view engine.. now its middleware.

    var expressVue = require('express-vue');
    
    var app = express();
    const vueOptions = {
        rootPath: path.join(__dirname, '../example/views'),
        layout: {
            start: '<div id="app">',
            end: '</div>'
        }
    };
    const expressVueMiddleware = expressVue.init(vueOptions);
    app.use(expressVueMiddleware);
    

    Lots of the config has changed, its best to read the README.

    Source code(tar.gz)
    Source code(zip)
  • v3.14.1(Jun 16, 2017)

    Huge performance increase.

    We started noticing concurrency issues at massive scale, so we have solved this issue.

    Increases of 1000%!!

    Huge thanks to @nick-fytros!!

    Source code(tar.gz)
    Source code(zip)
  • v3.12.0(May 15, 2017)

    Big release.

    You are now able to use CSS in component/view files..

    please use CSS for now, SCSS/LESS/etc support requires those lang's to be compiled, and since this is a runtime library, it will slow down your rendering on the server.

    Readme has been updated.

    Source code(tar.gz)
    Source code(zip)
  • v3.11.0(May 8, 2017)

    Scoped Slots

    @boguan updated the regex used for template identifying to allow for scoped slots in pull request #72

    Stack Traces

    @ralucas added better erroring into the parser in pull request #71, so you should see better stack traces!

    Thanks to both these two!

    Source code(tar.gz)
    Source code(zip)
  • v3.9.12(Apr 27, 2017)

  • v3.9.0(Mar 3, 2017)

    Hey,

    Ok a few things this updates

    • Better Error handling, it will now tell you that it can't find a file instead of just hard exiting node.
    • New Vue Head object (with fallback to old version)
    • Support for Google Structured Data in the head
    • Dropped support for node v4 and node v5

    Dropped Support for node V5 and lower!

    This is super important, I'm really sorry to have to do this going forward but some of the vue libraries have dropped support for this going forward and I have to follow suit node v6 is LTS, and has been for a while now, so you really should be updating.

    New Vue Head Object

    This is the new vue head object.. what changed? well i realised that in the vue block, there was a meta section and then head inside that. It made zero sense, it should have been a head block where title, and meta lived inside that basically like this example below!

    {
            data: {
                otherData: 'Something Else'
            },
            vue: {
                head: {
                    title: 'Page Title',
                    meta: [
                        { property:'og:title', content: 'Page Title'},
                        { name:'twitter:title', content: 'Page Title'},
                    ]
                }    
            }
    }
    

    So much nicer now! (I can sleep better at night)

    Source code(tar.gz)
    Source code(zip)
  • v3.6.0(Feb 23, 2017)

    Now in you can use pug/jade in your components!

    <template lang="pug">
        div.super-cool
            button(v-on:submit="amazingHandler") Button
    </template>
    

    Huge thanks to @refextu for the wonderful contribution!

    Source code(tar.gz)
    Source code(zip)
  • v3.5.0(Jan 20, 2017)

    Devtools!!!!

    You can now use the amazing chrome vue devtools by enabling devtools through the VUE_DEV=true environment variable

    Other

    • Moved second script into primary, No more need for that second script block, everything is handled now, this is referred in the readme file. if you still have this <script>app.$mount('#app')</script> you can remove it when using v3.5.0
    • Minor text fixes
    Source code(tar.gz)
    Source code(zip)
  • v3.2.0(Dec 1, 2016)

    • Changed the vue config object,
    • Added fallbacks
    • Removed the need to use rootPath and LayoutsDir

    Updated for a minimal and optional setup

    var expressVue = require('express-vue');
    
    var app = express();
    app.set('views', __dirname + '/app/views');
    //Optional if you want to specify the components directory seperate to your views, and/or specify a custom layout.
    app.set('vue', {
        //ComponentsDir is optional if you are storing your components in a different directory than your views
        componentsDir: __dirname + '/components',
        //Default layout is optional it's a file and relative to the views path, it does not require a .vue extention.
        //If you want a custom layout set this to the location of your layout.vue file.
        defaultLayout: 'layout'
    });
    app.engine('vue', expressVue);
    app.set('view engine', 'vue');
    
    Source code(tar.gz)
    Source code(zip)
  • v3.1.2(Dec 1, 2016)

  • v3.1.0(Nov 30, 2016)

    • Adds Support for Script and Style in META object
    head: {
        // Meta tags
        meta: [
            // Scripts
            { script: '/assets/scripts/hammer.min.js' },
            { script: '/assets/scripts/vue-touch.min.js', charset: 'utf-8' },
            // Note with Scripts [charset] is optional defaults to utf-8
            // ...
            // Styles
            { style: '/assets/rendered/style.css' }
            { style: '/assets/rendered/style.css', type: 'text/css' }
            { style: '/assets/rendered/style.css', type: 'text/css', rel: 'stylesheet' }
            // Note with Styles, [type] and [rel] are optional...
            // ...
        ],
    }
    
    Source code(tar.gz)
    Source code(zip)
  • v3.0.7(Nov 28, 2016)

  • v3.0.1(Nov 7, 2016)

    Huge refactor.

    Deprecated old object structure you passed into the view through the route..

    new object

    const viewObject = {
            data: {
                otherData: 'Something Else'
            },
            vue: {
                meta: {
                    title: 'Page Title',
                    head: [
                        { property:'og:title' content: 'Page Title'},
                        { name:'twitter:title' content: 'Page Title'},
                    ]
                },
                components: ['myheader', 'myfooter']
            }
    res.render('main', viewObject);
    

    The new object contains two root objects, vue and data. Everything in data will be passed into the parent .vue file's data function (REMEMBER: all data must be in functions! as per the vue spec) Everything in vue is configuration for vue. Currently available are meta and components as above.

    Everything in meta.head array is structured like above its JSON which translates into HTML

    Source code(tar.gz)
    Source code(zip)
  • v2.0.5(Oct 31, 2016)

  • v2.0.4(Oct 31, 2016)

    • Speeds up processing vue components
    • Adds more security
    • Fixed bug with SSR template not being sent with final HTML
    • Minor text fixes (lol)

    Huge thanks to @eirslett for his help with amazing es6 lambda functions.

    Source code(tar.gz)
    Source code(zip)
  • 1.0.3(Oct 6, 2016)

  • 1.0.2(Oct 6, 2016)

Owner
express-vue
express-vue
A Vue plugin for using Server-Sent Events (EventSource).

VueSSE VueSSE enables effortless use of Server-Sent Events by providing a high-level interface to an underlying EventSource. Install # npm npm install

James 106 Dec 14, 2022
Vue CLI plugin to create universal Vue applications with ease

UVue Build universal Vue applications with ease Documentation Live demo CodeSandbox template Discord chat Getting started Install vue add @uvue/ssr Th

UVue 128 Dec 24, 2022
The Intuitive Vue Framework

Build your next Vue.js application with confidence using Nuxt: a framework making web development simple and powerful. Links ?? Documentation: https:/

Nuxt 41.8k Jan 4, 2023
A super fast SSR framework for Vue.js.

Ream A super fast SSR framework for Vue.js. ❤️ Please sponsor me to support this project or prioritize a feature you want. I will work on this project

Ream 605 Dec 9, 2022
Server-side generation for Vue 3 on Vite

Server-side generation for Vue 3 on Vite

Anthony Fu 899 Jan 2, 2023
Vue rendering engine for Express.js. Use .Vue files as templates using streams

express-vue A Simple way of using Server Side rendered Vue.js 2.0+ natively in Express using streams If you want to use vue.js and setup a large scale

express-vue 1.3k Dec 30, 2022
Vue + Express.js = VueXpress / A server side rendering engine for Express.js. Use .vue files as your express.js templates.

Introduction VueXpress is a template engine for express.js. You can easily rendering *.vue templates on the server. Check out the usage information. I

null 101 Nov 9, 2022
Server-side rendering engine that renders vue files into html strings

Servue Helping you serve vue with servue Server-side rendering engine that renders vue files into html strings Servue Installation What is servue? Fea

Future Australia Party 57 Dec 23, 2022
Vue Cookbook (Vue1.0 + express) @yjj5855Vue Cookbook (Vue1.0 + express) by @yjj5855: A demo first screen rendering of a service

使用node.js+Vue.js+webpack 用node当前端服务器和后台服务器通讯和渲染页面,使用vue,vue-server,vue-router来实现SPA应用. 解决了SPA应用的SEO缺点,访问的第一个页面,使用vue-server来服务端渲染.使用vue-router+webpack

yjj5855 280 Dec 8, 2021
Vue Junmper: Retro style 3D rendering engine in full HD Realistic driving physics

vue-jumper live demo Controls Mouse = Steer Click = Brake Double Click = Jump R

晓寻遥 12 Dec 28, 2022
Self hostable tracker for twitch streams you actually watch.

Self hosted solution to efficiently managing twitch stream notifications and always stay up to date with your ever changing list of favorite streamers

null 4 Nov 2, 2021
A Vue2 plugin for input content suggestions, support using keyboard to navigate and quick pick, it make use experience like search engine input element

v-suggest A Vue2 plugin for input content suggestions, support using keyboard to navigate and quick pick, it make use experience like search engine in

Terry Zeng 74 Aug 27, 2022
A Vue2 plugin for input content suggestions, support using keyboard to navigate and quick pick, it make use experience like search engine input element

v-suggest A Vue2 plugin for input content suggestions, support using keyboard to navigate and quick pick, it make use experience like search engine in

Terry Zeng 74 Aug 27, 2022
Movue - Movie, Series Search Engine developed using omdb api with Vuejs. Vue Router, Vue Resource, Vuex

A project developed using omdb api with Vuejs. Vue Router, Vue Resource, Vuex were used in the development process

Mert Çalkan 2 Oct 24, 2022
Portfolio-public - A blog engine from scratch using Firebase And Vue.js

portfolio This is the code for my personal website mediocrebanana.com! I built a

Kevin Ma 2 May 30, 2022
Generate TypeScript declaration files for .vue files

vuedts This repository is fork from https://github.com/ktsn/vuetype Because that repository has not maintained now. Generate TypeScript declaration fi

null 20 Jan 5, 2022
A fullstack web project generator, use vue2.0 + vue-router + vuex + vue-router + express

generator-fullstack-vue Scaffold out a Fullstack Vuejs project:vue2;vuex;vue-router;vue-resource;express;mongo Installation First, install Yeoman and

lx 18 Aug 21, 2018
Multiplayer online chess game use Vue , Nodejs, Webpack, Em6, Socket.io, Mongodb, Express

VueChess Users can create private or public games against other real-time player or against the computer by choosing color, time and type of starting,

Gustavo Crespo Sanchez 405 Dec 20, 2022
A basic example of how to use VueJS, Express and PostgreSQL in conjunction.

PEVN (PostgreSQL Express VueJS NodeJS) Starter A basic example of how to use VueJS, Express and PostgreSQL in conjunction. More details on my blog pos

Jesal Gadhia 55 Dec 12, 2022
Generate dynamic PDFs using Vue templates and Prince

Generate dynamic PDFs using Vue templates and Prince

Mom's Friendly Development Company 0 Mar 21, 2021