Firebase Functions emulator Error: Cannot find module '../service-account.json' - node.js

I am trying to execute test functions with the firebase emulators:exec, the emulators start up successfully but are unable to load the functions code because of the following error
Error: Cannot find module '../service-account.json'
I have gone through npm install, npm run-script lint, npm run-script build etc many times, also wiped my node_modules folder and run npm install again, as well as restarting vscode, but I am repeatedly getting the error.
I have a functions folder in which the service-account.json is located:
├─ firebase.json
├─ firestore.indexes.json
├─ firestore.rules
├─ functions
│ ├─ .eslintrc.json
│ ├─ .gitignore
│ ├─ firestore-debug.log
│ ├─ lib
│ ├─ node_modules
│ ├─ package-lock.json
│ ├─ package.json
│ ├─ pubsub-debug.log
│ ├─ src
│ │ ├─ controller
│ │ │ ├─ functions
│ │ │ └─ shared.ts
│ │ ├─ index.ts
│ │ ├─ model
│ │ ├─ play-billing
│ │ ├─ service-account-firebase.json
│ │ ├─ service-account.json
│ │ └─ typings.d.ts
│ ├─ test
│ ├─ tsconfig.dev.json
│ └─ tsconfig.json
├─ gradle
The service-account.json should be accessed from the shared.ts file:
import * as functions from "firebase-functions";
import { PlayBilling } from "../play-billing";
import * as serviceAccountPlay from "../service-account.json";
import { InstanceIdManager } from "../model/InstanceIdManager";
import { ContentManager } from "../model/ContentManager";
/*
* This file defines shared resources that are used in functions
*/
// Shared config
export const PACKAGE_NAME = functions.config().app.package_name;
...
I have double checked the path to the file is correct by hovering my mouse over it and it shows the full path correctly.
I have checked my dependencies and everything seems to be in place:
├── #types/chai#4.2.15
├── #types/mocha#8.2.1
├── #types/node#14.14.31
├── #typescript-eslint/eslint-plugin#4.15.1
├── #typescript-eslint/parser#4.15.1
├── chai#4.3.0
├── copyfiles#2.4.1
├── eslint-plugin-import#2.22.1
├── eslint-plugin-promise#4.3.1
├── eslint#7.20.0
├── express#4.17.1
├── firebase-admin#9.5.0
├── firebase-functions-test#0.2.3
├── firebase-functions#3.13.1
├── googleapis#67.1.0
├── mocha#8.3.0
├── ts-node#9.1.1
└── typescript#4.1.5
I particularly puzzled because I have exactly the same structure, dependencies & functions code in another project, where it is working fine!
What am I missing?
I have searched through other answers and can't find anything that I haven't already checked.
Note that the service-account.json is the exact same one that I am using in the other project where I am able to emulate the test functions without issue.
UPDATE
After deleting my lib folder and rebuilding it, I now have a different error with the emulators loading my functions code:
It looks like you're trying to access functions.config().app but there is no value there.
My tsconfig.json is now showing an error on the opening brace:
Cannot find type definition file for 'express-serve-static-core 2'
but I cannot see anything wrong.
{
"compilerOptions": {
"lib": [
"es6",
"ESNext.AsyncIterable"
],
"module": "commonjs",
"noImplicitReturns": true,
//"noUnusedLocals": true,
"outDir": "lib",
"sourceMap": true,
//"strict": true,
"target": "es6",
"resolveJsonModule": true,
"esModuleInterop": true
},
"compileOnSave": true,
"include": [
"src",
"test",
"./typings.d.ts",
]
}
my lib file structure is as follows:
.
├── src
│ ├── controller
│ ├── index.js
│ ├── index.js.map
│ ├── model
│ ├── play-billing
│ ├── service-account-firebase.json
│ └── service-account.json
└── test
└── play-billing

