JavaScript fails to require a file from a concat string - javascript

I write a function which will load a file using require():
function loadFromName(name) {
const filename = `./${name}.initialState`;
return require(filename).default;
}
When I call this method, it will fail to find the file:
loadFromName('tab')
> Requiring unknown module "./tab.initialState". If you are sure the module is there, try restarting the packager or running "npm install".
I tried two kinds of inline require(). One is success; one is failed.
let initialState;
const name = 'tab';
initialState = require('./tab.initialState'); // success
const filename = './' + 'tab' + '.initialState';
initialState = require(filename); // failed
Why and how to fix it?
NOTE: I use this in React-Native development

Dynamic require is not supported on react native. There are lot of similar questions on stack overflow React Native - Image Require Module using Dynamic Names

Related

buildkite error : The plugins file is missing or invalid. Cannot find module 'xlsx' when running cypress test . Runs fine on local

I am getting error when running the cypress test on buildkite as below:
Status: Downloaded newer image for cypress/included:6.1.0
[2022-01-31T10:32:13Z] Your pluginsFile is set to /e2e/cypress/plugins/index.js, but either the file is missing, it contains a syntax error, or threw an error when required. The pluginsFile must be a .js, .ts, or .coffee file.
Or you might have renamed the extension of your pluginsFile. If that's the case, restart the test runner.
Please fix this, or set pluginsFile to false if a plugins file is not necessary for your project.
Error: Cannot find module 'xlsx'
Require stack:
/e2e/cypress/plugins/read-xlsx.js
/e2e/cypress/plugins/index.js
the same test runs fine on local on both browser and headless
"xlsx" is present in the package.json as both dependencies and dev dependencies.
code inside read-xlsx
const XLSX = require("xlsx");
const fs = require("fs");
const read = ({file, sheet}) => {
const buf = fs.readFileSync(file);
const workbook = XLSX.read(buf, { type: 'buffer' });
const rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
return rows
}
module.exports = {
read
}
Someone please help
I had the same problem.
But in my case, was an issue with case sensitive.
I put 'XLSX' inside the require in the read-xlsx.js file.
My read-xlsx.js file became like this and worked:
const fs = require('fs')
const XLSX = require('xlsx')

React Native Error Cannot find module 'metro-config/src/defaults/blacklist'

