How to convert Vue 2 web site to PWA wab app? - javascript

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

Related

How to implement Code Coverage in a cypress environment where NextJS is build while running the tests?

We would like to add code coverage to a setup where we use cypress and nextjs. In our cypress config we build nextJs using next() to mock the backend requests inside nextjs.
The cypress.config.ts looks like this:
async setupNodeEvents(on, config) {
...
const app = next({ dev, hostname, port }) // Build application in tests env
const handle = app.getRequestHandler()
await app.prepare().then(() => {
createServer(async (req, res) => { // Create server and start application
...
const parsedUrl = parse(req.url!, true)
await handle(req, res, parsedUrl)
...
}).listen(port, () => {
console.log(`> Ready on https://${hostname}:${port}`)
})
})
With this setup we can mock tests with nock while testing e2e. Quite similar to this setup: https://glebbahmutov.com/blog/mock-network-from-server/
The problem we are facing now is how to add Code Coverage to this application? We weren't able to instrument the code. Does anybody did this or can link a repo where this is done? Any tipps would help.

Vue Production issue with Express

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

How to call function from Nodejs running as windows service

I have created windows service from nodeJs application using node-windows package. Below is my code.
Main.js
var Service = require('node-windows').Service;
// Create a new service object
var svc = new Service({
name:'SNMPCollector',
description: 'SNMP collector',
script: './app.js',
nodeOptions: [
'--harmony',
'--max_old_space_size=4096'
]
//, workingDirectory: '...'
});
// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
svc.start();
});
svc.install();
/* svc.uninstall(); */
App.js
const { workerData, parentPort, isMainThread, Worker } = require('worker_threads')
var NodesList = ["xxxxxxx", "xxxxxxx"]
module.exports.run = function (Nodes) {
if (isMainThread) {
while (Nodes.length > 0) {
// my logic
})
}
}
}
Now when I run main.js, it creates a windows service and I can see the service running in services.msc
But, how can I call this run() method which is inside the running service, from any outside application? I couldn't find any solution for this, any help would be great.
You might consider simply importing your run function where you need it and run it there, then there is no need for a windows service or main.js - this assumes that "any outside application" is a Node application.
In your other application you you do the folowing:
const app = require('<path to App.js>');
app.run(someNodes)
For broader usage or if you do need to run it as a service, you could be starting an express (or another webserver) in your App.js with an endpoint that invokes your run function. Then from anywhere else you'll need to make an http call to that endpoint.
App.js
const express = require('express')
const bodyParser = require('body-parser')
const { workerData, parentPort, isMainThread, Worker } = require('worker_threads')
const app = express()
const port = 3000
var NodesList = ["xxxxxxx", "xxxxxxx"]
const run = function (Nodes) {
if (isMainThread) {
while (Nodes.length > 0) {
// my logic
})
}
}
}
app.use(bodyParser.json())
app.post('/', (req, res) => res.send(run(req.body)))
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
(Based off of example for express - https://expressjs.com/en/starter/hello-world.html)
You'll need to install both express and body-parser: $ npm install --save express body-parser from the directory of App.js.
From your other applications you will need to call the endpoint http://localhost:3000 with a POST request and the Nodes as a JSON array.
You can expose it on a port like the other answer mentions, though you'll want to make sure you don't expose it more broadly depending on the environment you're running in. There's a good answer here on ensuring the port is locked down.
As an alternative to exposing it on a port you can simply call the function by running the command in any other application:
node -e 'require("/somePathToYourJS/app").run()'
One concern is that app.js will now run at whatever permissions the calling application has. Although that can be resolved by running runas prior. More details here. But an example is:
runas /user:domainname\username "node -e 'require(^"/somePathToYourJS/app^").run()'"

Working Setup for Gulp, Connect, AngularUI Router and HTML5 Mode

I've tried and search a lot but I could not find any working solution for the following setup:
gulp
connect (https://github.com/senchalabs/connect)
connect-live-reload
angularJS
angularUI router with HTML5 mode on
The last option I tried was with connect-modrewrite, but that also didn't work. I think I got close by using https://github.com/expressjs/urlrouter but although it says, that is supports the express server functions, the setup descriped at angularUI router FAQ (https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode) doesn't work
app.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile('index.html', { root: __dirname });
});
I get the error, that send file doesn't work. I abandoned this way as I saw that the urlrouter project seams to be abandoned. So I tried to use connect-modrewrite and have this configuration now:
gulp.task('connect', ['sass', 'fonts'], function () {
var serveStatic = require('serve-static');
var serveIndex = require('serve-index');
var modRewrite = require('connect-modrewrite');
var app = require('connect')()
.use(require('connect-livereload')({port: 35729}))
.use(serveStatic('.tmp'))
.use(serveStatic('app'))
.use('/bower_components', serveStatic('bower_components'))
.use(serveIndex('app'))
.use(modRewrite(['^ app/index.html [L]']));
require('http').createServer(app)
.listen(9010)
.on('listening', function () {
console.log('Started connect web server on http://localhost:9010');
});
});
gulp.task('serve', ['connect', 'watch'], function () {
require('opn')('http://localhost:9010');
});
But what I get is just a "Cannot GET" when trying to load a page from a link directly. So what have I missed? How can I get the HTML5 mode working with connect or do I really have to use expressJS?

NodeJS: My node files have dependencies on variables in an other file

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
}

Categories