How to use node server with Vue Vite bundler - vue.js

Does someone know how to use Nodejs server instead of Vite own frontend dev server on the port 3000. I tried all command combinations like those below but with no success
vite
vite preview
vite preview --port:5000
Thanks
UPDATE Feb 8-th 2022
I have found a way. We have to add flag --watch to the vite build command, like: vite build --watch That way Vite will bundle only changes to the front-end and store it in the /dist folder but it will watch outside server like Nodejs. That way we can develop both front and back end file simultaneously and see the result immediately. We have to launch server file separately and serve index.html from there. If we use Nodejs and Express on the server side we also have to point default directory to be /dist because Vite will put bundled files there, like app.use(express.static(__dirname + '/dist'));. node will automatically serve index.html and other bundled files from this folder.

Basically you will set the middlewareMode to ssr on the server options:
const fs = require('fs')
const path = require('path')
const express = require('express')
const { createServer: createViteServer } = require('vite')
async function createServer() {
const app = express()
// Create Vite server in middleware mode. This disables Vite's own HTML
// serving logic and let the parent server take control.
//
// If you want to use Vite's own HTML serving logic (using Vite as
// a development middleware), using 'html' instead.
const vite = await createViteServer({
server: { middlewareMode: 'ssr' }
})
// use vite's connect instance as middleware
app.use(vite.middlewares)
app.use('*', async (req, res) => {
// serve index.html - we will tackle this next
})
app.listen(3000)
}
createServer()
This is explained in the doc: https://vitejs.dev/guide/ssr.html#setting-up-the-dev-server
Update for Vite 2.x
For Vite 2.x set server.middlewareMode to true and appType to custom:
// ...
const vite = await createViteServer({
server: { middlewareMode: true },
appType: 'custom'
})

Related

How to properly set up Vite, Express, Tailwind web app

Scenario:
I am making a basic web app using Vite & Tailwind. I set up my app as normal installing Vite, and Tailwind, and got everything running fine by testing for Tailwind css on localhost:5500.
Problem:
Once I added an Express server to the mix, and it sends the index.html in response to a 'GET' request # '/', I no longer get the compiled CSS from tailwind.
Is this an uncommon setup that should be troublesome?
You could possibly use a middleware like express.static
Example:
const express = require('express')
const app = express()
app.use(express.static(__dirname + '/public'))
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
})
In this example, the express.static middleware is used to serve the public directory, which is where the compiled CSS files from Tailwind will be located. Then the express server will send the index.html file in response to a GET request at the root '/' path.
Extra: Alternatively you can also use Webpack or Parcel , which can automatically handle the process of bundling and serving your CSS files

Handling endpoints APIs on client side instead of serverMiddleware in Nuxt

I'm on Nuxt 2.15.8 and trying to build an offline app with electron.js and prisma+sqlite for local DB.
In nuxt to hit a local endpoint there is a common way of using serverMiddleware and express like this:
// api.js that will be added to nuxt.config.js file as serverMiddleware
import express from 'express'
const app = express()
app.use(express.json())
export default {
path: '/api',
handler: app
}
which send endpoints beginning with api/ through app handler which I can use to access my BD (the common way to access sqlite3 DB is the same)
// added to api.js
import { PrismaClient } from '../../resources/prisma/client'
const prisma = new PrismaClient()
app.get(`/user/info`, async (req, res) => {
const result = await prisma.user.findUnique({
where: {
id: 1,
},
})
console.console.log(res);
res.json(result)
})
this will work fine on nuxt, also fine on nuxt-electron dev mode. but on built exe file serverMiddleware won't be called. So as it has be done by others (nuxt-electron accessing offline local DB) there must be a way to define endpoints on client side. any idea??
Updated:
as I changed my Nuxt-Electron boilerplate I could access serverMiddleware in exe file but it wont hit the endpoints yet!

Built Vue SPA not working when using "publicPath"

