Preserving node.js built-in imports for Electron in rollup - javascript

I am making a Electron app with Svelte and Typescript.
I started with this template for that exact purpose, but it disables node.js built-in imports (like fs) in the browser/electron frontend for security.
I do not need this improved security in my project, so I am trying to get node.js fs to work in the Electron browser.
I already modified the Electron Backend script that creates the Browser to re-enable nodeIntegration, and this works: using require("fs") in the Electron browser console logs the fs library.
Using this in the actual typescript frontend code does not work, however. From looking at the bundled JS, it seems like rollup is assuming that the import of fs is just available as a global variable, and trying to guess its name.
When building while importing fs and path, I get the following warnings:
(!) Missing shims for Node.js built-ins
Creating a browser bundle that depends on "path". You might need to include https://github.com/snowpackjs/rollup-plugin-polyfill-node
(!) Missing global variable names
Use output.globals to specify browser global variable names corresponding to external modules
fs (guessing 'fs')
path (guessing 'path')
The first warning suggests a 404 GitHub link that seems to be a polyfill for some Node built-in libraries. This isn't what I want, I want the real node.js fs library. It also informs me that I'm creating a browser bundle - I have tried setting the browser option of #rollup/plugin-node-resolve (used by the template) to false, but this did not help.
The second warning seems to simply inform that it's trying to guess global variable names - which it should not, it should keep the imports.
How do I allow importing Node.js modules here? The linked template project still closely resembles my current one.
Help is greatly appreciated.

Turns out that the deciding factor was the output.format of the rollup.config.js.
This was set to iife, which produced a result without require or import.
Changing it to cjs solves this problem.

Related

ReferenceError: require is not defined (Paynow)

