How do I configure vite.config for production when using the 'server' field with HTTPS for development? - vite

I enabled https in vite.config because I need it for development. But I don't know how to use this field in production since I'm going to use Nginx and let's encrypt. Do I need to check if I'm in development mode with an environment variable?
I'm using vite with SvelteKit.
Here's my vite.config
import { sveltekit } from '#sveltejs/kit/vite';
import { defineConfig, loadEnv } from 'vite';
import fs from 'fs';
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd(), '');
return {
plugins: [sveltekit()],
server: {
https: {
key: fs.readFileSync(env.HTTPS_KEY),
cert: fs.readFileSync(env.HTTPS_CERTS)
},
proxy: {}
}
};
});

If you are looking for production solution I'd suggest using a process manager like pm2
You can build a server using standard config and running vite build and configure pm2 with ecosystem file to use the compiled project

Related

How to setup a WebSocket server inside SvelteKit using the ws package?

I'm trying to create a simple WebSocket server that will run in a SvelteKit application. I found this tutorial online which shows how to do it using Socket.io, however I would like to use the ws module instead.
This is the vite.config.ts file that I've come up with so far:
import type { UserConfig } from 'vite';
import { sveltekit } from '#sveltejs/kit/vite';
import { WebSocketServer } from "ws";
const webSocketServer = {
name: "webSocketServer",
configureServer: () => {
const webSocketServer = new WebSocketServer({
port: 8080
});
webSocketServer.on("connection", (socket, request) => {
socket.on("message", (data, isBinary) => {
console.log(`Recieved ${data}`);
});
socket.send("test from server");
});
}
}
const config: UserConfig = {
plugins: [sveltekit(), webSocketServer]
};
export default config;
I can connect to this WebSocket server from the frontend (in +page.svelte, for example) and send messages between them.
But every time I make a change to my server's code and save the file, I get an error saying that "there's already something listening on port 8080" and my Vite dev server terminates. If I then start back up my Vite dev server by running npm run dev then it will all work fine again, until I make any change to the WebSocket server code and save the file, and then the same thing will repeat.
I would rather not have to re-start my Vite dev server every time I make a change to my WebSocket server's code. If possible, I would rather Vite automatically shut down my old webSocket server to make room for the new one before booting it up each time so that they won't conflict.
The tutorial I linked above shows this code snippet:
import adapter from '#sveltejs/adapter-node'
import preprocess from 'svelte-preprocess'
import { Server } from 'socket.io'
const webSocketServer = {
name: 'webSocketServer',
configureServer(server) {
const io = new Server(server.httpServer)
io.on('connection', (socket) => {
socket.emit('eventFromServer', 'Hello, World đź‘‹')
})
},
}
/** #type {import('#sveltejs/kit').Config} */
const config = {
preprocess: preprocess(),
kit: {
adapter: adapter(),
vite: {
plugins: [webSocketServer],
},
},
}
export default config
This snippet is using an old SvelteKit version where Vite configuration was done inside the svelte.config.js file, so the layout is a little different, but it seems they're simply spinning up their Socket.io server directly inside the configureServer method just like I am, but they're tapping into the existing Vite http server instead of creating a new one like I am. I tried doing this and I still get the same problem. Every time I try httpServer.listen(8080); on Vite's http server I'm told that the server was already listening on a port and the dev server terminates. I also tried manually creating an http server using require("http").createServer() and using that, but (unsurprisingly) that also did not work and acted identically to my initial attempt shown at the beginning of this question.
The tutorial seems to be booting up a Socket.io server the same way I'm trying to boot up mine, but they don't seem to be running into any conflicts like I am. I checked Socket.io's documentation to see if perhaps the Server constructor has a built-in failsafe to make sure it doesn't listen on a port if it's already listening on that port (and avoid creating the error), but the docs didn't give any information in that regard, so I'm still unsure as to what's going on there.
Is there any way to do what I'm trying to do, or am I going about this entirely the wrong way? I can't find hardly any information about this anywhere on the internet.
And also, what's going on in the Socket.io example that allows it to work where mine won't? Is Socket.io doing something special?
Here's my attempt at using Vite's built-in http server. This behaves the same as my other attempts.
vite.config.ts
import type { UserConfig } from 'vite';
import { sveltekit } from '#sveltejs/kit/vite';
import { WebSocketServer } from "ws";
const webSocketServer = {
name: "webSocketServer",
configureServer: (server: any) => {
const httpServer = server.httpServer;
const webSocketServer = new WebSocketServer({
noServer: true
});
webSocketServer.on("connection", (socket, request) => {
socket.on("message", (data, isBinary) => {
console.log(`Recieved ${data}`);
});
socket.send("hi c:");
});
httpServer.on("upgrade", (request: any, socket: any, head: any) => {
webSocketServer.handleUpgrade(request, socket, head, socket => {
webSocketServer.emit("connection", socket, request);
});
});
httpServer.listen(8080);
}
}
const config: UserConfig = {
plugins: [sveltekit(), webSocketServer]
};
export default config;
ws supports initialising with an existing server like socket.io
Don't store the application logic in the vite/svelte config, as it will be needed for the production build when vite is not available (I'm not familiar with sveltekit though so maybe it does some magic?). Create a standalone file for the ws setup:
import { WebSocketServer } from "ws";
export const configureServer = (server) => {
const webSocketServer = new WebSocketServer({
server: server.httpServer,
});
webSocketServer.on("connection", (socket, request) => {
socket.on("message", (data, isBinary) => {
console.log(`Recieved ${data}`);
});
socket.send("test from server");
});
}
export const webSocketServer = {
name: "webSocketServer",
configureServer,
}
Then you should be able to use your version of webSocketServer like the socket.io example as they both attach to the '#sveltejs/adapter-node' server.
import adapter from '#sveltejs/adapter-node'
import { webSocketServer } from './sockets.js';
/** #type {import('#sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter(),
vite: {
plugins: [webSocketServer],
},
},
}
export default config
configureServer can now be reused when you setup the custom server for production.

How to restart the SSR script in Vite?

I am using the Dev server provided by Vite. It provides a method to run the SSR code using the ssrLoadModule method on the dev server instance. This how I use it:
const vite = await createServer({
mode: 'development',
appType: 'custom',
root: path.join(process.cwd(), 'server'),
build: {
ssr: 'server/main.ts'
},
server: {
hmr: true
},
ssr: {
format: 'cjs',
target: 'node'
},
plugins: []
});
const loadedModule = await vite.ssrLoadModule('server/main.ts');
Here the above file runs the server/main.ts file and also imports another file user.ts. The main.ts file creates an Express app/server that listens on port 3000 which exposes CRUD APIs for User entity.
My question is how do I restart after the SSR script (main.ts) or any of its import dependencies get modified? I don't care if it is a full restart or HMR. Note, the HMR works for frontend code but not for backend SSR code.

How to set axios base url in nuxt config using gitlab variables?

I have a nuxt application which uses following configuration (nuxt.config.js)
axios: {
/* set API_URL environment variable to configure access to the API
*/
baseURL: process.env.API_URL || 'http://localhost:5000',
redirectError: {
401: '/Identity/Account/Login',
404: '/notfound'
}
},
I want to set the API_URL using gitlab variables(settings => CI/CD => Variables) but it doesn't seem to pick it

