Giter Site home page Giter Site logo

vue-cli-plugin-ssr's Introduction

@akryum/vue-cli-plugin-ssr

npm npm vue-cli3

Simple Server-Side-Rendering plugin for Vue CLI (Work-in-Progress)

Become a Patreon



Sponsors

Gold

sum.cumo logo

Silver

VueSchool logo Vue Mastery logo

Bronze


About

⭐ Features:

  • Automatic conversion of your project to SSR
  • Integrated express server
  • Vuex store
  • Async routes
  • vue-cli-plugin-apollo support
  • Custom middlewares

🚀 Roadmap:

  • Automatic conversion of vuex modules to state () {}
  • Integration with CLI UI

vue-cli-plugin-ssr's People

Contributors

akryum avatar alexandrebonaventure avatar chriscalo avatar davidrouyer avatar dsanders11 avatar frankfoerster avatar hmillison avatar kdmcclel avatar p1n5u avatar rdunk avatar sinanig1996 avatar skyhark-sacha avatar sodatea avatar svewag avatar tylermadsen avatar ulich avatar waydelyle avatar yekver avatar zickat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-cli-plugin-ssr's Issues

Docker Alpine Image - clipboardy & xcel

Having this issue with docker alpine image:

  - Local:   http://localhost:8080 (copied to clipboard)
(node:27) UnhandledPromiseRejectionWarning: Error: Couldn't find the required `xsel` binary. On Debian/Ubuntu you can install it with: sudo apt install xsel
    at handler (/usr/src/app/node_modules/clipboardy/lib/linux.js:7:9)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:27) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)
(node:27) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

Comparison with Nuxt

The ReadMe suggest that this project is still work-in-progress and the package has still not reached 1.0.0. However, I saw @Akryum demo it at the GraphQL summit 2018 and it looks fairly simple (great work!). The documentation is clear but there are not many stars or maintainers but there is a core Vue.js contributor involved. I'm trying to understand if it's ready to use for a production app or if I should sacrifice everything Vue CLI offers (which is a lot) and go with Nuxt for now.

Running completion hooks task hangs, node thread maxes out at 100% cpu

image

node -v 8.12.0

Trying to run the plugin in a pre-existing vue-cli-3 scaffolded app.

I'm not sure how to better stack trace the error, let me know if there's anything more I can do to help give a more meaningful report.

PS: Enjoyed your talk at VueJS Amsterdam, inspired to get SSR working on a vue-apollo based app I've been working on!

Router import when scaffolding into an existing project

I tried this plugin today and ran it in an existing project.
Everything went well in the end but there was one small issue:

Initially Vue CLI imports the router file like this.

import router from "./router"

After installing the plugin, the import remained the same, however router.js file changed and it exports a createRouter function.
Had to change the line above to
import {createRouter} from "./router"

I can see in the code, this is actually handled https://github.com/Akryum/vue-cli-plugin-ssr/blob/master/generator/index.js#L47

Maybe it's an issue with single/double (' and ") quotes ?

Adding Additional Keys to Context Object

Firstly thank you for all the effort of creating this wonderful plugin. I was wondering if there was a way of adding additional parameter to context object so one can use custom data inside index.html file.

for example

<!DOCTYPE html>
<html>
  <head>
    <title>{{ title }}</title>
    <script>var customData = '{{{ customData }}}'</script>
    {{{ renderResourceHints() }}}
    {{{ renderStyles() }}}
    
  </head>
  <body>
    <!--vue-ssr-outlet-->
    {{{ renderState() }}}
    {{{ renderState({ contextKey: 'apolloState', windowKey: '__APOLLO_STATE__' }) }}}
    {{{ renderScripts() }}}
  </body>
</html>

Use webpack chain

At first, I decided not to use this plugin, so I copied some stuff and then converted your webpack config to use webpack chain.
@Akryum Would you like to see a PR with this conversion?

Redirecting to a route on app initialisation

Currently I have two version of an app and I have separated them into two chunks using async components.

my router looks like this:

