"Cannot use import statement outside a module", even as mjs - express

I have been trying to import a simple function that says "Blah Blah" to my express server.
Unfortunately I am getting the error: SyntaxError: Cannot use import statement outside a module.
I have tried to google this issue the whole day, tried to change the file to .mjs and more, but the server keeps crashing with this error regardless of the methods I found online.
ExpressServer.js :
//start express server
const express = require("express");
const server = express();
const path = require("path");
var bodyParser = require("body-parser");
//Require functions that saves to DB
import {saveToDB} from './saveToDB.js';
// parse application/x-www-form-urlencoded
server.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
server.use(bodyParser.json());
server.listen(5000, () => {
console.log("express server is running..");
});
//Send form details to DB
server.get("/save", (req, res) => {
phone = req.body.number;
name = req.body.name;
saveToDB();
});
saveToDB.js
const saveToDB = () => {
console.log(`Blah blah blah`);
};
export default saveToDB;
The error:
import {saveToDB} from ('./saveToDB.js');
^^^^^^
SyntaxError: Cannot use import statement outside a module

First, check what Node version you are using. If it's 13 or above, ES6 and thus the import statement is supported. Else, you have to update your node version or use the ES5 way (require) instead of import.
Second: If the version is 13 or above, you can either change your file extension to .mjs or add { "type": "module" } to you package.json file.
Third: Always put your import statements at the top of the file. Also, I would probably not mix require with import, but that's personal preference.

Problem was fixed, apparently the problem starts when you try to use import on server side instead of require. If you still wish to use import you can update your node version and edit the type in package.json.
If you choose to go with the first route, you will also have to change all the "Require" in your file to import, otherwise you will get "ReferenceError: require is not defined"
The easier solution would be to change:
import {saveToDB} from './saveToDB.js';
With
const saveToDB = require("./saveToDB.js");
And in the exported module, use the older exporting method:
module.exports = saveToDB;

Related

mongoose and express not reading from .env file

I am having some trouble importing a .env file into my project. I have fallbacks in place so I didn't notice the issue until I was almost done with my project and was having trouble implementing a paypal button that wouldn't load. Now I am testing and I realize that all my env files have not been importing :/
I am new to using express but I think I did everything correctly as far as I can tell (but obviously not lol). I have imported all my dependencies and I am using dotenv:
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";
My code for importing my paypal .env file:
app.get("/api/config/paypal", (req, res) => {
res.send(process.env.PAYPAL_CLIENT_ID || "sb");
});
my .env file (located at the root of my folder structure)
PAYPAL_CLIENT_ID= my key info here without quotes
Where the code is eventually being called
const addPayPalScript = async () => {
}, [dispatch, orderId]); const { data } = await Axios.get('/api/config/paypal');
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = `https://www.paypal.com/sdk/js?client-id=${data}`;
script.async = true;
I am not sure why this configuration is not working. I have tried to move the env file to the same folder as the file that is calling it but this just fails to compile with an error. (I have a frontend and a backend folder) I have tried to move the env file to the root of the backend folder and it fails to compile with the same error message. It seems like the root of the project file is the correct location for the env file and all the information I can find online seems like my code is okay, but I still can not load the link for the paypal button when it is clicked on.
Any help would be greatly appreciated. Thank you!
Here is what you should do :
Instead of import dotenv from "dotenv";
Use :
import {config} from "dotenv";
config()
The only function you need from the dotenv library to read your .env configuration is config, to invoke it i've done config()
Now you can access values by doing : process.env.YOUR_ENV_VARIABLE_NAME

Vue CLI dynamic import from project module

I know it is possible to imports component from a bundled webpack file like this
import {componentA, componentB} from '../component.bundle';
Is it possible to achieve this same as a dynamic import, like this.
const url = '${window.location.origin}/assets/default/js/bundle/vue_data.bundle.js';
this.getAxiosInstance().get(url).then(response => {
const {Add, Edit, Filter, View} = () => import(response.data);
});
If yes, please how? Thank you
Yes, using dynamic imports:
To dynamically import a module, the import keyword may be called as a function. When used this way, it returns a promise.
I'm assuming from your url example that your import is in the assets directory of your project (i.e. src > assets) and not actually on an external domain. In that case, you don't need axios. You would do it like this:
const path = 'assets/default/js/bundle/vue_data.bundle.js';
import('#/' + path).then(module => {
const {Add, Edit, Filter, View} = module;
});
You need to hardcode the #/ portion or there will be issues, e.g. if you tried to do import(path) with const path = '#/assets/default/js/bundle/vue_data.bundle.js'

import js file inside .vue component loaded using httpVueLoader