I set a public path in vue.config.js like
module.exports = {
publicPath: '/subpath'
};
it works fine when I start the devlopment server with npm run serve (vue-cli-service serve). The app becomes available at localhost:8080/subpath which is exactly what I want. It uses vue-router and at least in development it seems to work perfekt with the /subpath as publicPath.
Problem
I am using Express to serve the app files. Running npm run build the app will be built and stored to ./dist folder (default output folder).
// simplified server.js
app.use(express.static(path.join(__dirname, '/dist')));
app.get('/', (req, res, next) => {
res.sendfile('./dist/index.html');
});
After starting my express server and visiting my browser at localhost:<port>/subpath or localhost:<port> it can't find the necessary files.
// EXAMPLE FROM BROWSER CONSOLE
GET http://localhost:5050/subpath/js/app.6c6daa90.js net::ERR_ABORTED 404 (Not Found)
Which somehow looks obvious to me but I don't know how to set the express server correctly to respect the publicPath setting . Maybe there is a different approach ?
Attempt #1
I made a little change in my express server.js
// app.use(express.static(path.join(__dirname, '/dist')));
/* NEW */
app.use('/subpath', express.static(path.join(__dirname, '/dist')));
This way it should serve the static files from the /dist folder when requested with /subpath/app.js
Result
From Browser console when requesting localhost:<port>/subpath or localhost:<port>
Refused to load the font 'data:application/font-woff2;base64,<omitted>' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'font-src' was not explicitly set, so 'default-src' is used as a fallback.
Refused to load the image 'http://localhost:5050/favicon.ico' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
I played around with express.static and this combination seems to work for me
const path = require('path');
const express = require('express');
const history = require('connect-history-api-fallback');
const app = express();
app.use(history());
app.use(express.static(path.join(__dirname, '/dist')));
app.use('/subpath', express.static(path.join(__dirname, '/dist')));
const listener = app.listen(5050, () => {
console.log(`Open http://localhost:${port} in your browser`);
});
Sidenote : Adding connect-history-api-fallback was not required to solve the initial problem but is required for vue-router to work properly when in history mode.

Multiplayer game in Phaser - the "script" element could not be loaded

How do you configure the server for this template ? => https://github.com/nkholski/phaser3-es6-webpack
I'm trying to do it by following this tutorial => https://gamedevacademy.org/create-a-basic-multiplayer-game-in-phaser-3-with-socket-io-part-1/?a=13
I added two dependencies: nodemon and express.
I created the server.js file with the server configuration.
const express = require('express')
const app = express()
const server = require('http').Server(app)
const path = require('path')
app.get('/', function(req, res) {
res.sendFile(path.resolve('index.html'))
})
server.listen(8081, function() {
console.log(`Listening on ${server.address().port}`)
})
In the package.json file, I added a command to start the server:
nodemon src/server/server.js
The server starts correctly but the indicated html file can not read the scripts (" The load failed for the "script" element with the source vendor.js and app.js").
Project structure: https://i.imgur.com/r4QcXoJ.png
I solved this problem by indicate to the folder in which the scripts are located .
In my case it was a folder called 'dev'.
Adding this line solved the problem:
app.use('/dev', express.static('dev'))

Use Express.js in an existing Nuxt.js project

I have a project built with Nuxt.js and I want to use express to be able to report bugsnag errors on my asyncData method etc.
How would I go to import that? I suppose is not as simple as npm install express --save.
I already have an api written in PHP so I would not use that as an api or anything else.
Is it overkill? Or is it a necessary evil? :D
To start using Express with an existing Nuxt project, you'll need to set up a simple server.js file that sets up your Express server and adds your Nuxt application as middleware. The only slight complication is setting it up to auto-rebuild in development. Here's a quick example server.js file that pulls in Nuxt and handles building when not in production.
const { Nuxt, Builder } = require('nuxt');
const app = require('express')();
// We instantiate Nuxt.js with the options
const isProd = process.env.NODE_ENV === 'production';
const config = require('./nuxt.config.js');
config.dev = !(isProd);
const nuxt = new Nuxt(config);
// No build in production
if (!isProd) {
const builder = new Builder(nuxt);
builder.build();
}
app.use(nuxt.render);
app.listen(3000);
console.log('Server is listening on http://localhost:3000');
You can then incorporate bugsnag as you normally would in express, I assume by requiring it and including it as middleware.
You dont need express to handle errors in asyncData. To handle errors in asyncData/fetch on ssr you just need to hook into render:errorMiddleware. See sentry plugin for nuxt for example
But it would only catch errors that happens on SSR. On client unfortunately that wont catch anything ( as well as express wont do anything for client). There is a bug for this in nuxt see here