I understand a similar question has been asked before. I am trying to import a payment gateway module (paynow/nodeJS) into a web application. Browser console is displaying
"ReferenceError: require is not defined"
at line
const { Paynow } = require("paynow");
What is that I could be doing wrong?
There are two likely causes of this:
You are trying to run the JS in a browser instead of in Node.js
You have Node.js configured to use ES6 modules instead of CommonJS modules
If the former, run the code designed to be run in Node.js in Node.js.
If the latter, either use import instead or configure the system to use CommonJS modules (don't use the .mjs file extension and don't use package.json's type field.

require is not defined javascript

****** EDIT *******
I do realize the mistake now, i was running my script in my terminal when i was testing my require.
****** OLD ****
The answer might all ready be here on the page, but i have not been able to find it, the general answers i see is that i cannot use "require" client sided.
The thing is the script i am trying to run works perfectly on my school laptop. But it doesnt want to run on my on Desktop at home.
I am trying to run a script where i want to require like this. "var fs = require('fs');"
But the console in my browser just gives me this error ( ReferenceError: require is not )
I am using Visual Studio Code, with Node.js.
I have a basic index.html file which uses 1 script.js file. Nothing else is being used for it.
A link for my files should you want to take a look (
https://drive.google.com/file/d/1VgEmwtcHkURFT1WmPOnEKr_OHLT_SY78/view?usp=sharing )
I am using Visual Studio Code, with Node.js.
I have a basic index.html file which uses 1 script.js file.
So you have two sets of JS.
JS that runs in Node.js
JS that runs in the browser (delivered via index.html)
var fs = require('fs'); is very much in the former category. require is a built-in in Node.js. fs is a core library of Node.js.
You are trying to run it in the browser, where it isn't supported and does not work. You need to run it in Node.js.
i see is that i cannot use "require" client sided.
There are browser-side implementations of require and tools (like Webpack) which will bundle modules into a browser compatible file, but neither of those approaches will help you here because fs itself depends on Node.js.
require() is not standard JavaScript, it's built into NodeJS to load modules.
Try using Express or similar to run a simple web server and it should work. Right now it's not working from home because it's not being compiled by the Node engine.
require() it's not an internal function of javascript in the front-end, you're going to need to import some library that realizes this for you, as for example require.js or browserify.
Otherwise fs is only supported in NodeJS you need to run in the server not in the browser.
this helped me, check your package.json for type:"module" and remove it.

Module name "crypto" has not been loaded yet for context

While trying to use this library
I initially got error ReferenceError: require is not defined.
To solve it, I added required library. This now started with another error as Module name "crypto" has not been loaded yet for context
FOR LEG PULLERS: This is not a duplicate question, As all the questions are either poorly answered or not answered.
I have done my research, EG: this does not tells where to try it.
this is unanswered. this does not tells where do I get those paths like 'path/to/filesize' and all other paths anyways if I get then also is useless in my context. this defines a module of its own, I need a predefined "crypto" module. The default google library is not doing the job.
From my guessing, you are under browser environment instead of developing a NodeJS app.
This crypto you refer to is actually for back-end (NodeJS), provided as NodeJS API, and also, the require keyword, is a NodeJS one.
And from my knowledge, there is no crypto in the default browser environment, neither is there a require. For most cases, there is a REQUIRE.JS and Browserify that let you use this type of require statement, but for your case, I suggest not to use them.
For crypto used in browser environment, I would suggest something using some third-party libraries, like crypto-js, and you without browserify or bower, you should pay special attention to its Usage without RequireJS section.

Breaking a React-Native application into plugable modules

I am looking to write a React-Native application. I want to be able to download new modules at run-time on the device to extend functionality. There would be some core logic that knows how to request new modules based on some form input like a dbs. I do not want to bundle everything into a single monolithic bundle which is what I believe happens now with the built in packager.
This would something similar to how RequireJS works in browser. What I need to know is:
How do I build independent modules? react-native bundle doesn't seem to allow me to select which root modules to begin with and only works on root project
How can I at run-time request new functionality be injected into the current JavaScript environment?
React native starts by pointing at a JS bundle. This means that you would at least have to restart the app to reload the js bundle (assuming that you're reading it from a server and not from the ios device itself).
If you did have a way to update the js files on the server (through some sort of web service that updated based on things the user does) then restarting the app could theoretically reload the JS and provide new functionality to the app.
I was able to get something pretty close to this in JS only. First I had to expose a few more options in the current react-native bundler, mainly, the url (to change the "main" module) and blacklist (to keep from bundling react-native in second bundle) options to their packager (http://github.com/facebook/react-native/blob/master/packager/README.md).
I then had to write a custom fetcher that would download the second bundle and use eval() to evaluate it in the current environment.
The one rub is that I had to add __d('react-native',[],require('react-native')) in the first bundle which I think work like define() from require.js. This exports 'react-native' as an unmangled name that the modules which I plug in can access via normal require() statements. It's a bit confusing at first but from what I can tell they React-native packager works a little like r.js (see http://requirejs.org/docs/optimization.html).

Concatenate NPM package into one JS file

I am trying to get Swig (the template language) working on Parse Cloud Code with Express. Parse Cloud Code is a Node/Express host that doesn't allow NPM. Ridiculous, I know. I can still load external files into code with requires statements however, so I think that there's hope I can get this working.
So my question is how do I get the whole entire Swig package into a single JS file that I can include from my Parse Express app like so:
var swig = require("./cloud/swig.js");
Worth noting that Parse breaks normal require statements so that the NPM package as-is doesn't work without modifying each and every single file in the node_modules folder to have cloud in its path (which is why my above path has cloud in it). Parse also chokes while uploading lots of small files. Concatenation is a need on this platform.
I have tried playing with browserify for hours, but no combination of anything I do makes exposes the Swig object when I load the browserified file with the require statement. I think it may be the right option since the Browserified file includes all the files from Swig, but it doesn't expose them externally.
My question is either can this be done in browserify, and if so, how? Or is there another way to concatenate a NPM repo down to one file so it can be more easily included from this platform?
Thanks so much.
Browserify is not the right tool for the job.
As the name implies, browserify is intended to be used to generate files you want to execute in the browser. It walks the require calls from an entrypoint (i.e. some JS file you pass to browserify) and bundles them in an object that maps their names to functions wrapping the modules. It does not expect a require function to already exist and doesn't make any use of it. It substitutes its own implementation of require that only does one thing: look up names from the bundle, execute the matching function and return its exports.
You could theoretically require a browserify bundle, but it would just return an empty object (although it might mess with globals). And in all likelihood it might break because the bundled modules think they are being executed in a browser. This won't do any good.
The only sane option if you want to stick with the host, is to copy over the node_modules folder from your local project folder. This may not work if your computer and the server are not 100% compatible (e.g. 32-bit vs 64-bit, Debian vs RedHat, OSX/Windows vs Linux) but this mostly depends on your exact dependencies (basically anything that is built with node-gyp can be a problem).
Node.js uses the node_modules folder when looking up dependencies in require calls automagically. If you can somehow get a node_modules folder with the right contents on the server, require("foo") will work as long as node_modules contains a module foo.
Ultimately, you are trying to use npm modules in Parse Cloud code and currently it's not possible:
https://parse.com/questions/using-npm-modules-in-cloud-code
But if you are only trying to use Swig, then as a work-around, you can consider using underscore template instead. Parse already includes underscore:
https://parse.com/docs/cloud_modules_guide#underscore

Categories