How to import module based dependencies for firebase cloud functions? - node.js

I want to organize my firebase cloud functions in specific files,
and currently, I have these 3:
index.ts
crypto.ts
webscrape.ts
Inside of these files, I have functions that use specific dependencies that are needed nowhere else.
For example, in crypto.ts I need the crypto-js package to encrypt some user data and store it into the database.
So I am importing it like so:
import * as CryptoJS from "crypto-js";
as advised in https://firebase.google.com/docs/functions/handle-dependencies#typescript
On the other hand, when I try to import puppeteer into webscrape.ts like this:
import * as puppeteer from"puppeteer-extra";
then calling puppeteer.launch(); gives me an error :
Property 'launch' does not exist on type 'typeof import("c:/Users/username/Desktop/project/firebasee/functions/node_modules/puppeteer-extra/dist/index")'
and it only works when I do const puppeteer = require("puppeteer-extra");
What's the difference here?
My goal is to keep the dependencies of each functions and file/module as small as possible because I assume that this will also keep the size of each function container small (Is that even true?)
I didn't want to import everything to index.ts even when I trigger a function, that doesn't use this dependency at all.
So what is the correct way of handling these dependencies?
Thanks!

The following import will get the default export from that package.
import puppeteer from "puppeteer-extra"
I looked for the default export in the Github repository and found that.
const defaultExport: PuppeteerExtra = (() => {
return new PuppeteerExtra(...requireVanillaPuppeteer())
})()
export default defaultExport
They have mentioned both ES6 import and require methods here.
// javascript import
const puppeteer = require('puppeteer-extra')
// typescript/es6 module import
import puppeteer from 'puppeteer-extra'
You can read more about import on MDN.

Related

unable to figure out error from passport-custom

trying to use passport-custom and the very first line, from pseudocode at npmjs, errors out:
import passportCustom from 'passport-custom';
The is no default import in index.js when I open it up under node_modules/passport-custom/lib
I must be missing something fundamental here, don't know what though
Try to use CommonJS const passportCustom = require("passport-custom") You probably have older version of Node.js which does not support ES6 modules.
There is no default export. So you will have to name the items you want to import (put them in curly braces).
//Example:
import { a,b,c,d} from 'youPackage';
//Your case:
import { passportCustom } from 'passport-custom';
Above are called named imports. When a package exports one item by default using: export default passportCustom ;, you could have use your code. You can access the code of the package to have a look for yourself.

Is it possible to import a function in a modules subfolder

I'm trying to access the decode() method in the jsQR module.
I found an example that called decode() directly but that was from an HTML file, not nodejs.
In visual code I see this...
I know that the default export is defined in index.d.ts but is there anyway of importing the other classes/functions on the rest of the dist folder?
I've tried to import using require("jsqr/decoder") and require("jsqr/decoder/decode") to no avail.
EDIT
To be clear, I don't want jsQR, the default export. That deals with images. I'm trying to explicitly call the decode() method in the pic which accepts a BitMatrix
There are no limitations in what you can require from node_modules. So, with your case it should look like:
TypeScript\ESM Modules:
import { decode } from 'jsqr/dist/decoder/decoder';
CommonJS:
const { decode } = require('jsqr/dist/decoder/decoder');
UPD: If you take a look into dist folder for jsqr package, you can find that there are only d.ts files. Which means that you can not import it from there.
But, you can find an actual export of the module here:
Which means that you should able to import it from jsqr:
const { decode } = require('jsqr');

Importing third party Libraries into a Stenciljs Project

So Im trying to import the third party npm module 'rss-parser' to my Stenciljs project. I tried it like in the official documentation:
let Parser = require('rss-parser');
let parser = new Parser();
(async () => {
let feed = await parser.parseURL('https://www.reddit.com/.rss');
console.log(feed.title);
feed.items.forEach(item => {
console.log(item.title + ':' + item.link)
});
})();
I got the Error: Can't find variable: require.
I think I'm somehow missing how I need to install these libraries but I can not figure out how. I've red about moudle bundlers but I thought that comes with the Stenciljs compiler already.
Is it a problem that Im trying to import old JS code in a ES6 project?
Thanks for your help
Stencil components are written in TypeScript, so you use import to pull in dependencies:
import Parser from 'rss-parser';
More on TypeScript's modules here: https://www.typescriptlang.org/docs/handbook/modules.html
var Parser = require('rss-parser') is a requireJS syntax which is not going to work with stencil.
You need to import it using one of the following ways:
import Parser from 'rss-parser';
import { Parser } from 'rss-parser';
import 'rss-parser';
And this purely depends upon how the module has exported the variable.
Another thing you might need to do in your stencil.config.ts file is to set
nodeResolve: true

