How do you import a function with parameters using ECMAScrip6? - node.js

I am setting up a brand new project in Express using Babel and ESLint, and am trying to setup dynamic routes. The only issue is that I cannot figure out how to call the loader for the routes. This is my current code regarding the loader.
routes/index.js
import fs from 'fs';
/**
* Register Default Routes
* #param {Object} app express.Application
*/
export default function(app) {
fs.readdirSync(__dirname).forEach((fileName) => {
if (fileName == __filename.slice(__dirname.length + 1)) return;
let fileNameStripped = fileName.substring(0, fileName.lastIndexOf('.'));
require('./' + fileNameStripped)(app); // does not work
});
}
index.js
import express from 'express';
import routes from './routes/index.js';
const app = express();
app.use(express.static('public'));
routes(app); // works now
...
Babel Error
TypeError: require(...) is not a function
at /app/build/routes/index.js:1:314
at Array.forEach (<anonymous>)
at exports.default (/app/build/routes/index.js:1:195)
at Object.<anonymous> (/app/build/index.js:1:393)
at Module._compile (module.js:649:30)
at Object.Module._extensions..js (module.js:660:10)
at Module.load (module.js:561:32)
at tryModuleLoad (module.js:501:12)
at Function.Module._load (module.js:493:3)
at Function.Module.runMain (module.js:690:10)
The issue appears to be related to https://github.com/babel/babel/issues/2683

Since nested route files are supposed to be ES modules with default exports, require('./' + fileNameStripped) is module object and not a function. It should be:
require('./' + fileNameStripped).default(app);
Depending on Babel configuration (dynamic-import-node plugin is required), require() can be replaced with dynamic import() but it's less desirable here, because dynamic import is not synchronous and can cause race conditions.

Related

Have problem using export function in node js [duplicate]

This question already has answers here:
Node.js - SyntaxError: Unexpected token import
(16 answers)
Closed 1 year ago.
The code for pug.compiler.js is:
/**
* Pug Utilities
*/
const {compileFile} =require('pug');
/**
*
* #param {String} relativeTemplatePath Pug template name
* #param {Object} [data] Object
* #returns {String} HTML
*/
export function compile(relativeTemplatePath, data){
let absoluteTemplatePath = process.cwd() + '/src/views/' + relativeTemplatePath + '.pug';
let compiledTemplate = compileFile(absoluteTemplatePath)(data);
return compiledTemplate;
};
The error is :
export function compile(relativeTemplatePath, data){
^^^^^^
SyntaxError: Unexpected token 'export'
at wrapSafe (internal/modules/cjs/loader.js:984:16)
at Module._compile (internal/modules/cjs/loader.js:1032:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
at Module.load (internal/modules/cjs/loader.js:933:32)
at Function.Module._load (internal/modules/cjs/loader.js:774:14)
at Module.require (internal/modules/cjs/loader.js:957:19)
at require (internal/modules/cjs/helpers.js:88:18)
at Object.<anonymous> (D:\ProgramData\projects\nodejs\whatsapp\test\app.js:11:22)
at Module._compile (internal/modules/cjs/loader.js:1068:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
So I have a problem understanding how do I use this export function. I think it should work right?
The problem is NodeJS considers module by default as CommonJS Modules.
So instead of export you should use module.exports, or if you're using NodeJS v13+ you can enable ES Modules by either:
Changing the extension of your file to mjs
Adding "type": "module" property to your package.json
Using module.exports should be like:
function compile(relativeTemplatePath, data){
let absoluteTemplatePath = process.cwd() + '/src/views/' + relativeTemplatePath + '.pug';
let compiledTemplate = compileFile(absoluteTemplatePath)(data);
return compiledTemplate;
};
module.exports = {compile};

Node.js - Import Package Issue - Not a Function

Using node v12.9.0 on macOS Mojave, have the following project structure (with app being the root folder):
app
\
utils.js
app.js
utils.js
console.log('utils.js')
const add = function(a ,b) {
return a + b
}
module.exports = add
app.js
const add = require('./utils.js')
const sum = add(4, -2)
console.log(sum)
Tried running this:
node app.js
Error:
app/app.js:3
const sum = add(4, -2)
^
TypeError: add is not a function
at Object.<anonymous> (/Users/devuser/app/app.js:3:13)
at Module._compile (internal/modules/cjs/loader.js:936:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)
at Module.load (internal/modules/cjs/loader.js:790:32)
at Function.Module._load (internal/modules/cjs/loader.js:703:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:999:10)
at internal/main/run_main_module.js:17:11
Can you try this:
utils.js
const add = function(a ,b) {
return a + b
}
module.exports = {
add : add
}
app.js
const utils = require('./utils.js')
const sum = utils.add(4, -2)
console.log(sum)
It actually works now using my original code inside both the Integrated Terminal that Visual Studio Code provides and the native macOS Terminal.
Now it just prints:
2
Don't know why it was had a TypeError earlier?
Am new to node.js so I can't comment on what changed?

Alexa Lambda Function "Unable to import module 'index'" when using new required function

I'm building an Alexa skill (deploying via CLI), and all has been going well up until needing to make a few Http calls.
I decided to use first axios, then require in order to do so.
When I installed axios using npm, all seemed well. Adding just the "const axios= require('axios');" line caused my lambda function to start complaining about "Unable to import module 'index'" in the Cloudwatch logs, however, and specifically calling out the line in index.js where I make that require statement.
Removed axios, tried require...same deal.
Any thoughts?
Not actually using the packages yet even, it complains on the require line if I uncomment it.
/* eslint-disable func-names */
/* eslint-disable no-console */
/* eslint-disable no-restricted-syntax */
const error_handler = require('./error_handler');
const globals = require('./globals');
const helper_functions = require('./helper_functions');
const intents_aquarium = require('./intents_aquarium');
const intents_built_in = require('./intents_built_in');
const intents_conversion = require('./intents_conversion');
const intents_helper = require('./intents_helper');
const intents_tank = require('./intents_tank');
const intents_unhandled = require('./intents_unhandled');
const skillBuilder = globals.Alexa.SkillBuilders.standard();
//const request = require('request');
exports.handler = skillBuilder
.addRequestHandlers(
intents_built_in.launchRequest,
intents_built_in.exitHandler,
intents_built_in.sessionEndedRequest,
intents_built_in.helpIntent,
intents_built_in.yesIntent,
intents_built_in.noIntent,
intents_aquarium.aquariumCreateIntentHandler,
intents_aquarium.aquariumCreateSimpleImperial,
intents_conversion.aquariumVolumeIntentGallonsToLitres,
intents_conversion.aquariumVolumeIntentLitresToGallons,
intents_helper.thankYou,
intents_tank.tankObservation,
intents_built_in.fallbackHandler,
intents_unhandled.unhandledIntent,
)
.addErrorHandlers(error_handler.errorHandler)
.withTableName('Tank-Mate')
.withAutoCreateTable(true)
.lambda();
Error looks like this:
Unable to import module 'index': Error
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/var/task/index.js:16:17)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
...which to me looks like it's complaining about the index.js require line.

Extend SchemaDirectiveVisitor To Use Apollo Server Schema Directives in NodeJS

I'm trying to extend SchemaDirectiveVisitor in order to make a custom directive in Apollo Server 2. I'm specifically using the 2.2.6 hapi node module.
Here's my server.js code:
const { ApolloServer } = require('apollo-server-hapi');
const { SchemaDirectiveVisitor } = ApolloServer;
class ViewTemplateGroup extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
console.log('Im calling this directive!');
return;
}
}
When I start up my server I immediately get the following error:
TypeError: Class extends value undefined is not a constructor or null
at Object.<anonymous> (/Users/garrett.kim/Desktop/Projects/Test Web/poc-graphQL-forms-gyk/server.js:36:33)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Function.Module.runMain (module.js:701:10)
at startup (bootstrap_node.js:193:16)
at bootstrap_node.js:617:3
To my knowledge, I'm following the Apollo Server 2 example very closely.
https://www.apollographql.com/docs/apollo-server/features/creating-directives.html
Any help getting directives working would be appreciated.
The ApolloServer class does not have a SchemaDirectiveVisitor property on it; therefore, calling ApolloServer.SchemaDirectiveVisitor results in undefined and a class cannot extend undefined as the error indicates. Just import SchemaDirectiveVisitor directly from the apollo-server-hapi module:
const { ApolloServer, SchemaDirectiveVisitor } = require('apollo-server-hapi')

