I'm trying to install SSR on my current Vue app, and for this I'm using the vue-plugin-ssr extension. I want to run it with express, so I created a new file called server.mjs and have this:
import express from "express";
import { createServer as createViteServer } from "vite";
import { renderPage } from "vite-plugin-ssr";
async function createServer() {
const app = express();
// Create Vite server in middleware mode and configure the app type as
// 'custom', disabling Vite's own HTML serving logic so parent server
// can take control
const vite = await createViteServer({
server: { middlewareMode: true },
appType: "custom",
});
// use vite's connect instance as middleware
// if you use your own express router (express.Router()), you should use router.use
app.use(vite.middlewares);
app.get("*", async (req, res) => {
// `renderPage()` can also be used in serverless environments such as
// Cloudflare Workers and Vercel
const { httpResponse } = await renderPage({ url: req.url });
res.send(httpResponse.body);
});
app.listen(3000);
}
createServer();
So this actually works for dev, when I run node server.mjs, but neither client or server folder has an index.html file, so how can I run this on production actually?
Only what I'm doing is to set the folder on nginx to path/dist/client, do I need to do something else?
btw as a response on production I have only 403 forbbiden.
You need to run the client and ssr build process as demonstrated in Vite's documentation and then:
Move the creation and all usage of the vite dev server behind dev-only
conditional branches, then add static file serving middlewares to
serve files from dist/client
Related
I have checked PWA function when use vue 3 but there aren't in vue 2.
so if you have good idea to convert from vue 2 project to pwa, please share.
Thanks.
I found answer for my question. I will share it for all developers.
First, I have done follow this this
vue/cli-plugin-pwa
Second:
make registerServiceWorker.js file with this code:
/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
console.log(
'App is being served from cache by a service worker.\n'
)
},
registered () {
console.log('Service worker has been registered.')
},
cached () {
console.log('Content has been cached for offline use.')
},
updatefound () {
console.log('New content is downloading.')
},
updated () {
console.log('New content is available; please refresh.')
},
offline () {
console.log('No internet connection found. App is running in offline mode.')
},
error (error) {
console.error('Error during service worker registration:', error)
}
})
}
Third:
make service-worker.js:
// inside src/service-worker.js
// define a prefix for your cache names. It is recommended to use your project name
workbox.core.setCacheNameDetails({prefix: "simple-vue-project"});
// Start of Precaching##########################
// __precacheManifest is the list of resources you want to precache. This list will be generated and imported automatically by workbox during build time
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
// End of Precaching############################
// Start of CachFirst Strategy##################
// all the api request which matchs the following pattern will use CacheFirst strategy for caching
workbox.routing.registerRoute(
/http:\/\/get\.geojs\.io\/v1\/ip\/country\.json/,
new workbox.strategies.CacheFirst()
);
// End of CachFirst Strategy####################
there is a Vue.js plugin, here.
if not :
Create a services worker, you can introduce to it here
add webmanifest or manifest.json of your choice, read here
Add express to your project as depencency
create server.js like file, and serve the built Vue App from the server with express
// server.js ex:
const express = require('express');
const path = require('path');
const port = process.env.PORT || 8080;
const app = express();
app.use(express.static(__dirname));
app.use(express.static(path.join(__dirname, 'build')));
app.get('/ping', function (req, res) {
return res.send('ping');
});
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html')); //serving build folder
});
app.listen(port);
The modern #vue/cli provides you the option to turn on PWA while scaffolding both Vue 2 as well as Vue 3 projects. Check out this documentation.
If you have already created the project, CLI offers a new functionality called Vue UI. Simply type vue ui in the cmd and it should open up Vue UI where you can reconfigure your project using graphical interface.
If you are interested in learning Vue JS check out these courses - Complete Vue JS Course, Vue 3 Essentials
I'm writing a simple nodejs app that I want to pack using pkg. The app will give to the user the ability to upload some files that after are processed from the embedded server script will be sended back to the vue client app.As I know, I need to add multipart/form-data to the vuejs form?Since I'm new to express, what's the best way to handle multiple files upload?Since pkg will pack the app to work with a virtual filesystem, how I can create a temp dir in the folder where the app is executed when the files are uploaded?I've seen the provided example on the express website but it uses some dependencies and I don't want to have too many libraries for my project.
This is the basic code I have at the moment
const http = require('http');
const express = require('express');
const path = require('path');
const app = express();
class eCrypt {
constructor(){
this.app = app;
this.assets = path.format({dir: __dirname, base: 'assets/'})
}
async init(){
this.app.use(express.static())
this.app.use(express.json());
this.app.use(express.urlencoded({
extended: true
}));
this.app.get('/', (req, res) => {
res.sendFile('index.html', {root: this.assets});
});
this.app.post('/compressEncrypt', (req, res) => {
//here I need to manage uploaded files
});
}
async encryptAndCompress(data){
//in this method I'm processing the files
}
}
I have different routes in my node js application and i have to use socket.io in every route to make my node and react js application realtime. But, i have the below structure of my node js application.
router.js
const express = require('express');
const router = express.Router();
const worksheetController = require('../controllers/worksheet')
const attendenceController = require('../controllers/attendence')
router.route('/worksheets')
.get(
worksheetController.getWorksheet
)
.post(
worksheetController.validateWorksheet,
worksheetController.addWorksheet,
attendenceController.markAttendence
)
router.route('/attendances')
.get(
attendenceController.getAttendance
)
module.exports = router;
server.js
const express = require('express');
const router = require('./router');
const app = express();
app.use('/api', router);
app.listen('5000', () => {
console.log('Listening on port');
});
module.exports = app;
So, I want to know
1) Should i need to use http module to create a server, if i need to use socket.io.
2) How can i use socket.io for diffrent routes.
I found posts that match's to my question on stackoverflow, which is this, this and this. But i don't think, that works for me. So please help me.
You can use http module or other module in document of socket.io for to use socket.io
I don't sure your idea. But when you want implement socket.io. I think you should run another node app. (Meaning you have 2 nodejs app. 1 for node http normally and 1 for socket.io app). After you can use path option when init socket.io app https://socket.io/docs/server-api/#new-Server-httpServer-options. Because when you deploy to production. You should run your socket.io app with beside of proxy serve (ex: nginx). Socket.io basically support multi transport and protocol. So if use with http restful. How about config your connection mapping from nginx to socket.io app, how you setup error handler ?.
In your case:
+ Create new file socket.js:
// socket.js
var http = require('http')
var socket_io = require('socket.io')
function init_socket(app) {
const server = http.Server(app)
const io = socket_io(server, { path: 'your-path-want-for-socket-io' }) // default: /socket.io/
}
import {init_socket} from 'socket.js'
init_socket(app)
I'm running a basic static server with Express in a separate server file.
In my Gulpfile, I use nodemon to run the server file and then pass its address to browsersync to proxy through.
When the browser navigates to the webpage, I am presented with an infinitely loading page which is "Waiting for localhost:3000". The website loads instantly after refreshing the page.
Below are my express server and gulpfile:
// server.js
import express from 'express';
const app = express();
app.use(express.static('build'));
app.listen(4000);
// gulpfile.babel.js
import browser from 'browser-sync';
import gulp from 'gulp';
import plugins from 'gulp-load-plugins';
const $ = plugins();
gulp.task('default',
gulp.series(server, browsersync, watch));
// Start the server with nodemon
function server(done) {
return $.nodemon({
script: 'server.js',
exec: 'babel-node',
})
.on('start', () => {
done();
});
}
// Proxy the server with browsersync
function browsersync(done) {
browser.init({
proxy: 'http://localhost:4000',
});
done();
}
// Watch for file changes
function watch() {
gulp.watch('scripts/**/*.js').on('change', gulp.series(browser.reload));
}
This issue was unfortunately caused by babel-node.
I am creating an app with nodejs. In the app, I have a app.js script that is the entrypoint that initializes both the app, as an expressjs app, and the http server that I use.
Just to clarify: modules here are not npm modules, they are my own files. I've written the app in modules. They are just seperate script files used by require()-ing them.
This app has several modules that a main module handler initializes. It reads the contents of a folder, which contains my own modules, and then by convention call the .initialize on each module after running a require() call on the filenames without the .js extension.
However, I have 1 module that needs the app variable to create an endpoint, and 1 module that needs the httpServer variable to create a web socket. Both of these are instansiated in app.js.
Seeing as I don't know what kind of modules will be in the folder, I don't really want to send app and httpServer to every module if they are just needed by 1 module each. Something like dependency injection would fit nice, but is that possible without to much overhead?
Right now I just temporarily added app and httpServer to the GLOBAL object.
What I usually do is have app.js export app so that modules elsewhere in my app can require it directly rather than having to deal with passing it around everywhere. I also slightly modify app.js so that it won't "listen" if it is required as a module that way later on if i decide to wrap it with another app, I can with minimal changes. This is not important to your question, I just find it give me more control when unit testing. All you really need from the code below is module.exports = app
'use strict';
var express = require('express'),
app = express(),
config = require('config'),
pkg = require('./package.json');
// trust reverse proxies
app.enable('trust proxy');
app.set('version', pkg.version);
module.exports = app; // <--- *** important ***
if (app.get('env') !== 'production') {
app.set('debug', true);
}
// calling app.boot bootstraps the app
app.boot = function (skipStart) { // skipStart var makes it easy to unit test without actually starting the server
// add middleware
require('./middleware/');
// setup models
app.set('models', require('./models'));
// setup routes
require('./routes/');
// wait for a dbconnection to start listening
app.on('dbopen', function () {
// setup hosting params
if (!skipStart) {
let server = app.listen(config.port, function () {
app.emit('started');
console.log('Web Server listening at: http://%s:%s', server.address().address, server.address().port);
// mail server interceptor for dev
if (app.get('env') !== 'production') {
// Config smtp server for dev
let SMTPServer = require('smtp-server').SMTPServer,
mailServer = new SMTPServer({
secure: false,
disabledCommands: ['STARTTLS'],
onData: function(stream, session, callback){
stream.pipe(process.stdout); // print message to console
stream.on('end', callback);
},
onAuth: function (auth, session, callback) {
callback(null, {user: 1, data: {}});
}
});
// Start smtp server
mailServer.listen(1025, '0.0.0.0');
} else {
// start agenda jobs only on production
require('./jobs.js');
console.log('Agenda Jobs Running.');
}
});
} else {
app.emit('booted');
}
});
};
// If this is the main module, run boot.
if (require.main === module) {
// move all of this to next tick so we can require app.js in other modules safely.
process.nextTick(app.boot);
}
Suppose you want to initialize 2 file from main app.js
app.js
var socketIni = require('./socketini.js');//You have to pass server
var xyz = require('./xyz.js')//you have to pass app
var app = express();
var server=http.createServer(app);
socketIni(server);
xyz(app);
socketini.js
module.exports = function(server){
//your socket initilize goes here
var io = require('socket.io').listen(server);
}
xyz.js
module.exports = function(app){
//you can access app here
}