i want to not use webpak form my vue devlopement,
so there is 2 alternative
writting components as .js file or
writing them as .vue file and use httpVueLaoder to load component as if they are .js file
with httpvueLoader think go grate untile the time i want to use an API inside my component
ther i can not get the API
i have a Home.vue componet inside ther is a FormLot.vue component in witchi try to import API.js
<script>
let FormLot = window.httpVueLoader('./frontEnd/page/lot/FormLot.vue')
module.exports = {
name:"Home",
components: {FormLot:FormLot},
...
};
</script>
in FormLot.vue
// _END_ is the absolut path to the site , soi can change it later
let API = import(_END_+'/api/api.js') // dont work return promise
import API from './frontEnd/api/api.js' // dont work componnet dont show at all :(
let FormLotE1 = window.httpVueLoader(_END_+'/page/lot/FormLotE1.vue')
module.exports ={
...
};
</script>
API.JS
module.exports ={
...
};
API.JS
export default {
...
};
with API.js i tryed export default and module.export bothe dont work
nota
when using webpack API.js got been normaly imported and work fine
when using import API from path httpVueLaoder dont work
so i tried to do
const API= import(path)
problem witch that ,API is promise ,wich can notbe used :(
using await dontsolve the problem even when using
const API = (async ()=> await import(path))()
my solution still to call import using await but not in the top of the script
i call it in the mounted() function
async mounted(){
API = (await import(_END_+'/api/api.js')).default
},
note that you must use .default because import return a module :)
enter code here

Property 'close' does not exist on type 'Application'

I am importing expressjs like this:
import { Request, Response, Application, Router } from 'express';
const app: Application = require('express')();
and in typings.json:
"express": "registry:npm/express#4.14.0+20160925001530",
when i type app.close() i get:
[ts] Property 'close' does not exist on type 'Application'.
How can i solve this?
Where can i report this? (if it is a bug)
Am i the only one struggling alot with typescript typings?
The definition of Application provided does not have the method close...Server does and (app:Application).listen returns a Server.
start(){
server = app.listen(options.port, function () {
debug('Server listening on port ' + options.port)
})
}
stop(){
server.close();
}
You can report typings that are Definitely typed here. This is the package coming from npm.
Typescript is hard.

How do you specify file upload directory for express within sails?

I'm uploading a file from a browser <input type="file" name="myfile" id="myfile" using sails. I need to place it in other than the default express location. I'd use the following code in naked Express:
app.use(express.bodyParser({ keepExtensions: true, uploadDir: uploadFolder }))
For sails I wrote code along the lines of this relevant answer
First, I tried SkyTecLabs' answer. policies/configfileupload.js contains
'use strict';
var sailsExpress = require('../../node_modules/sails/node_modules/express'),
path = require('path');
console.log('.. initializing policies/configFileUpload');
module.exports = function configFileUpload (req, res, next) {
var uploadFolder = path.normalize(__dirname + '/../public/uploads');
console.log('.. in policies/configfileupload.js. uploadFolder=', uploadFolder);
console.log('typeofs are=',typeof req, typeof res, typeof next, typeof sailsExpress);
sailsExpress.bodyParser({ keepExtensions: true, uploadDir: uploadFolder });
next();
};
config/policies.js contains
'SchedController' : {
'uploadsubmit': 'configfileupload'
}
Express continues to upload the file to the default directory. Typeof req, res, next, sailsexpress are: object, object, function, function so the signature looks OK. (I tried returning the function configFileUpload just in case, but the controller was never called.)
Then I tried mikemcneil's suggestion. config/express.js
'use strict';
var sailsExpress = require('../node_modules/sails/node_modules/express'),
path = require('path');
module.exports.express = {
customMiddleware: function (app) {
var uploadFolder = path.normalize(__dirname + '/../public/uploads');
console.log('.. in config/express.js. uploadFolder=', uploadFolder);
console.log('typeof sailsExpress=', typeof sailsExpress, 'typeof app=', typeof app);
app.use(sailsExpress.bodyParser({ keepExtensions: true, uploadDir: uploadFolder }));
}
};
and the upload was still placed in the default directory. The typeofs sailsexpress and app are both function.
If the above code is correct for including express middleware in sails, then perhaps this middleware is performed only after express' formidable dependency parses the data and uploads the file.
I don't know in this case of any place in sails where I can place express configuration options such as bodyParser.
Warning: Before you release your app...
If you're expecting lots of file uploads, and especially big ones, you need to reconsider your strategy before deploying into production. You can replace the bodyParser middleware manually by replacing sails.config.express.bodyParser.
The default bodyParser in Express/Connect (and Sails, as of v0.9.x) uses a tmp directory to buffer files (similar to what you'd see in PHP). To get uploaded files somewhere else, you'll need to move them. Check out http://howtonode.org/really-simple-file-uploads for more on how to do that.
There is another option you might check out, depending on how adventurous you are. As I have time, I've been working on an alternative default bodyParser that can be used with Sails or Express. It defers to the underlying library for param/JSON parsing, but uses formidable's raw onPart events to allow streaming uploads without writing the entire file to disk. More on that:
Example repo: https://github.com/mikermcneil/stream-debug
Discussion: https://groups.google.com/d/msg/sailsjs/525fK7pgK8U/bduPudCSLUgJ
Source: https://github.com/mikermcneil/file-parser