node module googleapis causes issues - node.js

I wanted to start using Google Authentication in my nodejs webapp am using the googleapis package.
The moment I require this package after installing it, I immediately get the following error:
protocol sync?8d88:2 Uncaught Error: Cannot find module './framer'
at webpackEmptyContext (eval at ./node_modules/http2/lib/protocol sync recursive (app.js:1053), <anonymous>:2:10)
at Array.map (<anonymous>)
at eval (index.js?1fa7:46)
at Object../node_modules/http2/lib/protocol/index.js (chunk-vendors.js:7788)
at __webpack_require__ (app.js:854)
at fn (app.js:151)
at Object.eval (http.js?4679:136)
at eval (http.js:1264)
at Object../node_modules/http2/lib/http.js (chunk-vendors.js:7711)
at __webpack_require__ (app.js:854)
I've looked into the source here:
var modules = ['./framer', './compressor', './flow', './connection', './stream', './endpoint'];
modules.map(require).forEach(function(module) {
for (var name in module.serializers) {
exports.serializers[name] = module.serializers[name];
}
});
And confirmed that those files are present:
I've already tried to reinstall the packages (http2 & googleapis) but no change.
Why would those relative require statements fail? The files are clearly present.
My webapp is a client-server app using vue. Also note that this is my first little project using node so if you need any additional information on this issue from me just let me know.
Thanks in advance for the help.

I also faced this issue while trying to make googleapis lib work in React app. Reason is googleapis is recommended for server-side web apps.
For React/Client side web apps, I made it work following this documentation.
https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow#js-client-library

Related

Node JS (cpanel) Error: I'm getting an error [ERR_REQUIRE_ESM]: Must use import to load ES Module

So, I've spent quite a few hours today trying to put my nodeJS app that's fully using ESM (modules), and I've deployed it via cPanel on a server that's using Node v. 14.20.1. I'm constantly getting an error:
App 1153856 output: internal/modules/cjs/loader.js:948
App 1153856 output: throw new ERR_REQUIRE_ESM(filename);
App 1153856 output: ^
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /<serverlocation>/app.js
App 1153856 output: at new NodeError (internal/errors.js:322:7)
App 1153856 output: at Module.load (internal/modules/cjs/loader.js:948:11)
App 1153856 output: at Function.Module._load (internal/modules/cjs/loader.js:790:12)
App 1153856 output: at Module.require (internal/modules/cjs/loader.js:974:19)
App 1153856 output: at Module.require (/opt/cpanel/ea-ruby27/root/usr/share/passenger/helper-scripts/node-loader.js:80:25)
All files are written as modules, I don't have one "require()" anywhere.
Since the Node started fully supporting JS modules from v14 on, I'm taking a wild guess that the hosting server I'm using (and their Passenger for NodeJS) is using a loader that's using "require()" when calling my app.js file.
I've tried multiple solutions, I've even switched my app.js file to a CommonJS type, but then it required me to switch all other files to CJS as well, which would be too much hassle.
Has anyone managed to find a proper solution to this issue?
For anyone trying to solve this issue, this is how I solved it:
1- Create a loader script: Not necessarily in the same folder as the main app.js file of your app, but that's where I created it. Call it something like loader.cjs. The extension being .cjs is important if you have "type": "module" in your package.json.
As you might've guessed, this will be the new main of your app. Since the passenger's loaders have an issue with ES modules, just let it load a commonjs file instead.
2- Dynamic import of app.js: Did you know that you can still load ES modules in commonjs files? You just need a little extra bit to do so.
Apparently, ES modules are loaded asynchronously, and this doesn't work well with synchronous commonjs files. That's why you got the issue in the first place, right?
Therefore, the solution is: dynamic imports. Just like async functions, treat the imports of ES modules as promises. I don't really like using .then(), so I opted with await:
async function loadApp() {
await import("/path/to/app.js");
}
loadApp();
3- Rename your app.js's extension: I don't exactly know why this is necessary, but I got error along the lines of "couldn't find /path/to/app.mjs" and so I changed it to so. Then it worked. You can keep the name of the file as "app.js" in the path in the previous point, and the import will sstill correctly look for "app.mjs";
There might be more efficient ways to do this, but that's what my 2 bits of brain could come up with. Hopefully it helps others as well.

Using msal in Angular with Server side rendering