export function createRouter () {
  return new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [
      {
        path: '/',
        component: () => import(/* webpackChunkName: "web-app" */'./WebApp')
      },
      {
        path: '/cna',
        component: () => import(/* webpackChunkName: "cna-app" */'./CnaApp'),
        children: [
          {
            name: 'VSplashPage',
            path: '/',
            component: () => import(/* webpackChunkName: "cna-app" */'./components/pages/VSplashPage')
          },
          {
            name: 'VFallbackPage',
            path: '/fallback',
            component: () => import(/* webpackChunkName: "cna-app" */'./components/pages/VFallbackPage')
          }
        ]
      }
    ]
  })
}

Is there a way to redirect the user to the correct app based on a condition on initialisation? I tried adding this in my app.vue :

created() {
    this.$router.push('/cna')
}

but it doesn't seem to work :(

v0.3.0 fails to run from inside docker container

v0.3.0 works fine in bare linux/windows environments, but fails to run from inside docker contains. Here is how to reproduce:

  1. make sure docker for linux/windows is installed on host

  2. vue create test with mininal configs (only choosing router is enough)

  3. cd test && vue add @akryum/ssr

  4. put the following docker-compose.yml in the root folder of the created test project:

    version: '3.7'
    
    services:
      test:
        container_name: 'test'
        image: node:8
        volumes:
          - .:/test
        working_dir: /test
        ports:
          - '8000:8000'
        restart: always
        command: ['node', './node_modules/@vue/cli-service/bin/vue-cli-service.js', 'ssr:serve']
  5. run docker-compose up -d

  6. run docker exec -it test curl localhost:8000 and see the ssr running correctly inside the docker

  7. however, run curl localhost:8000 directly from host getting curl: (52) Empty reply from server, despite that we already use ports: - '8000:8000' to forward the http service from the container out to the host.

why I think it's a bug for v0.3.0:

  1. simply change the last line of the docker-compose.yml to

     command: ['node', './node_modules/@vue/cli-service/bin/vue-cli-service.js', 'serve', '--port', '8000']
    

    and then curl localhost:8000 works;

  2. simply installing v0.2.3 instead of v0.3.0 fixes it, too.

Problem with vue-cli-plugin-vuetify

After adding this plugin over vue-cli-plugin-vuetify and vue-cli-plugin-apollo I I get the following error on ssr:serve

