I have created a npm package named test_package_cat, which is supposed to read a json file (info.json) at the beginning.
Thus, index.js (main entry) and info.json are at the same level.
When I run the index.js locally, I can read the file.
either:
fs.readFileSync('info.json')
or
fs.readFileSync(path.resolve(__dirname, 'info.json')
works fine.
However, when I have another program, a React page,that uses the package, it fails to read the json file.
cat = require('test_package_cat')
cat.meow()
When I run index.js locally, if I console.log(__dirname), it gives me C://......../myProject.
However, when running the React app, console.log(__dirname) just prints "/" and when I try to print directories/files, it shows nothing.
How can I make the my npm package to read info.json file?
Edit: After more searching, I managed to get it working by doing:
let info = require('./info.json')
console.log(JSON.stringify(info))
but would still like to know how to do it using "readFile" way.
fs is only available in the Node runtime environment. It isn't available in a browser's JavaScript runtime environment. I'm surprised you haven't encountered an error to that effect.
Related
I have a react app that loads data from a local json file using
import data from './data.json'
it is all working fine without any issues and I'm able to open my index.html in 3000 and also open it as simple HTML page in browser.
Now I run npm run build which creates the build directory. However, my json values become kind of stagnant as it is hardcoded in the javascript in the build. So the question is how can my code in build directory reads json files from a specific location dynamically.
My question: Why not use fetch and serve the JSON from a server side API?
To partially answer your question:
Without changing any webpack configuration, you can use the import() function, instead of import, and a chunk will be built with the json content within a js file.
async function fn() {
const json = await import("./foo.json")
document.title = json.bar
}
On the other hand, probably, webpack has a way to configure this output to be json, but for that you'll need to npm run eject or use a tool to override the webpack production config.
Apart from other alternatives, what you're looking for vanilla Javascript is called fetch API. It's possible to read from either local or remote URLs via fetch method.
As per the example you provided above, instead of doing below;
import data from './data.json'
You can make use of it like;
fetch('./data.json')
Also it works pretty same way as per any URL;
// Sample working URL example to mock some real data
fetch('https://jsonmock.hackerrank.com/api/football_competitions?year=2015')
And best part of it, the parameter fetch method accept can be modified easily since it both accepts local file path and a URL as a variable very same way;
let baseURL = 'https://jsonmock.hackerrank.com/api',
endpointToCall = 'football_competitions',
year = '2015',
URL;
URL = `baseURL/${endpointToCall}?year=${year}`;
fetch(URL);
Note: With the last example above, my point is to destructure the same API endpoint used with previous example before, via dynamic variables in order to being able to more clearer. Please let me know if it's not and you need more clarification.
What you can do it before you run the npm run build you make a request to your server to get the data.json file and then just run the npm run build when it loads. You can write a simple script for it.
For example:
#!/bin/bash
# Get the file from the server
curl https://yourServer/data.zip -o data.zip
# Unzip the file, you can also use unzip
zip -d data.json
# Move the file to the desired directory
mv data.json /yourApp/data/data.json is
# Navigate to the directory where the npm package is
cd /yourApp/
# This one is optional but you should run a test to see if the app won't crash with the new json data that you fetched
# Run tests
npm run tests
# Run the build command for React
npm run build
You can modify this script with your paths and it should work.
Summary
Get the json data with curl
Unzip it
Move it to your react app where data.json is and replace it
Run the tests (optional)
Run the build
You're done.
Hope this helps.
I`m only starting my JS journey and I will be really grateful if you help me to receive data using the JS. I found that info on the alcor exchange site that is the exchange site for wax (gaming crypto currency).
What is on site:
// Code not tested yet, and provided for explanation reason
import fetch from 'node-fetch'
import { Api, JsonRpc, RpcError } from 'eosjs'
const rpc = new JsonRpc('https://wax.greymass.com', { fetch })
// Get buy orderbook from table
const { rows } = await rpc.get_table_rows({
code: 'alcordexmain',
table: 'buyorder',
limit: 1000,
scope: 29, // Market id from /api/markets
key_type: 'i128', // we are using it for getting order sorted by price.
index_position: 2
})
I faced with some trouble because of JSHint version and updated it to 9. But still "await" is red and JSHint is asking for semicolon after it - which causes huge amount of new errors. However the project is opening in the browser with no info of course. But in the console I see an error.
index.html:1 Uncaught TypeError: Failed to resolve module specifier "node-fetch". Relative references must start with either "/", "./", or "../".
P.S. I checked the posts with such error but actually didn't understand what should I do because all of them are proposing some changes for JSON file and I only have index.html and that js. file.
There is a difference between JavaScript in your browser and JavaScript on a server.
JavaScript in a browser is the code that can be injected into HTML (inlined or linked), which is evaluated by the browser.
JavaScript on a server is not related to JavaScript in a browser. The language is the same, but the environment is not. It's like “draw in Paint” and “draw on a real life canvas”. Colors are the same, but everything else is not.
So, what you are trying to do here is to run server-side JavaScript in a browser. That's the real reason you're getting this error.
There are two ways to fix this error.
Probably the one you should go
You should install Node.js, read about npm, init your npm project, put everything into .js file and eval using Node.
In a nutshell, let's say you've already installed Node.js and node -v outputs something in your terminal. Then everything you need to do is:
$ cd path/to/the/directory/you/like
$ npm init -f
$ npm install --save node-fetch eosjs
$ touch index.js
Then edit index.js using your favorite editor, adding there the code you're trying to run.
You may encounter error due to using await on a “top-level”. In this case, put it into an async function:
import fetch from 'node-fetch'
import { Api, JsonRpc, RpcError } from 'eosjs'
const rpc = new JsonRpc('https://wax.greymass.com', { fetch })
(async () => {
const { rows } = await rpc.get_table_rows({
code: 'alcordexmain',
table: 'buyorder',
limit: 1000,
scope: 29, // Market id from /api/markets
key_type: 'i128', // we are using it for getting order sorted by price.
index_position: 2
});
})();
Aaaand, that's it. You do not need to run browser here at all.
Probably the one you should not go, but can
If you need to run your JavaScript in a browser, then you need to either bundle all the deps using a tool like webpack (which still requires you to use Node.js & npm), or you may replace the deps you're trying to use with client-side alternatives.
E.g. instead of requiring node-fetch you may use Fetch API.
What to use instead of eosjs I do not know, but if you decide to use this dependency in a browser, you will at least need to use import maps to tell the browser how to resolve such dependencies. Because, well, the error you've got tells you exactly this: your browser does not know what you're trying to import. Browsers use URLs as import paths, not ids (or “bare names”).
I am using selenium-webdriver module on npm and my code is =
const selenium = require('selenium-webdriver');
const { Builder, By, Key } = selenium;
(async() => {
const driver = await new Builder().forBrowser('chrome').withCapabilities(selenium.Capabilities.chrome().set('chrome.binary', './drivers/chromedriver.exe')).build();
})();
It gives me the error Error: The ChromeDriver could not be found on the current PATH. I downloaded chromedriver then try both using .withCapabilities(that part is still inside the code above) and export PATH=$PATH: but both not worked still giving same error I have chromedriver in a folder called drivers and that folder is on same folder with my index.js file I think my path writing is wrong but I really don't know how to do it can someone help?
As #Max Daroshchanka suggested in the comments section, first thing is that you must have the path to the executable chrome.exe for the "chrome.binary" option.
Secondly, I will suggest that you have the same version for chromedriver.exe and your chrome.exe. I faced the same issue because I was not having the same version.
Now the following is something that did not work for me. Could not be the case with you.
Thirdly, I will also suggest that instead of relying on the node.js (or any package manager's) library (this gets created when you perform npm install, for every dependency there is a /lib folder created that has the executable) to add the required chromedriver.exe file. What I mean is manually download the required version driver file from here:
http://chromedriver.storage.googleapis.com/index.html
and add this downloaded extracted path to the PATH env variable.
I am trying to call a function in a python file from a js file, I got this to work through my console, but I am now trying to implement it in a mobile app using expo.
The way I had set this up is, I have the JS file for a certain screen in my app, this then calls a function in a separate JS file, which then calls the function in the python file.
I am using the child_process module to talk to python from JS.
And as I said, this was working before I tried to export the JS function to my screen file.
index.js
export function foo(process, sentence){
const spawn = require("child_process").spawn;
const process = spawn("python3", ["./python.py", sentence]);
...
}
screen.js
*other imports
import { foo } from "./filepath..."
...
But when I run npm start I get the following error:
Failed building JavaScript bundle.
While trying to resolve module `child_process` from file `/Users/mee/Documents/GitHub/project/app/screens/screen.js`, the package `/Users/mee/Documents/GitHub/project/node_modules/child_process/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`/Users/me/Documents/GitHub/project/node_modules/child_process/app/screens/screen.js`. Indeed, none of these files exist:
How can I fix this?
It won't work for few reasons
child_process is part of the node standard library, it's not available in other environments like react-native or browser
even if above was not true, there is no python3 executable on your phone
python.py file from your local directory wouldn't be even uploaded to the phone because bundler is only uploading one big js file with entire js code combined + assets, python.py is neither of those.
Only solution that make sense it to rewrite that code to javascript.
Technically it's not impossible, there might be a way to do that, by compiling python interpreter for mobile platform, or using some tool that translates python code into js, but it's not something that you should consider.
I am using Browserify (http://browserify.org/) to load a module in JavaScript. I keep getting the following error:
I have no idea why this is happening. I have a "package.json" file in a directory called "wordnet-develop", which is located in the same location as the JavaScript file.
Originally I thought that there might be a path problem. However, I did the same exact thing but with a test.js file, and it worked. So, I think that there may be something wrong with using package.json.
The beginning of the package.json file:
The beginning of my JavaScript file:
The directory containing the javascript file:
The directory (seen above as "wordnet-develop")containing the package.json file:
UPDATE
I replaced var WordNet = require('./wordnet-develop/node-wordnet'); with var WordNet = require('./wordnet-develop/lib/wordnet'); as suggested by klugjo.
It may have worked, but now I am getting a new error message:
This happened again but with 'async' module missing. I checked lib/wordnet, and it included requirements for bluebird and async, so that's probably the error source.
However, I now have no idea what to do. I'm new to node.js and modules, so I'm unfamiliar with solutions. Am I supposed to parse all of the code and find all the required modules online? Shouldn't they have been included in the module? Is the problem that I'm trying to use a node.js module in vanilla JavaScript?
I don't think what you are trying to do is supported: you have to link directly to the entry javascript file of the node-wordnet library.
Replace
var WordNet = require('./wordnet-develop/node-wordnet');
With
var WordNet = require('./wordnet-develop/lib/wordnet');