Can't import exported functions

I am having strange issues with Typescript when I import things from a file which exports them. Sometimes I will export a function, then import it to another file, then I use the function and it is not a function anymore. When I define the function in the same file, all of a sudden the function is a function?!?!?
Why would a function stop being a function when it is exported? I have had similar problems with classes too.
The hard part of this issue is I can't recreate a simple example because it only happens when I am using some kind of higher level package.
For example, I had a similar issue with sequelize-typescript here: my github issue with typescript-sequelize
Below is some codes showing off the basic issue I'm having with one of the decorators from InversifyJS.
container.ts
import {fluentProvide} from "inversify-binding-decorators";
export const provideSingleton = (identifier: any) => {
return fluentProvide(identifier)
.inSingletonScope()
.done(true);
};
test.service.ts
import {provideSingleton} from './container'
#provideSingleton(TYPES.TEST)
export default class TestService {}
The strangest thing is when I put the provideSingleton in the same file as the TestService, everything works!?!?!
Basically to recreate the issue, simply follow the example from here: inversify-binding-decorators - Using #provideFluent multiple times. However there is an issue with the example, so please see this issue: fluentProvide example needed. The above provideSingleton reflects the changes from that issue. Then you simply import the provideSingleton function from another file instead of defining it in the same like in the example.
Can anyone explain to me what I'm missing? Why oh why would certain exported items not bee seen as the type they are? Is there a step I'm not seeing that NodeJS takes to make the item actually exported and therefore different? Can I force the function to resolve as a function so it can be used as such?
ENV:
NodeJS: 10.9.0
Typescript: 3.0.1
Mac: 10.13.16
So it looks like you can get issues like this when NodeJS can't handle a recursive import. I'm not exactly sure how to check you are getting this error other than your symptoms are like what I stated above. Basically the recursion caused my function to not load and therefore undefined is not a function.
It would be easy to notice if you had code like so:
a.ts
import B from './b';
export default class A extends B {}
b.ts
import A from './a';
export default class B extends A {}
In my case, I think my function provideSingleton did not like the file I put it in because of some conflicting code in the file, which all I had was:
import {Container} from 'inversify';
import "reflect-metadata";
import {fluentProvide} from "inversify-binding-decorators";
const container = new Container();
function ProvideSingleton(identifier: any) {
return fluentProvide(identifier)
.inSingletonScope()
.done(true);
}
export {container, ProvideSingleton}
In the end, if this issue comes up, try another file for your function and pay good attention to how the order of the loading happens. Although NodeJS handles recursive imports most of the time, you can still trip it out.

Supporting node and es-module style imports for typescript package

I have a project that I am converting from JS (transpiled via babel) to Typescript. The module consists of a single function and uses an module.exports = myFunction to set it as the default.
The issue that I've run into is that I'd like to preserve require format for node users:
const myModule = require('my-module')
still allow es module aware users (typescript/babel) to import:
import myModule from 'my-module'
I've seen the typescript-library-starter which has a separate build process using rollup to emit UMDified version of the module that translates the module.exports.default = myModule to a node style module.exports = myModule but I'd prefer not to have to include an entirely separate build system for server side code (this is server only, so there's no great need for the tree-shaking/compression that rollup provides).
Currently, I can do something like the following
export = myFunction
which will support the const myModule = require('my-module') use case, but means that TS/es module users will need to do something like:
import * as myModule from 'my-module'
or drop back to a simple const myModule = require('my-module') (which removes the benefits of typescript).
Is there a pattern to distribute my module that works for both node style requires and es-module style imports?
I didn't get a great answer to this so I ended up using export = and import = require
// index.ts
function myModule () {}
export = myModule
Node users can use a regular require and typescript users can use a mix of import and require to get type safety:
// consumer.ts
import myModule = require('my-module')
Which is a pattern I gleaned from theTypescript docs:
When exporting a module using export =, TypeScript-specific import module = require("module") must be used to import the module.
You can see this "live" in my protractor-flake module.

Resources