...\node_modules\vuetify\lib\index.js:1
(function (exports, require, module, __filename, __dirname) { import Vuetify from './components/Vuetify';
                                                                     ^^^^^^^

SyntaxError: Unexpected identifier
    at new Script (vm.js:79:7)
    at createScript (vm.js:251:10)
    at Object.runInThisContext (vm.js:303:10)
    at Module._compile (internal/modules/cjs/loader.js:657:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at r (E:\Projects\ready\frontend\node_modules\vue-server-renderer\build.js:8365:16)
    at Object.vuetify/lib (webpack:/external "vuetify/lib":1:0)
    at __webpack_require__ (webpack/bootstrap:25:0)
    at Module../src/App.vue (src/App.vue:1:0)
    at __webpack_require__ (webpack/bootstrap:25:0)
    at Module../src/entry-server.js (app.js:1492:66)

Disable ssr

Is there any way to disable SSR after installing plugin? Maybe something like <no-ssr> component in nuxt.js?

HMR doesn't apply to the DOM

Thank you for the most accurate ssr plugin at first :)

I do:
vue add this plugin
yarn ssr:serve

browser console:

[HMR] connected client.js:92
// then I've made changes in App.vue, i.e.
[HMR] bundle rebuilding client.js:234
[HMR] bundle rebuilt in 1756ms client.js:242
[HMR] Checking for updates on the server... process-update.js:41
[HMR] Updated modules: process-update.js:114
[HMR]  - ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"/home/ ... src/App.vue?vue&type=template&id=7ba5bd90& process-update.js:116
[HMR]  - ./src/App.vue?vue&type=template&id=7ba5bd90& process-update.js:116
[HMR] App is up to date. process-update.js:121 

And it doesn't affect DOM: I cannot see the changes.

Version: the latest vue-cli to now and webpack.

Running SSR Server does not work with Typescript

I'm evaluating this plugin to use with a Vue-CLI project created with Typescript.

Repro steps:
vue create new-project
vue add @vue/typescript
vue add @akryum/ssr
npm run ssr:serve

Result: When opening localhost:8000, I get an error from the server on initial render: TypeError: runner is not a function.

Expected Result: Example app renders as expected.

Let me know if this is on the radar already? I'm pretty interested in this project so I would be happy to attempt to contribute a solution to this issue.

demo repo: https://github.com/hmillison/vue-ssr-plugin-reproduction.git

Server use

Hello, I want to know how to use it on the server side. Is there any documentation available? Also support koa2?

e2e tests: wait for first compilation

Hi,
Thanks for the package, it is great!
I'm trying to setup e2e tests with SSR with Cypress. The official e2e-cypress-cli-plugin does not allow to specify to run an alternative command to 'serve' (here ssr:serve) so I overcame the problem by creating a custom service such as :

module.exports = (api, opts) => {
  api.registerCommand('test:e2e:ssr', async (args, rawArgs) => {
    const server = await api.service.run('ssr:serve')
    args.url = 'http://localhost:8080'
    const runner = await api.service.run('test:e2e', args, rawArgs)
    runner.on('exit', () => server.close())
    runner.on('error', () => server.close())
    return runner
  })
}

Problem

ssr:serve signature is pretty different from the traditional serve and this code up there ⬆️ wasn't await the initial compilation like you would expect from serve.

PR

In order to be able to wait for the initial compilation before starting e2e tests, I had to return the readyPromise from the app middleware.

registerServiceWorker import not being removed from main.js when using semicolons

Hello, another quick fix here.

When invoking this plugin in a project with the pwa plugin and an eslint config that uses semicolons, the registerServiceWorker import line is not removed from main.js.

This can be resolved by doing this

-contents = contents.replace(/import ('|")\.\/registerServiceWorker('|")\n/, ``)
+contents = contents.replace(/import ('|")\.\/registerServiceWorker('|");?\n/, ``)

Here https://github.com/Akryum/vue-cli-plugin-ssr/blob/master/generator/index.js#L47

Duplicated CSS rules in production

When using this CLI plugin, there are duplicated CSS rules when using CSS modules and the "composes" feature. This seems to be caused by the critical CSS that's inlined into the <head> and is both happening in development and production (main issue).

I've created the following test repo (https://github.com/mrksbnch/vue-ssr-css-issue) that I created using vue create (Vue router as the only feature) and vue add @akryum/vue-cli-plugin-ssr. Afterwards, I added a test.css file in the folder assets and composed (<style module>) two style declarations from that file in Home.vue and HelloWorld.vue.

You can see the duplicated rules after running npm run ssr:serve or npm run ssr:build and npm run ssr:start in the dev tools:

screen shot 2019-01-06 at 18 32 42

Both CSS rules are inlined on the server side (<style data-vue-ssr-id>):

screen shot 2019-01-06 at 18 33 20

This is just a simple test repo with only one CSS rule. In a proper app this will cause a lot (!) of duplicated CSS rules and increase the file size by quite a bit. I've tested it with a simple app and I noticed some rules being duplicated 5 or 6 times.

Generator won't work for directory based router and store

The generator expects a router.js at the base of the src folder. It might suits a lot of projects, but some project architectures decouple their routes or their store into sub-parts. Thus, there is one «router» directory with one «index.js» file that composes the router definitions. Same for the store.

If you look at line 85 of generator/index:

      const file = getFile(api, './src/router.js')

Then two lines later, it'll fail:

        let contents = fs.readFileSync(file, { encoding: 'utf8' })

how to use asyncData ?

Hi,

how to use asyncData ? I have problem app init vuex state data.

Good works

 App running at:
  - Local:   http://localhost:8001
(node:10829) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'errorMessage' of undefined
    at app.js:3606:20
(node:10829) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not
 handled with .catch(). (rejection id: 716)

Plugin breaks `yarn/npm run serve`

I'm aware that this plugin is supposed to add SSR to a Vue CLI project and yarn/npm run ssr:serve works fine but it would still be great to support yarn/npm run serve in order to run the project as a regular SPA without SSR (if needed).

Currently, after adding this plugin and trying to run the development server (without SSR) it just shows a blank page. The other SSR plugin (https://github.com/vueneue/vueneue) seems to support both npm commands.

Options for point to various files

I see that the generator file modifies existing files (main.js, vuex/store.js, etc). I'd like to be able to tell the plugin where these files are located in my project, since they aren't in the root src directory. Im still new to the the Vue CLI architecture but it seems like maybe using a generator preset or something might allow a user to set custom locations. Is that correct thinking?

Guidance on running this project locally

Hi, i'm trying to run this project locally with it linked to my own application so I can test out some minor updates to this, but I am getting a number of "cannot find module" errors when running npm run ssr:serve.

Any guidance on specific configuration that is needed to run this locally?

Static Site Generation

It would be very cool to give this plugin the ability to generate static routes for static site hosting like Github Pages.

Server prefetch hook

I think, need create prefetch hook, what do check serverPrefetch and mounted hook

SSR server freezes after throwing error.

Both apollo-server and graphql-yoga automatically collect errors thrown in resolver functions and pass a sanitized version of the erros to the front-end. That works perfectly without ssr.

However, when doing this with vue-cli-plugin-ssr, the ssr server freezes when the graphql server thrown errors. Not only yarn ssr:serve but also yarn ssr:start behaves like that, making it quite fragile in production.

I am not sure if this is due to my mis-configuration or something else?

Vuex Store is called more than twice

Hi,
I didn't understand why store is call more than twice in my vue-cli ui I can log four time the same function call:

initOffresEmploi count request 174
sotre setCountOffresEmploi 174

initOffresEmploi count request 174
sotre setCountOffresEmploi 174

initOffresEmploi count request 174
sotre setCountOffresEmploi 174

fetchOffresEmploi 174
fetchOffresEmploi final count 100

initOffresEmploi count request 174

Error running build:ssr

ERROR WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.

  • configuration[1] has an unknown property 'optimization'.

I thinks it has something to do with webpack 4

SSR server forwarding cookies to apollo server?

This is a following issue from vuejs/apollo#400.

I am using vue-cli-plugin-ssr together with vue-cli-plugin-apollo and try to achieve proper SSR which prefetch data from the apollo server according to the authentication jwt from cookie.

My ssr server runs on localhost:8000 and apollo server runs on localhost:4000.

After using cookie instead of http request headers to pass the jwt to the ssr server, I can see the cookie is successfully passed to the ssr server:

image

But when the ssr server prefetches from the apollo server via its own http request, I can see it passes no cookie to it, therefore the prefetch is still no properly authenticated.

So now the problem is how to forward this cookie from the ssr server to the apollo server. The source code creating the ssr server here (https://github.com/Akryum/vue-cli-plugin-ssr/blob/master/lib/server.js#L4-L21) provides no interface to inject express middleware like cookie-parser, and I also couldn't find a way to export from here the express req object, which I believe is necessary in my entry-server.js file to customize the server-side ApolloProvider.

Any suggestions about that?

CSS being rendered as style tag on build

Everything works so great with this plugin! I just had a small question. When I run ssr:build all the css files inside my <style> tags are being rendered on the html as style tag and I also have them referenced as main.css. Is there a way to remove the style tag from the outputted html?

Here's the outputted html.
screenshot 2018-11-15 at 17 05 57

and here is my App.vue

<template>
  <div id="app">WebApp</div>
</template>

<script>
export default {
}
</script>

<style lang="scss">
  body {
    background: red;
  }
</style>

vuex entry-client.js initialstate

Hi,
I want to know why store state was not loaded in client side, and how to load the initial state .
For server side no problems, everything work thine :)
thanks for your help

Cannot use https

When I write in vue.config.js:

devServer: {
  https: true
}

it's don't work. How fix it?

Wrong cached response without query params

When rendering page which can have query params if has cached with some params, but page was requested with no query at all it returns wrong cached page. I guess it is not problem with your problem, i just cant make an issue for vue-server-renderer =(. Maybe we can find a way to fix this together.

ssr working with quasar

I am using the quasar plugin with ssr. Quasar plugin added { transpileDependencies: [/[\\/]node_modules[\\/]quasar-framework[\\/]/], } in vue.config.js since its source code in node_modules is ES6 and has lots of 'import's.

Without adding vue add @akryum/ssr it works fine; after adding ssr, the server side wepback does not know the quasar module should be transpiled and gives an error like:

(function (exports, require, module, __filename, __dirname) { import BtnMixin from './btn-mixin.js'
                                                                     ^^^^^^^^

SyntaxError: Unexpected identifier
    at new Script (vm.js:79:7)
    at createScript (vm.js:251:10)
    at Object.runInThisContext (vm.js:303:10)
    at Module._compile (internal/modules/cjs/loader.js:657:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at r (C:\Users\beep\git\c42v4\node_modules\vue-server-renderer\build.js:8346:16)
    at Object.quasar-framework/src/components/btn/QBtn.js (webpack:/external "quasar-framework/src/components/btn/QBtn.js":1:0)
    at __webpack_require__ (webpack/bootstrap:25:0)
    at Module../src/main.js (main.js:1317:101)
    at __webpack_require__ (webpack/bootstrap:25:0)
    at Module../src/entry-server.js (main.js:1220:63)

Is there a way to add transpileDependencies to server-side webpack?

How to redirect to another application with redirect router option ?

Hello,
I have a problem with redirect option in router.
I want redirect to another app, with another domain (like google.com).

export function createRouter() {
  return new Router({
    mode: 'history',
    base: '/',
    routes: [
      {
        path: '/',
        name: 'home',
        component: Home,
      },
      {
        path: '/about',
        name: 'about',
        component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
      },
      {
        path: '*',
        redirect: (to): any => {
            window.location.href = 'https://google.com' // for example
            // window is not interpreted on server side rendering, but I don't know another solution to redirect
        },
      },
    ],
  })
}

Do you know a good solution to redirect to another domain with server side AND client side ?

Thanks you very much !

Change location of generated entry files

Is it possible to change the location of where the client and server entry files are located? Currently yarn run ssr:serve looks for them in the root src directory, but I'd like mine elsewhere. Perhaps this can be configurable in the vue.config.js file?

Problem using ssr plugin and service worker plugin together

Hello,

First, really nice job with your plugin.

I just found a small issue when I use it it with service worker plugin. It works when I first load the page, but a the second time (when the page come from the cache) I have a blank page with this issue in the console :

Uncaught (in promise) DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.
    at Object.Zr [as appendChild] (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:39158)
    at g (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:41765)
    at h (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:41015)
    at _ (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:41851)
    at P (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:45087)
    at a.__patch__ (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:45447)
    at a.Ue.t._update (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:17525)
    at a.r (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:18420)
    at sn.get (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:20934)
    at new sn (http://localhost:8000/js/chunk-vendors.915e47f8.js:7:20852)

I'm using a fresh vue-cli app for the test, building it in production mode, just adding dynamic import on all routes (it was my main issue in ssr with vue). It work find without service worker plugin.

Do you think I did a mistake adding plugin, or is it a global issue ?

Does not work out of the box

Basically when I create fresh project with vue-cli, install pwa plugin, apollo plugin and ssr plugin, I expect that after yarn serve something will be visible for me in the front end. Instead I'm greeted with
{{{ renderResourceHints() }}} {{{ renderStyles() }}} {{{ renderState() }}} {{{ renderState({ contextKey: 'apolloState', windowKey: '__APOLLO_STATE__' }) }}} {{{ renderScripts() }}}
in my html and there's an error saying that #app element could not be found. Indeed there is no such element in public/index.html.
Do I need to follow additional setup steps? Why can't this vue-cli scaffolding work out of the box and present me some demo?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.