Dynamic require() in pkg (node.js) - javascript

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

Related

Is there any way to get a list of files in a directory into a variable when using webpack?

When creating a browser app, there doesn't seem to be any way to get a list of files in a particular location using javascript. In Nodejs this is easily done using fs.
Basically I have a directory called images/, and I want to manipulate a list of all the files as a javascript variable without having to manually create the list of files. I thought that since webpack bundles all of the files that there might be some way to generate the list as a JSON file (or an alternative) which could be read in with javascript -- though I haven't found any way to do that yet.
What is the best way to do this?
I was able to solve this by creating a plugin:
src/plugins/FileLister.js:
const fs = require('fs');
class FileLister {
constructor(options) {
if (!options || !options.path || !options.outputFile) {
const msg = "Please specify the path and outputFile options.";
throw new Error(msg);
}
this.options = options
}
apply(compiler) {
compiler.hooks.done.tap({name: 'FileLister'}, () => {
const files = fs.readdirSync(this.options.path)
fs.writeFileSync(this.options.outputFile, JSON.stringify(files));
})
}
}
module.exports = FileLister;
Then in my webpackage.config.js:
import:
const FileLister = require('./src/plugins/FileLister.js')
plugins section:
new FileeLister({
path: path.resolve(__dirname, 'src/important_files/'),
outputFile: path.resolve(__dirname, 'dist/important_files.json')
}),
This creates a file called important_files.json in the dist directory containing a list of the files in src/important_files/.

ElectronJS : How to show changes in the code immediately?

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)

Cannot find module Error While js files are located in same Directory

I have added a js Module called mongoUtil, which contains the code hereafter, following a suggestion found at this link.
const MongoClient = require( 'mongodb' ).MongoClient;
const url = "mongodb://localhost:27017";
var _db;
module.exports = {
connectToServer: function(callback) {
MongoClient.connect(url, {useNewUrlParser: true}, function(err, client) {
_db = client.db('MyDB');
return callback(err);
});
},
getDb: function() {
return _db;
}
};
I have furthermore used the following line in my app.js Module:
const mongoUtil = require('mongoUtil')
However, I am obtaining the following error while the 2 Modules are located in the same Directory:
Error: Cannot find module 'mongoUtil'
What am I missing?
If you provide a module name to require it will search node_modules for it.
If you want to read a module from the current directory, you need to use the file path. This can be relative: require("./mongoUtil")
The exact documentation is here including a (rather long) pseudocode explanation of how the algorithm of locating a module works.
But in short, there are two basic ways of loading a module:
Using the name of an installed module (may be globally or locally installed), for example require('mongodb'). This would look for the (global or local) node_modules/mongodb folder.
Using a path (absolute or relative), for example require('./mongoUtil'). This would look for a file at the given path - if it's relative, then it is relative to the current file.
So, the solution is to use require('./mongoUtil') and not require('mongoUtil').
This will work:
const mongoUtil = require('./mongoUtil.js');
Or even just the following, since the extension is automatically resolved:
const mongoUtil = require('./mongoUtil');

webpack solve require arguments before build (constexpr)

I'm working on a RESTful API express.js server. what I expect is something like A node Express router middleware for RESTful API base on certain folder path. but this package using dynamic require which loads modules on runtime with an expression. this cause webpack throw an error: Critical dependency: the request of a dependency is an expression. what I did is change require to require.context, which introduce the actrully problem: Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
sample code
// import-routes.js
function importRoutes(folder, pattern = /\.js$/) {
const files = require.context(folderPath, true, pattern);
files.keys().forEach((file) => {
// do something here
});
}
module.exports = (folder, pattern) => importRoutes(folder, pattern);
// index.js
const routes = require('./lib/import-api')('./apis');
// constexpr routes = require('./lib/import-api')('./apis');
// otherIndex.js
const routes = require('./lib/import-api')('./otherApis');
// constexpr routes = require('./lib/import-api')('./otherApis');
Is there something just like constexpr in cpp that could solve this on compile time?
Reference of constexpr

SailsJS custom config files

I am aware I can create a custom file inside the config directory and reference the variables from within that
module.exports.myconfig = {
foo: 'bar'
}
sails.config.myconfig.foo
But I need to write to these variables too and have them saved. In previous projects I have done this with JSON config files and used PHP to write to them.
Is there any way of doing this with Sails or should I just create some JSON files to pull and push my config vars?
There's no mechanism built in to Sails for persisting configuration variables. However, in the latest build of Sails there is a lower event you can listen for which indicates that Sails is exiting. You could catch this and persist your data then. For example, in your /config/bootstrap.js, something like:
var fs = require('fs');
module.exports = function(cb) {
sails.on('lower', function persistConfig() {
fs.writeFileSync(sails.appPath+'/config/myConfig.js',
'module.exports = ' + JSON.stringify(sails.config.myconfig));
});
// ... other bootstrap stuff ...
return cb();
}

Categories

Resources