use #std/esm to use ES6 in Express node.js project

I'm working on a Node.js project. I'm trying to use ES6 feature (like "import", "export") with a new ESM library but I'm struggling how to use it in Express app.
Here is what I have done:
Run npm i --save #std/esm in the project directory.
In index.js add "require("#std/esm")" to first line
use ESS "import"
here is my index.js
require("#std/esm")
// const express = require( "express" );
import express from '../node_modules/express'
const router = express.Router();
/* GET home page. */
router.get( "/", ( req, res, next ) => {
res.render( "index", { "title": "Express" } );
} );
// export default router
module.exports = router;
Run the project but I get this error
/usr/local/bin/node /Volumes/Elements/Learning/Node/Project/NodeMongoTest1/routes/index.js
/Volumes/Elements/Learning/Node/Project/NodeMongoTest1/routes/index.js:3
import express from '../node_modules/express'
^^^^^^
SyntaxError: Unexpected token import
at new Script (vm.js:51:7)
at createScript (vm.js:136:10)
at Object.runInThisContext (vm.js:197:10)
at Module._compile (module.js:626:28)
at Object.Module._extensions..js (module.js:673:10)
at Module.load (module.js:575:32)
at tryModuleLoad (module.js:515:12)
at Function.Module._load (module.js:507:3)
at Function.Module.runMain (module.js:703:10)
at startup (bootstrap_node.js:193:16)
Process finished with exit code 1
Any know how to config ESM with Express Node.js?
There are three ways to enable ESM with #std/esm.
Enable ESM with a CJS bridge:
index.js
// Provide options as a parameter, environment variable, or rc file.
require = require("#std/esm")(module/*, options*/)
module.exports = require("./main.mjs").default
Enable ESM in the Node CLI with the -r option:
node -r #std/esm main.mjs
Enable ESM in the Node REPL:
node -r #std/esm
Try #2 first to check whether rest of code is correct in index file

Resources