Proxy in development mode of React won't redirect

I'm building an app with create-react-app.
I have local Apache server running on port 80 to execute my backend API PHP scripts.
I have added
"proxy": "http://localhost:80" to my package.json,
but on this axios requests:
getAllCategories = () => {
const url = process.env.PUBLIC_URL+`/api/api/categories/categories.php`;
axios.get(url)
.then(res => {
const categories = res.data.data;
this.setState({ categories });
}).catch(err => {
console.log('Axios fetch error:',err);
})
}
My request are directed to
Request URL: http://localhost:3000/api/api/categories/categories.php
according to Chrome Devtools and I'm not getting the data required.
In the build mode on remote server everything works fine with those paths indicated.
How can I configure proxy in dev mode to access my API files?
Have you tired path like this?
axios.get(`/api/api/categories/categories.php`)
...
If you are using create-react-app install http-proxy-middleware as a dev dependency and in your src folder create a file called setupProxy.js (it must be spelt exactly like that).
In that file:
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/api', { target: 'http://localhost:80' }));
};
You will need to restart the app for it to take effect.
Your api calls should not need the process.env

Use Nuxt programmatically without builder

I am using nuxt programmatically inside express with nuxt.render middleware like below
const { Nuxt, Builder } = require('nuxt')
const app = require('express')()
const api = require('../api')
app.use('/api', api)
let config = require('../nuxt.config.js')
config.dev = !(process.env.NODE_ENV === 'production')
// Init Nuxt.js
const nuxt = new Nuxt(config)
app.use(nuxt.render)
async function start() {
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
// Listen the server
app.listen(port, host)
console.log('Server listening on ' + host + ':' + port)
}
start()
When I am developing the server api routes and make some changes to the server side api files and restart the server, the whole nuxt project builds everytime which takes too much time. This is inconvenient as there were no changes in the nuxt files, only changes in the api route files.
So after building once, I comment out the following lines:
if (config.dev) {
// const builder = new Builder(nuxt)
// await builder.build()
}
I then restart the server which of course does not start the nuxt builder. But then I am now not able to access nuxt on browser. The server api routes work but the nuxt page routes just show "Nuxt loading…" screen.
How can I use nuxt app in development mode without building it everytime?
It might be a valid use case, sometimes one doesn't want to use two servers for a very small api/ui pair. What I would suggest is also to have a detached mode which works through nuxt/proxy and you could run it whenever you are doing dev work. In detached mode your nuxt works separately and api runs also separately and nuxt imitates above setup via `nuxt/proxy. It's very easy to setup via adding smth like this in nuxt config
modules: [
['#nuxtjs/proxy', { "/api/": { target: 'http://localhost:888/api'} }]
]
In prod you could run as before.
You can use build.parallel, build.cache, and build.hardSource. This will dramatically speed up your build times after the initial build.
I do not recommend this for production builds though. This is how I have it in my code:
nuxt.config.js:
const isDev = process.env.NODE_ENV === "development";
module.exports = {
// ...
build: {
parallel: isDev,
cache: isDev,
hardSource: isDev
},
// ...
};
And in the package.json I set the NODE_ENV to production for the build script:
"scripts": {
"build": "NODE_ENV=production nuxt build"
}
P.S.: You might also need to set build.publicPath for the dev builds.

Resources