I'm currently working on a project in React Native, yesterday it was working perfectly with no errors, and now all of a sudden I'm getting this error.
error Cannot find module 'metro-config/src/defaults/blacklist'
Require stack:
- /Users/sri/Downloads/cc_x/reactnativelcsapp/VitalitiApp/metro.config.js
I've tried soo many solutions, removing the node modules and installing it back, updating the modules, looking to change the backlist. I've checked my files and I can't find the blacklist file but I'm trying to fix it but honestly have no idea how to fix it. I was wondering if anyone would know what to do.
the blacklist file seems to be renamed as exclusionList
const blacklist = require('metro-config/src/defaults/exclusionList');
use this line instead in metro.config.js
In newer versions of metro-config the function is now called exclusionList. So change the blacklist reference with exclusionList in metro-config.js file which is located in the project root directory.
const exclusionList = require('metro-config/src/defaults/exclusionList');
If still issue persists, then add metro-config as a dev dependency:
npm install -D metro-config
I had the same Issue as others. Changing it to
const exclusionList = require('metro-config/src/defaults/exclusionList');
Fixed my issue.
I had to create metro.config.js and insert the following code since I was using AWS Amplify:
const blacklist = require('metro-config/src/defaults/exclusionList');
module.exports = {
resolver: {
blacklistRE: blacklist([/amplify\/#current-cloud-backend\/.*/]),
},
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
};
I had the same error in myapp/node_modules/expo-yarn-workspaces/index.js
From my require stack so I opened this file and found const blacklist = require('metro-config/src/defaults/blacklist'); into my app node modules.
So I changed it to
const blacklist = require('metro-config/src/defaults/exclusionList');
which fixed my problem

How to get Jest to see the functions I am writing for MongoDB Stitch?

I am trying out Stitch, a serverless/hosted JavaScript environment from MongoDB. My main purpose is to help me learn modern JavaScript, but I am trying to write a useful app as well.
I have written the following function, and saved it in my Stitch app. I believe this follows the documented way to write functions in Stitch, and I have tested it from the Stitch administration console:
exports = function(query){
const http = context.services.get("HTTP");
const urlBase = context.values.get("stackOverflowApiUrl");
const options = [
'order=desc',
'sort=activity',
'site=stackoverflow',
'q=' + encodeURIComponent(query),
'user=472495',
'filter=!--uPQ.wqQ0zW'
];
return http
.get({ url: urlBase + '?' + options.join('&') })
.then(response => {
// The response body is encoded as raw BSON.Binary. Parse it to JSON.
const ejson_body = EJSON.parse(response.body.text());
return ejson_body.total;
});
};
This code is pretty simple - it obtains an http object for making external API fetches, and obtains a configuration value for a URL urlBase to contact (resolving to https://api.stackexchange.com/2.2/search/excerpts) and then makes a call to the Stack Overflow Data API. This runs a search query against my user and returns the number of results.
So far so good. Now, I want to call this function locally, in Jest. To do this, I have installed Node and Jest in a local Docker container, and have written the following test function:
const callApi = require('./source');
test('Simple fetch with no user', () => {
expect(callApi('hello')).toBe(123);
});
This fails, with the following error:
~ # jest
FAIL functions/callApi/source.test.js
✕ Simple fetch with no user (3ms)
● Simple fetch with no user
TypeError: callApi is not a function
2 |
3 | test('Simple fetch with no user', () => {
> 4 | expect(callApi('hello')).toBe(123);
| ^
5 | });
6 |
at Object.<anonymous>.test (functions/callApi/source.test.js:4:12)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.418s
Ran all test suites.
(In fact I was expecting it to fail, since it contains a global object context that Jest does not have access to. I will work out how to mock that later, but for now Jest cannot even see the function at all).
I suspect I can see the reason - in the Jest introduction docs, one has to do this for the SUT:
module.exports = function() { ... }
However the Stitch docs seem to require functions to be defined as:
exports = function() { ... }
I do not have a background in JavaScript to understand the difference. I could try module.exports in Stitch, but I would rather not, since this would either not work now, or cause a breakage in the future. Can Jest be instructed to "see" bare exports without the module prefix?
Incidentally, I have picked Jest because it is popular, and because some of my JavaScript colleagues vouch for it. However, I am not wedded to it, and would be happy to use something else if it is known to be better for Stitch development.
Update
Following the useful answer from jperl below, I find that the following construction is not possible in Stitch:
module.exports = exports = function() {}
I also cannot do this:
exports = function() {}
module.exports = exports
If I try either, I get the following error:
runtime error during function validation
So it looks like I have to get Jest to work without module.exports, or create a glue file that imports the exports version into module.exports, with the main file being used by Stitch, and the glue importer being used by Jest.
I suggest you to read this thread. And you're right in thinking it has to do with modules.exports vs exports. The thing is that module.exports and exports first point to the same thing. So something like this works:
//modify the same object that modules.exports is pointing to
exports.a = {}
exports.b = {}
but this won't:
exports = {}
Why? Because now exports points to something else than module.exports so what you're doing has no effect at all.
Update
Following some updates in the comments, we came to the view that Stitch does not seem to support the export format that Jest requires.
This is an addendum to jperl's answer, to show how I got Jest working while respecting Stitch's limitations.
Firstly, it is worth noting how a Stitch application is laid out. This is determined by the import/export format.
auth_providers/
functions/
function_name_1/
config.json
source.js
function_name_2/
config.json
source.js
...
services/
values/
The config.json file is created by Stitch remotely, and is obtained through a export. This contains ID information to uniquely identify the function in the same folder.
I believe it is common JavaScript practice to mix tests with source code, so I am following that style (I am new to modern JS, and I confess I find this style untidy, but I am running with it nevertheless). Thus I add a source.test.js file in each function folder.
Finally, since there is a discrepancy between what Stitch requires and what Jest requires, I have written a script to create a source code file under _source.js in each function folder.
So, each folder will contain these files (the underscore files will probably be ignored by Git, as they will always be generated):
_source.js
config.json
source.js
source.test.js
In order to create the underscored copies, I am using this shell script:
#!/bin/bash
# Copy all source.js files as _source.js
for f in $(find functions/ -name source.js); do cp -- "$f" "$(dirname $f)/_$(basename $f)"; done
# Search and replace in all _source.js files
for f in $(find functions/ -name _source.js); do sed -i -e 's/exports =/module.exports =/g' $f; done
A bit hacky perhaps, but it works!

PubNub Node util.inherit is not a function

After adding the pubnub node sdk to my nativescript Project
npm install pubnub
I get following error message:
> System.err: Error: Parsing XML at 58:9 System.err: > util.inherits is
> not a function
I simply require it like this:
const PubNub = require("pubnub");
Any idea how that could happen?
Currently, PubNub Node SDK is not compatible with NativeScript v5. It is compatible with NativeScript v3. PubNub is investigating changes that can be made to be compatible with NativeScript v5.
Workaround by #Jon_not_doe_xx:
In the webpack.config.js file, add this in the head:
const shims = require('nativescript-nodeify/shims.json');
const aliases = {};
for (const key of Object.keys(shims)) {
const value = shims[key];
aliases[key + '$'] = value;
}
aliases['inherits$'] = 'inherits/inherits_browser';
// Remove hook, as this will only cause problems at this point.
// Checking and deleting within webpack ensures
// that it will be deleted during a cloud build.
let fs = require("fs");
let process = require("process");
if (fs.existsSync(__dirname + "/hooks/after-prepare/nativescript-nodeify.js")) {
process.stdout.write("Found evil hook, deleting...\n");
fs.unlinkSync(__dirname + "/hooks/after-prepare/nativescript-nodeify.js");
process.stdout.write("Should be fixed now.\n");
}
else process.stdout.write("Hooks seem clean, moving on.\n");
Also, modify the alias object inside the resolve object in the webpack.config.js file:
alias: {
'~': appFullPath,
'#': appFullPath,
...aliases
},

Browserify: Uncaught error when requiring js file by path created from string concatenation

I am using browesify for client side app. I have files maps.js and directions.js sitting besides my index.js file, and inside my index.js, I have a function getPageName() which returns the name of the file that I should "require". When I try to do
var pageName = getPageName();
var page;
if (pageName === 'maps') {
page = require('./maps');
} else if (pageName === 'directions') {
page = require('./directions');
}
it works fine. But when I instead try to use following trick to minimize my code,
var pageName = getPageName();
var page = require('./' + pageName);
I get error Uncaught Error: Cannot find module './maps' in console log in Chrome. Why does it not work when I use string concatenation but works when I use pass the path explicitly?
That is a limitation of Browserify and similar type libraries. In order to do the require() the library has to examine the js code as a string, and determine file paths before the code is run. This means file paths have to be static in order for it to be picked up.
https://github.com/substack/node-browserify/issues/377
Browserify can only analyze static requires. It is not in the scope of
browserify to handle dynamic requires

Categories

Resources