Is there any way to deploy a VueJS app locally without having it limited by the browser?
I want the user to be able to call the application from the command line, for example app_name --port 6000, and then be able to load up the app from http://127.0.0.1:6000 or any other port they selected. The important thing is, the Vue App must be able to import and use native NodeJS modules, such as fs and zeromq.
Vuejs code must run in a browser environment in which you don't have access to your hardware. So basically you have three options to achieve this:
1. Use Electron
Electron gives you a chromium instance in which your UI (Vuejs) code can run and a separate process in which you can have access to your hardware using nodejs.
2. Create a simple http server with node
In this case you need to create a server with nodejs. For example you can create a file named server.js like this:
const http = require('http');
const fs = require('fs')
http.createServer((req, res) => {
// Do something with fs
const data = fs.readFileSync('path/to/some/file');
// return back the data with http
http.writeHead(200, {ContentType: 'text/plain'})
http.write(data);
}).listen(8000)
And fetch the data in your Vuejs app with http like this:
export default {
data () {
return {
myData: null
}
},
methods: {
onSomeAction () {
const {data} = await axios.get('localhost:8000')
this.myData = data;
}
}
}
Now in your package.json you can put this to run both when npm serve is called:
...
"scripts": {
...
"serve": "node server.js & vue-cli-service serve"
}
3. Use Nuxt
In case you need to do something with your hardware ONCE, and BEFORE the render you can use Nuxt to access the hardware before rendering the Vuejs app and handing it over to your browser.
Related
IMPORTANT: If you want to help me or you have the same issue discuss it here: https://github.com/vercel/pkg/discussions/1580
I'm writing a node.js app which downloads repositories from GitHub at runtime. These contain javascript files which I require at runtime. But now I want to package my code into an executable using pkg, but I read that I can't just simply require packages at runtime using pkg. So my question is: How can I require these files at runtime? I'ts important for me to access its exported function, as I need to pass variables into it. Here is an example dynamically downloaded file:
module.exports = function PluginServerSideRenderer (app, dir, config) {
/*
*
* app is the express app
* dir is the current-working-directory of the server or mostly the root
* config is the config.json file as a javascript object
*
*/
app.get('/__plugin-template__', (req, res) => {
// Uncomment if user must be logged in to access this page
// if (req.session.loggedin !== true) return res.redirect('/login') // Login Check
res.send('Hello World from the Plugin-Template!')
})
}
Normally I would use this code to import these files:
// Plugin Server Side Renderer
const plugindirx = path.join(dir, '.tvt', 'plugins')
const files = fs.readdirSync(plugindirx)
const activeplugins = JSON.parse(fs.readFileSync(path.join(plugindirx, 'active.json'), 'utf8').toString())
for (const plugindiroutoffiles of files) {
if (plugindiroutoffiles === 'active.json') continue
if (!(activeplugins[genFileName(plugindiroutoffiles)])) continue
const filesx = fs.readdirSync(path.join(plugindirx, plugindiroutoffiles))
const ssrfile = path.join(plugindirx, plugindiroutoffiles, filesx[0], 'serverside.js')
require(ssrfile)(app, dir, config, Logger, IServConfig)
}
// End Plugin Server Side Renderer
If you want to use a routes.json file for custom json-server routing from the command line, you can do so with the --routes option like this:
json-server --watch db/db.json --routes db/routes.json --port 9001
However, I don't see a similar option anywhere if you are starting your json-server from a javascript file. I am looking for something like this:
const server = jsonServer.create();
const router = jsonServer.router('db.json')
server.use(router)
// This part is what I am looking for
const customRouter = jsonServer.customRouter('routes.json')
server.use(customRouter)
server.listen(3000, () => {
console.log('JSON Server is running')
})
I know we can do explicit custom routing in javascript but that is verbose and I would prefer to just reference a routes.json file. Is this possible?
One will need to use the rewriter api that the json-server provides.
Example from the documentation:
// Add this before server.use(router)
server.use(jsonServer.rewriter({
'/api/*': '/$1',
'/blog/:resource/:id/show': '/:resource/:id'
}))
What is the right way to configure/enable an Elastic APM agent in a Nuxtjs project?
I referred this documentation for a custom NodeJS app. The key takeaway was:
It’s important that the agent is started before you require any other
modules in your Node.js application - i.e. before http and before your
router etc.
I added the following snippet in nuxt.config.js, but the APM agent is not started or working. I do not see any errors in the app logs.
var apm = require('elastic-apm-node').start({
serviceName: 'nuxt-app',
serverUrl: 'http://ELK_APM_SERVER:8200'
})
Is there any other way to do this?
We managed to get this working using a custom Nuxt module which explicitly requires the Node modules to instrument after it has initiated the APM module.
modules/elastic-apm.js:
const apm = require('elastic-apm-node');
const defu = require('defu');
module.exports = function() {
this.nuxt.hook('ready', async(nuxt) => {
const runtimeConfig = defu(nuxt.options.privateRuntimeConfig, nuxt.options.publicRuntimeConfig);
const config = (runtimeConfig.elastic && runtimeConfig.elastic.apm) || {};
if (!config.serverUrl) {
return;
}
if (!apm.isStarted()) {
await apm.start(config);
// Now explicitly require the modules we want APM to hook into, as otherwise
// they would not be instrumented.
//
// Docs: https://www.elastic.co/guide/en/apm/agent/nodejs/master/custom-stack.html
// Modules: https://github.com/elastic/apm-agent-nodejs/tree/master/lib/instrumentation/modules
require('http');
require('http2');
require('https');
}
});
}
nuxt.config.js:
module.exports = {
// Must be in modules, not buildModules
modules: ['~/modules/elastic-apm'],
publicRuntimeConfig: {
elastic: {
apm: {
serverUrl: process.env.ELASTIC_APM_SERVER_URL,
serviceName: 'my-nuxt-app',
usePathAsTransactionName: true // prevent "GET unknown route" transactions
}
}
}
};
All the answers are outdated and from beginning incorrect (17.02.2022)
To make it work follow these steps:
1.) Create a nodeApm.js in your root dir with the following content:
const nodeApm = require('elastic-apm-node')
if (!nodeApm.isStarted()) {
nodeApm.start()
}
2.) Use environment variables to store your config. For example:
ELASTIC_APM_SERVICE_NAME=NUXT_PRODUCTION
ELASTIC_APM_SECRET_TOKEN=yoursecrettokenhere
3.) Edit your package.json
"scripts": {
// if you want apm also on dev to test, add it also here
"dev": "node -r ./nodeApm.js node_modules/nuxt/bin/nuxt",
...
"start": "node -r ./nodeApm.js node_modules/nuxt/bin/nuxt start",
...
! Be awere that in ~2022 the node_modules bin folder has lost the "." in the directory name
! In all othere anwsers people forget the start parameter at the end
"start": "node -r ./nodeApm.js node_modules/nuxt/bin/nuxt start",
Based on what I've seen it looks like there isn't a "right" way to do this with the stock nuxt command line application. The problem seems to be that while nuxt.config.js is the first time a user has a chance to add some javascript, that the nuxt command line application bootstraps the Node's HTTP frameworks before this config file is required. This means the elastic agent (or any APM agent) doesn't have a chance to hook into the modules.
The current recommendations from the Nuxt team appears to be
Invoke nuxt manually via -r
{
"scripts": {
"start": "node -r elastic-apm-node node_modules/nuxt/.bin/nuxt"
}
}
Skip nuxt and use NuxtJS programmatically as a middleware in your framework of choice
const { loadNuxt } = require('nuxt')
const nuxtPromise = loadNuxt('start')
app.use((req, res) => { nuxtPromise.then(nuxt => nuxt.render(req, res)) })
Based on Alan Storm answer (from Nuxt team) I made it work but with a little modification:
I created a file named nodeApm.js where I added the following code:
const nodeApm = require('elastic-apm-node')
if (!nodeApm.isStarted()) { ... // configuration magic }
In script sections I added:
"start": "node -r ./nodeApm.js node_modules/nuxt/.bin/nuxt"
I am using ElectronJS in order to build a Desktop Application.
However, I would like to auto-update the changes in the code and see the result immediately.
For example, if I am creating a WebServer with express on localhost, alyways when i update the browser, i get the changes.
On the Go Live extension on VSCode, this happens automatically after CRTL + Save
Does there exist any similar functionality for electron?
My current alternative is to close the whole electron application and start it with npm start again...
Thanks.
use electron-hot-reload package get hotreload
import { mainReloader, rendererReloader } from 'electron-hot-reload';
import { app } from 'electron';
import path from 'path';
const mainFile = path.join(app.getAppPath(), 'dist', 'main.js');
const rendererFile = path.join(app.getAppPath(), 'dist', 'renderer.js');
mainReloader(mainFile, undefined, (error, path) => {
console.log("It is a main's process hook!");
});
rendererReloader(rendererFile, undefined, (error, path) => {
console.log("It is a renderer's process hook!");
});
Example project with configuration
https://github.com/valentineus/electron-hot-reload/tree/6feca4b65b78c674aea096906ecd7b46abebc36a/example/application/src
Found it on my own.
As #ShioT mentioned, this is called hot reload / live reload.
electron-reload | npm package
https://www.npmjs.com/package/electron-reload
Frontend
require('electron-reload')(__dirname);
Backend (hard reset)
const path = require('path')
require('electron-reload')(__dirname, {
// note that this path can vary
electron: path.join(__dirname, 'node_modules', '.bin', 'electron')
});
The simplest way I've found is using electron-reloader, after installation, just paste the following code at the top of the app entry file, and you're all set:
const { app } = require('electron')
app.isPackaged || require('electron-reloader')(module)
I've built a small internal app using React and Next.js. I'm using an .env file per their instructions with my API key and secret.
My api/hello.js file does a simple
export default async (req, res) => {
const data = await fetch(`https://api.trello.com/1/lists/abc123/cards?key=${process.env.KEY}&token=${process.env.TOKEN}`)
And yet when I build and deploy my app to production, inspect the JS files, and search "trello" in them, I'm able to see the key and secret right there.
Not quite sure what I'm doing incorrectly here. Would love some help. Thanks!
My next.config.js file:
module.exports = {
env: {
KEY: process.env.KEY,
TOKEN: process.env.TOKEN
},
}
Since Next.js 9.4 you can add .env file and add secrets there without third-party packages like dotenv.
next.config.js
require('dotenv').config();
// this code exposes your environment variables to the client-side.
module.exports = {
env: {
KEY: process.env.KEY,
TOKEN: process.env.TOKEN
},
}
You're using the secret in API routes, so you don't need to expose them to client side. You can remove it:
module.exports = {
env: {
KEY: process.env.KEY,
TOKEN: process.env.TOKEN
},
}
To avoid exposing secrets, do not use the NEXT_PUBLIC_ prefix for them.
If you run next build you should not see .env variables in the output JS files.