I am working on a Express/NodeJs project. I am new to Express/NodeJs, I am trying to import airportQuery.js into DistanceFormula.js. I am trying to directly import airportQuery.js from DistanceFormula.js. Im trying to call getAirports and return the answer to DistanceFormula.js. I not sure if I have to use the node routing or if i'm doing it correctly.
File Stucture:
File Structure
DistanceFormula.JS
import {getAirports} from "./api/airportQuery";
console.log(getAirports('3c675a'));
AirportQuery.js
async function getAirports(planeIcao) {
let airport = {
arrival: "",
destination: ""
};
const airport_url = 'https://opensky-network.org/api/flights/aircraft?icao24=' + planeIcao + '&begin=1517184000&end=1517270400';
const response = await fetch(airport_url);
const data = await response.json();
console.log(data[0]);
console.log(data[0].estArrivalAirport);
airport.arrival = data[0].estArrivalAirport;
console.log(data[0].estDepartureAirport);
airport.destination = data[0].estDepartureAirport;
return airport
}
const fetch = require("node-fetch");
export {getAirports};
ERROR: Uncaught SyntaxError: Cannot use import statement outside a module
To use modules in node.js, you have to do the following:
Be running a version of nodejs that supports ESM modules (v8.5+).
Run with this command line flag: node --experimental-modules
Name your file with an .mjs file extension OR specify it as a module in package.json
See the relevant documentation for more info.
This is true not only for the top level file you import, but if it also uses import, then the same rules above have to apply to it too.
Note, that once you get your modules to load properly, you will then have a problem with this line of code because getAirports() returns promise, not a value. All async functions return a promise, always. The return value in the function will become the resolved value of the returned promise. That's how async functions work. So, change this:
console.log(getAirports('3c675a'));
To this:
getAirports('3c675a').then(result=> {
console.log(result);
}).catch(err => {
console.log(err);
});
Related
I am trying to import the data from the /public/config.ini file into other files throughout my React app.
I am able to fetch the data using Axios however since it is an async function upon loading the files the data is initially undefined.
I am unable to just import the file since it's saying that "Module not found: You attempted to import ../../public/config.ini which falls outside of the project src/ directory. Relative imports outside of src/ are not supported."
I tried using Axios and storing the data as a global variable.
let CONFIG_DATA;
const getConfigData = async () => {
await Axios.get("/config.ini").then((data) => {
const response = ini.parse(data.data);
CONFIG_DATA = response;
console.log(response, "CONFIG DATA");
});
};
getConfigData()
console.log(CONFIG_DATA)
However I get the value as undefined when I am logging it to the console.
Using static import mode works well.For example:
import App from './App.js';
And in common general style of using "import()" works well:
async function fun(){
const App = async ()=> await import("./App.js");
console.log(await App() )//it load module successfully
}
fun();
When i use a string variable parameter for import(),it dosn't work.And it will throw error:
async function fun(){
const path = "./App.js";
const App = async ()=> await import(path).catch(err=>console.log(err));
await App() //Error: Cannot find module 'xxx module path'
}
fun();
So,i must load all modules before using.Could i dynamic import modules like that demo?
I go through the mdn docs about dynamic import but not get helpful information.
And require() performs the same.
Does someone have the same questions?
You need to use ./ and not ../, as ../ is the parent directory and not the current directory. I don't know why this only applies to dynamic imports, but thats just some weird thing about it.
I would like to include a couple of JSON files in my JavaScript code that are in the same directory as my JavaScript source file.
If I wanted to include another JavaScript file I could simply use require.
Now I'm using readFileSync and __dirname to get the JSON, which I think is an ugly way to do it.
Is there something similar for require that enables me to load a JSON file?
As of node v0.5.x yes you can require your JSON just as you would require a js file.
var someObject = require('./somefile.json')
In ES6:
import someObject from './somefile.json'
JSON files don’t require an explicit exports statement. You don't need to export to use it as Javascript files.
So, you can use just require for valid JSON document.
data.json
{
"name": "Freddie Mercury"
}
main.js
var obj = require('data.json');
console.log(obj.name);
//Freddie Mercury
Two of the most common
First way :
let jsonData = require('./JsonFile.json')
let jsonData = require('./JsonFile') // if we omitting .json also works
OR
import jsonData from ('./JsonFile.json')
Second way :
1) synchronously
const fs = require('fs')
let jsonData = JSON.parse(fs.readFileSync('JsonFile.json', 'utf-8'))
2) asynchronously
const fs = require('fs')
let jsonData = {}
fs.readFile('JsonFile.json', 'utf-8', (err, data) => {
if (err) throw err
jsonData = JSON.parse(data)
})
Note:
1) if we JsonFile.json is changed, we not get the new data, even if we re run require('./JsonFile.json')
2) The fs.readFile or fs.readFileSync will always re read the file, and get changes
No. Either use readFile or readFileSync (The latter only at startup time).
Or use an existing library like
cjson
Alternatively write your config in a js file rather then a json file like
module.exports = {
// json
}
A nifty non-caching async one liner for node 15 modules:
import { readFile } from 'fs/promises';
const data = await readFile('{{ path }}').then(json => JSON.parse(json)).catch(() => null);
You even can use require of your JSON without specifying the extension .json.
It will let you change the file extension to .js without any changes in your imports.
assuming we have ./myJsonFile.json in the same directory.
const data = require('./myJsonFile')
If in the future you'll change ./myJsonFile.json to ./myJsonFile.js nothing should be changed in the import.
You can import json files by using the node.js v14 experimental json modules flag. More details here
file.js
import data from './folder/file.json' assert { type: 'json' }
export default {
foo () {
console.log(data)
}
}
And you call it with node --experimental-json-modules file.js
You can use a module to create a require.
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
const foo = require('./foo.json')
if you are using typescript, you can just add in your tsconfig.json a new field called resolveJsonModule: true, and then you can import all the informations of any .json file just like this:
import * as jsonfile from "./path/to/json"
In an "old way" of managing modules in Node.JS (CommonJS modules) you can do something like this:
Example of Express.js route: app.use('/user', require("./user"));
How to do this when I am using ES6 Modules (import, export) and transcribing by Node.JS server by babel?
I can't just do: app.use('/user', import {user} from './user');
Try separating it out into multiple expressions - import (as well as export) are not available at the same lexical level as you are trying to use it the example:
import { user } from './user'
...
app.use('/user', user)
There is a way to do dynamic inline imports in node, detailed here:
https://javascript.info/modules-dynamic-imports
This code has worked for me:
let {default: foo} = await import('./foo.js');
Here is a working example of a function I wrote as part of a db migration tool in node.
const getMigrations = async (path) => {
const migrateDir = await fs.readdirSync(path);
const migrations = await Promise.all(migrateDir.map(async (filename) => {
let {default: migration} = await import(`${path}/${filename}`);
return migration;
}));
migrations.sort((a, b) => {
return a.seq - b.seq;
});
return migrations;
};
Where an example migration is like:
export default {
seq: 1.1,
label: 'create user table',
sql: `
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
...
);
`
};
I am using node v12.18.4 with "type": "module" in my package.json. When I run the script, I get a warning that the ESM module loader is experimental, but it works. However, there is a note on the page linked to above that says:
Dynamic imports work in regular scripts, they don’t require script type="module".
I hope this helps. I believe you should be able to apply this to your problem.
I transpile my ES6 code using Webpack along with BabelJS in NodeJS environment. The problem is that, when I try to import a set of specific .js modules, the MODULE_NOT_FOUND exception would be thrown. This is the main chunk of code I've written so far:
export default async () => {
const modulesToBeImportedByNames = ['a.js', 'b.js', 'c.js'];
const modulesToBeImportedByPromises =
modulesToBeImportedByNames.map(moduleFilename =>
import(`./${moduleFilename}`) // exception is thrown here
);
const importedModules = await Promise.all(modulesToBeImportedByPromises);
}
Note: I've used #babel/plugin-syntax-dynamic-import plugin within my BabelJS configuration.
Looks like the filenames should be relative, as you are importing application files.
const modulesToBeImportedByNames = ['./a.js', './b.js', './c.js'];