I eventually fixed all of my problems as follows:
Firstly, I deleted the entire lib folder, and then ran
npm run-script build
to build a new lib folder.
This fixed the error for the emulators to find the module '...service-account.json'
I had an error with finding index.js, which I fixed by correcting an error in the package.json file, for the path "main" to index.js
I still could not run my functions from the emulators - I found the solution was to run the following command in the functions directory of my project.
firebase functions:config:get > .runtimeconfig.json
(see this answer here: https://stackoverflow.com/a/42978220/15046746)
Now when I run firebase emulators:start, all of my functions are correctly initialised, and also I can run emulators:exec to run all of the test functions in the emulators.

If I'm reading this correct your service account file is inside the src/ directory. But once your function is built, the compiled code gets deployed to the lib/ directory. There your relative path is no longer valid.

Related

How to configure Eslint + Prettier for backend/frontend project

I have a project with the following (very schematic) file structure:
.
├── backend
│ ├── config
│ ├── controllers
│ ├── middleware
│ ├── models
│ ├── routes
│ └── server.js
├── frontend
│ ├── node_modules
│ ├── package.json <== Eslint + Prettier here
│ ├── postcss.config.js
│ ├── public
│ ├── src
│ ├── tailwind.config.js
│ └── yarn.lock
├── node_modules
├── package.json <== Eslint + Prettier here
└── yarn.lock
The backend is an express server, the frontend a React app.
I want to have my eslint and prettier configs in both package.json files (different rules apply, indicated in the tree above) but if I cannot compile because they conflict.
I added these to both package.json files:
"eslintConfig": {
"extends": "#gbrachetta/eslint-config",
"rules": {
"sort-imports": "off",
"import/order": "off"
}
},
"prettier": "#gbrachetta/prettier-config"
but as mentioned above the two cannot coexist and compilation fails, so I have to delete the config above alternatively from one or the other package.json, depending on which part of my code I'm working on, and thus either frontend or backend don't have eslint/prettier linting.
I'm on VSCode and rely heavily on the error/warning system VSC provides.
Is there a way to keep them both, and eventually have different rules depending on if it's frontend or backend?

For all subfolders in a Node.js project, use global custom entry point for require

Question
Is it possible to configure a global, custom entry point to be used by require for all subfolders in a Node.js project?
Rationale
When working in Node.js, I like having my index.js file as the topmost file in each subfolder in my IDE.
However, depending on the IDE and the way it sorts files, this is not always possible (for example, VSCode has several sorting options available, and none of them can achieve this).
To achieve that, I prefix it with _index.js, but then lose the built-in capability of require to recognize it as the default entry point.
Although this can be mitigated by adding a package.json into each subfolder, with a main property directing to the entry point file - I'd like to know if there's a way to define a "global" custom entry point, be it in the topmost package.json or using some npm package which I'm not aware of.
Example
Let's say I have the following folders structure, and assume that our IDE sorts files alphabetically:
MyApp
├── app.js
├── package.json
├─┬ featureA
│ ├── func1.featureA.js
│ ├── func2.featureA.js
│ └── index.js
└─┬ featureB
├── func1.featureB.js
├── func2.featureB.js
└── index.js
To keep index.js as the topmost file, we prefix it with an underscore, and use a package.json for each subfolder to define it as an entry point:
MyApp
├── app.js
├── package.json
├─┬ featureA
│ ├── _index.js
│ ├── func1.featureA.js
│ ├── func2.featureA.js
│ └── package.json
└─┬ featureB
├── _index.js
├── func1.featureB.js
├── func2.featureB.js
└── package.json
The package.json for both featureA and featureB is identical:
{
"main": "_index.js"
}
That package.json is necessary so that we can use require in the following way in app.js:
// app.js
const featureA = require('./featureA');
const featureB = require('./featureB');
But can these two package.json files be replaced with some "global" alternative?

Typescript folder structure in a project with client, server and shared code

I have a project with the following structure
project
├── client
│ └── src
│ ├── index.js
│ ├── and.js
│ ├── some.js
│ ├── other.js
│ └── files.js
├── public
├── server
│ ├── out
│ │ ├── index.js
│ │ └── any.other.dependency.js
│ ├── src
│ │ ├── index.ts
│ │ └── foo.js
│ └── templates
├── shared
│ └── constants.js
└── mutliple.config.files.json
My goal is to have a server with all the server logic inside server/src, which serves different html files from server/templates. I want the server code to use Typescript, and the compiled output should go to server/out.
There's also the client side of the application, which lives in client/src. The logic there is complex enough that I decided to use webpack for bundling. I might even add some react in the future. All this code is compiled by webpcak and the resulting files live in /public.
I also share some constants between the client and server logic, and I decided to put them in ./shared. I might want to add some utilities there in the future, so let's assume it's not just constants.
At some point in the future I'd like to migrate the whole project to TS, but I'm not close to that yet.
How can I achieve this with Typescript?
I have the webpack side sorted out. My problem comes with the TS compiler. I can't manage to get it working because shared is out the compilerOptions.outDir, but if I set it as the whole project folder I end up with a crazy server/out folder structure. Something like server/out/server/src/index.js
My tsconfig.json looks like this:
{
"extends": "#tsconfig/node12/tsconfig.json",
"include": ["server/src/*", "shared/*"],
"exclude": ["node_modules"],
"compilerOptions": {
"allowJs": true,
"noImplicitAny": false,
"outDir": "./server/out/",
"rootDir": "./server/src"
},
}

can't copy deep folder structure with gulp

I"m getting the strangest behavior.
I have a gulp file it has three tasks. clean, copy a bunch of stuff to a folder, copy entire folder to other destination.
It seems to copy MOST of the entire folder, but leaves certain folders empty. There is no rhyme or reason, they are all folders that container javascript files and folders. Makes no sense.
Here's what I got.
gulp.task('clean', function(cb) {
del([config.get("deploy.output.deploy"), config.get("deploy.buildDirectory")],{force:true}, cb);
});
gulp.task("copy-source",["clean"], function () {
gulp.src("src/**")
.pipe(gulp.dest(config.get("deploy.output.app")+"/src"));
gulp.src(["package.json", "server.js", "bootstrap.js"])
.pipe(gulp.dest(config.get("deploy.output.app")));
gulp.src("config/**")
.pipe(gulp.dest(config.get("deploy.output.app")+"/config"));
return gulp.src("deploy/*")
.pipe(gulp.dest(config.get("deploy.output.deploy")));
});
gulp.task("copy-to-buildDir",["copy-source"], function () {
return gulp.src(config.get("deploy.output.deploy")+"/**")
.pipe(gulp.dest(config.get("deploy.buildDirectory")));
});
gulp.task("deploy",[ "copy-to-buildDir"]);
src folder structure looks like this, more or less obviously psudo structure
output
└── app
├── config
│ └── file7.js
├── src
│ ├── modules
│ │ ├── ges
│ │ │ ├── file1.js
│ │ │ └── file2.js
│ │ └── file3.js
│ ├── file4.js
│ └── controllers
│ └── file5.js
└── file6.js
dest folder structure looks like this
output
└── app
├── src
│ ├── modules
│ │ └── EMPTY
│ └── controllers
│   └── file5.js
└── file6.js
so modules and controllers are sisters, and one has the files one does not. makes no sense.
if you have any ideas I'd greatly appreciate it.
also the building up of the src (the first task) works every time. Also
I've tried just about every concievable permutation of the dependencies e.g. ["clean"]
below task definition is not correct
gulp.task("copy-source",["clean"], function () {
gulp.src("src/**")
.pipe(gulp.dest(config.get("deploy.output.app")+"/src"));
gulp.src(["package.json", "server.js", "bootstrap.js"])
.pipe(gulp.dest(config.get("deploy.output.app")));
gulp.src("config/**")
.pipe(gulp.dest(config.get("deploy.output.app")+"/config"));
return gulp.src("deploy/*")
.pipe(gulp.dest(config.get("deploy.output.deploy")));
});
you are doing 4 copies but checking the end of only final copy stream.
Either separate them into 4 tasks or combine the src and create single task to solve the issue

Ignore folders in .couchappignore

My CouchApp has the following folder structur, where files inside the app folder are compiled into the _attachments folder:
my_couchapp
├── _attachments/
│ ├── app.js
│ ├── app-tests.js
│ └── index.html
├── app/
│ └── app.js
├── Assetfile
└── views/
I want to exclude the file Assetfile, _attachments/app-tests.js and the folder app.
My current .couchappignore looks like this:
[
"app",
"Assetfile",
"_attachments/app-tests.js"
]
But this doesn't seem to work. All files beginning with app inside the _attachments folder are not pushed.
How do I define folders and specific files to be excluded when the CouchApp is pushed via couchapp push?
After a little more experimentation I found a way: the app folder can be excluded by specifying app$, so the final .couchappignore now looks like this:
[
"app$",
"Assetfile",
"app-tests.js"
]
In case you arrived here looking for a way to ignore subfolders, you are just like me. Here's my problem:
my-couchapp/
├── node_modules/
│ ├── react.js
│ ├── url/
│ ├── browserify/
│ └── coffee-script/
├── app/
│ └── app.js
└── views/
I wanted to include node_modules/react.js and node_modules/url/ (and all subfolders), but didn't want to include node_modules/browserify/ and node_modules/coffeescript.
I was trying
[
"node_modules/browserify$",
"node_modules/coffee-script$"
]
but it wasn't working.
[
"node_modules\/browserify",
"node_modules\/coffee-script"
]
also didn't work.
The only thing that worked was
[
"browserify",
"coffee-script"
]
I don't know why.

Resources