express-vue / vue-pronto

Rendering Engine for turning Vue files into Javascript Objects
Apache License 2.0
20 stars 12 forks source link

Using own vue configuration throws an error #170

Closed andoniabedul closed 9 months ago

andoniabedul commented 3 years ago

Hi Daniel.

First of all, thank you for all your work on this.

Description of Issue

I'm having this error, because I'm using my own Vue App strings with vue constructor in order to achieve some requirements.

Stack Trace / Console Log

Error: bundle export should be a function when using { runInNewContext: false }. at /Users/projects/moonshine2/node_modules/vue-server-renderer/build.dev.js:9381:17 at new Promise (<anonymous>) at /Users/projects/moonshine2/node_modules/vue-server-renderer/build.dev.js:9368:14 at Object.renderToString (/Users/projects/moonshine2/node_modules/vue-server-renderer/build.dev.js:9544:9) at Renderer.RenderToString (/Users/projects/moonshine2/node_modules/vue-pronto/lib/renderer/renderer-webpack.js:456:40)

This happen because the file utils/config.js have this code:

if (config && config.app && config.client) { return { app: config.app, server: config.app, client: config.client, }; }

On the server configuration we are assigning the app configuration, so it means a new context for Vue.

Additional Comments

If we put

if (config && config.app && config.client) { return { app: config.app, server: config.server, client: config.client, }; }

Works like a charm.

What do you think? Thank you in advance.

danielcherubini commented 3 years ago

Maybe we could go a step further and have some way to overload this...

Also you missed a null check for config.server in the initial if block..

andoniabedul commented 3 years ago

That's right, maybe we can do this:

/**

export function createApp(data) { const mergedData = Object.assign(App.data ? App.data() : {}, data); App.data = () => (mergedData)

const app = new Vue({ data, render: h => h(App), }); return { app }; }`;

const server = import { createApp } from "./app"; export default context => { return new Promise((resolve, reject) => { const { app } = createApp(context); resolve(app); }); };;

const client = import { createApp } from "./app"; const store = window.__INITIAL_STATE__; const { app } = createApp(store ? store : {}); app.$mount("#app"); ;

return { app: (config && config.app)? config.app : app, server: (config && config.server)? config.server : server, client: (config && config.client)? config.client : client, } };

The only problem I see here it's that the filepath should be "calculated" from configuration side.

Another option it's that config.app, config.server and config.client be functions that returns strings and not strings, to bind the filepath on each configuration.

But overload as you say with files it's a better solution in the long term.

What do you think? Regards.