I've been using msal.js for authentication in my Angular application. This is working fine for development builds using ng serve. Unfortunately this library gives me an error when I try to run a server build using node. This build is generated using npm run build:prod and served by using npm run server. After attempting to serve this using node, the following error occurs:
/Users/mikey/Documents/projectname-angular8/dist/server.js:170525
class WindowWrapper extends Window {
^
ReferenceError: Window is not defined
at Module.<anonymous> (/Users/mikey/Documents/projectname-angular8/dist/server.js:170525:29)
at __webpack_require__ (/Users/mikey/Documents/projectname-angular8/dist/server.js:21:30)
at Object.#azure/msal-angular/dist/msal.module (/Users/mikey/Documents/projectname-angular8/dist/server.js:148059:18)
at __webpack_require__ (/Users/mikey/Documents/projectname-angular8/dist/server.js:141641:30)
at Object../src/app/app.server.module.ngfactory.js (/Users/mikey/Documents/projectname-angular8/dist/server.js:142963:13)
at __webpack_require__ (/Users/mikey/Documents/projectname-angular8/dist/server.js:141641:30)
at Object../src/main.server.ts (/Users/mikey/Documents/projectname-angular8/dist/server.js:147883:37)
at __webpack_require__ (/Users/mikey/Documents/projectname-angular8/dist/server.js:141641:30)
at Object.0 (/Users/mikey/Documents/projectname-angular8/dist/server.js:147904:18)
at __webpack_require__ (/Users/mikey/Documents/projectname-angular8/dist/server.js:141641:30)
I can understand why the error is happening, but as this third party library is required, I am unable to remove this package from the project all together. I've tried only loading this part of the code in app.browser.module.ts but then I am having injection errors when attempting to run the server side version in the browser.
I hope someone can explain me how I can make a runnable server side build of this project while using this third party library.

Module #google-cloud/speech not supported for Vue JS?

I'm playing with the Google Cloud API Speech-to-Text Node client library. Works quite well, and well described in their documentation.
Problems come when I wanted to use it in a VueJS : it simply seems not to be supported.
First attempt :
npm run serve returns
ERROR Failed to compile with 3 errors 11:35:13
This dependency was not found:
* http2 in ./node_modules/#grpc/grpc-js/build/src/channel.js, ./node_modules/#grpc/grpc-js/build/src/subchannel.js and 1 other
But http2 is a core module in Node now, and when I run node -p http2 I do get results.
Second attempt :
npm i http2
npm run serve returns
WARNING Compiled with 1 warnings 11:41:07
warning in ./node_modules/http2/lib/protocol/index.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
In browser, console provides error
Uncaught Error: not supported
at Root.loadSync (root.js?ee6e:234)
at Object.loadSync (index-light.js?071f:69)
at Object.eval (index.js?f193:244)
at eval (index.js:250)
at Object../node_modules/#grpc/proto-loader/build/src/index.js (app.js:1383)
at __webpack_require__ (app.js:724)
at fn (app.js:101)
at Object.eval (grpc.js?6f5f:34)
at eval (grpc.js:288)
at Object../node_modules/google-gax/build/src/grpc.js
My Vue App is basic and can be retrieved using vue-cli by running vue create app. I then added in the HelloWorld Component the basic code displayed in the quickstart guide.
My theory is : VueJS can't use google-gax module due to gRPC. What do you think ?
Currently the Google Cloud API client libraries such as the one you are using cannot be used from the browser. As you noted, those libraries use gRPC, which in turn uses http2. The problem is that currently no major browser allows JavaScript libraries to use the full functionality of the HTTP/2 protocol, so there is currently no complete browser shim for the Node http2 module.
The http2 module you got from npm is a different library with a different API. It most likely also does not work in the browser for the same reason.

How to integrate Dialogflow API v2 with MS BotFramework using dialogflow-nodejs-client-v2

I am building a bot using MS BotFramework functions and I am trying to use Dialogflow with MS BotFramework but I am failing with setting up configuration. dialogflow-nodejs-client-v2 library requires that GOOGLE_APPLICATION_CREDENTIALS environment variable is set. Which I believe I set :
I've also manually uploaded conf file into the, what I believe is the working directory
Yet bot is still failing. I tried various paths as value of a variable including absolute path : D:\home\site\wwwroot\messages\test-0691d01dae88.json
still with no luck.
Error I am getting is very cryptic :
Exception while executing function: Functions.messages. mscorlib: One or more errors occurred. Error: package.json does not exist at D:\home\site\wwwroot\package.json
at Object.module.exports.exports.find (D:\home\site\wwwroot\.funcpack\index.js:272715:15)
at Object.module.exports.exports.status.OK (D:\home\site\wwwroot\.funcpack\index.js:51739:12)
at __webpack_require__ (D:\home\site\wwwroot\.funcpack\index.js:21:30)
at Object.<anonymous> (D:\home\site\wwwroot\.funcpack\index.js:271412:12)
at __webpack_require__ (D:\home\site\wwwroot\.funcpack\index.js:21:30)
at Object.module.exports.module.exports (D:\home\site\wwwroot\.funcpack\index.js:84837:27)
at __webpack_require__ (D:\home\site\wwwroot\.funcpack\index.js:21:30)
at Object.<anonymous> (D:\home\site\wwwroot\.funcpack\index.js:260961:14)
at __webpack_require__ (D:\home\site\wwwroot\.funcpack\index.js:21:30)
at new GrpcClient (D:\home\site\wwwroot\.funcpack\index.js:132359:25).
It suggest package.json is missing but this error only occurs if I try to use dialog flow to be specific I require recognizer.js file in index.js.
var apiairecognizer_v2 = require('./recognizer');
It's content is :
"use strict";
const dialogflow = require('dialogflow').v2beta1;
const uuid = require('uuid');
// next line causes error
const sessionClient = new dialogflow.SessionsClient();
var ApiAiRecognizer = function(){
};
ApiAiRecognizer.prototype.recognize = function (context, done){
}
module.exports = ApiAiRecognizer;
Commenting out sessionClient line will make bot work.
Any idea how to configure Dialogflow v2 with MS BotFramework functions?
thanks
Error seems straight forward for any node.js application. You are using statement:
var apiairecognizer_v2 = require('./recognizer');
So application is expecting package.json file for installing packages like:
{
"name": "abc",
"devDependencies": {
"dialogflow":"^0.6.0",
"uuid":"^3.3.2",
"recognizer":"^0.0.2"
}
}
it is used for installing package by npm.
Error is that it is expecting package.json with all referenced & dependent packages there in location D:\home\site\wwwroot\package.json
You can either manually add that or try going to that folder if node is installed & npm is used, try
npm install --save recognizer
or
npm install --save-dev recognizer
it will save latest package in package.json.
It seems you are already getting two packages dialogflow & uuid resolved using npm without error so issue is missing recognizer entry in package.json.
Try adding package in package.json there.

azure-storage not working with web pack (azure-functions-pack) server side

I made an Azure Function micro service using Node.js and I'm using the npm module azure-storage to insert files in a Blob Storage.
Locally is working fine, but when deploying to development environment, it is executed a script that executes azure-functions-pack and generate a bundle with the service code and all the required npm modules. Then when making a request to the micro service, it return a status code 500 and in the logs the error is the following:
System.Exception : Error: Cannot find module "."
at webpackMissingModule (D:\home\site\wwwroot\.funcpack\index.js:238044:68)
at Object.<anonymous> (D:\home\site\wwwroot\.funcpack\index.js:238044:147)
at __webpack_require__ (D:\home\site\wwwroot\.funcpack\index.js:21:30)
...
I only know that the problem is the azure-storage module because If I comment the "azureStorage = require('azure-storage');" , then start working. I also tried the npm module fast-azure-storage without success and until now I was not able to find a workaround for this problem. The code that uses this module is the following:
const blobSvc = azureStorage.createBlobService(storageConnectionString);
const writeStream = blobSvc.createWriteStreamToBlockBlob('containerName', fileName);
return new Promise(function (resolve) {
writeStream.write(svgString);
writeStream.on('close', () => {
resolve('https://' + storageAccount + '.blob.core.windows.net/containerName/' + fileName);
});
writeStream.end();
});
The version of azure-storage is 2.6.0. Thanks for any help.
Not a direct answer to your question - but you should use output binding feature of Azure Function to insert Blobs instead of doing that manually with library calls.
If you do that, you won't have to import the package, so it will also solve your problem.
Read more about output bindings in docs, there is a node example there too.
Actually the problem wasn't the azure-storage module, but the node-chartist module which for some reason also was causing problems in other modules. After remove node-chartist all the modules started working perfectly.

Resources