visual studio not finding firebase node module - node.js

I used the command npm install firebase --save from the root of my project folder and a firebase folder was successfully added to my node_modules folder and the packages.json was also updated.
I also use typescript so I have a app.ts file where I try and do import Firebase = require("firebase");
However it doesn't work. I get red squiggles and error saying cannot find external module "firebase".
I have installed express and importing it in app.ts as well and that works fine, no errors.
I have tried to look through the firebase source but its minified and impossible to try and do any finding there, about what is exported and such.
Any ideas about what might be wrong and how I can fix it?

Three things:
You should download the Firebase type definition from Definitely Typed using NuGet, TSD, or some other method.
The Firebase definition on Definitely Typed doesn't seem to be written in an external module form. You may need to add the line export = Firebase; at the bottom of it.
TypeScript currently has odd default behavior with definition files (d.ts) that describe external modules written in JavaScript; it will search in each directory from the directory where the file is back to the root of the current drive looking for a .ts or .d.ts file with a name that matches the name of the thing you've imported. So your best bet is to move the Firebase.d.ts file to the root of the project. If you're interested in a bit more discussion on this, check out https://github.com/Microsoft/TypeScript/issues/2338 . They're working on it.
If you do those three things, it should work.

Related

Node/NPM How to map import paths

I have an NPM module that uses another local NPM module containing shared code. Neither of them are public, this is all local.
I import the shared module in my package.json like so:
"my-shared": "file:../my-shared-code"
When I npm install, my-shared-code gets imported correctly, and I can import code like:
import Blah from 'my-shared/src/sharedTypes';
Problem
I have to use the word "src" in the import. However, when I build I create a build directory, which breaks all these imports!
I was wondering if I could use NPM to map the imports somehow?
Can I make it so I don't have to use the word "src" at all?
Could I just do:
import Blah from 'my-shared/sharedTypes';
and then it magically figures out whether to use the "src" or "build" dirs?
What I tried
I looked into the options for package.json, and there is a "files" property that I thought might help. However I think that just whitelists files.
I also looked into the "main" property, however I'm not "exporting a module". I just have a load of utility files that I wanna be able to import into multiple other projects.
What I'm actually trying to achieve
I'm using typescript, and I've got a front-end and a backend that both share types for certain models, but also share some utility functions.
I want my typescript/react front-end and my typescript backend to be able to import typescript files from another node_package, however it needs to know to use "src" for development and "build" when built for production.
While it's not exactly what you're asking for, you might be looking for npm link. It's not intuitive, but it's what I use for your above situation.
npm-link is a way of registering local projects so that others can reference them. Just beware that reading the docs is important -- using it may impact your local environment in non-obvious ways (especially if you build and publish directly from your machine--versus CI/CD).
In the consumer project you can use path mapping --> https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
As for the package, you can re-export using export * from './my-file' syntax, in a index.ts file (you may need one at each directory). But this is tedious if you have a lot of files. (imperfect example)
Another solution seems to make a script to copy the package.json into the dist folder and make the build there.
There is a similar discussion there: How to npm publish specific folder but as package root

Node Module Paths in Host Application

just like to add a short preface to this question - It may be a true issue of how Node functions, or it may be a fundamental misunderstanding on my part of how modules in Node work.
Recently, I've been working on a new project, specifically, a new Node module that requires some configuration via a .json file. I've had quite a few issues with this, being tested via linking the module to an Angular 2 (v5) project, and attempting to use the module in a service.
As I have the module set up right now, the configuration is loaded immediately as the module is initialized. It attempts to look for a config.json file, and read values from aforementioned file. I have this working, to an extent. I am able to require the file, read the file, and throw an error if the file is not found - but only in the same directory as the module's main file. The issue that I've come across is trying to determine how to find the path to the host project's root path - in this case, the Angular project. For example, say the absolute path to my module's root is /home/dev/angular2project/src/node_modules/module/. How can I determine the root path of the host, in this case /home/dev/angular2project/? What if the module has been installed globally?
I have attempted to use my weak understanding of the path module, paired with various searches of SO, to resolve this issue. I've tried using path.resolve(__dirname) to no avail path.resolve(process.cwd). This works well when debugging the module by itself. When attempted to be run from the Angular project, it simply returns / as the path, despite the actual root of the Angular project being home/dev/Desktop/angular2proj.

Implementing dropbox-content-hasher in electron node.js app

I have a fully functioning Electron App that uses node.js fs module to look at local files. I need to compare these files to files held on Dropbox. I have the Dropbox module all set up and running and have retrieved the content-hash for each file using the filesGetMetadata method and now I need to create a hash, in the same way, for each of my local files to compare to. I have found this code here: GitHub Repo written by Dropbox themselves, but being a relative newbie to Node.js and Electron I have only ever installed and 'required' node modules. This code just requires a js file (I tried to install the module, just in case!) and despite the js file I am implementing it on existing in the same directory as dropbox-content-hasher.js (like the example in the link) I can only get the error Uncaught Error: Cannot find module './dropbox-content-hasher' in my console. I've played with a few attempts at getting the right path but the error looks like it's still looking in the node_modules folder and I've no idea how to change this. Any help appreciated?!
I worked it out through trial and error... making the assumption from all my other requires that 'it' starts by looking in the node_modules folder, the following ended up working:
require('../src/js/dropbox-content-hasher.js');
Just thought I'd update this for anyone in my situation who doesn't quite know enough before embarking on a project!!

Tutorial for creating custom typescript libraries

I am a relative newbie to node.js and typescript and am looking for tutorials and examples for building custom libraries for typescript. I am currently working on a project(switched to WebStorm GUI) that requires I build several microservices and several of the microservices will need to share certain code, i.e., base repository functionality, etc. My though would be to move the code they have in common to a series of separate libraries(projects) and make them into typings and have the projects that need them to install them. Following the example I found here, and using grunt: What is the story for creating and consuming TypeScript libraries?, I was able to generate the .js file and the .d.ts files in a dist folder on the project. There are a few areas that I am confused about:
1) The example makes reference to a "main": "./dist/my.service.js" section in the jsconfig file, how necessary is this file and what should go into it?
2) If all of the files are transpiled and added to the dist folder, will the dependent code still be able to access it or do I have to transpile all of the files to root?
3) After I have have all of the file successfully transpiled and moved to the proper location, how do I install them to the dependent project if they are local and not up on the npm or Definitely Typed, etc.?
Well if you would like to see an example project that I am currently working on that at the moment can be installed with npm is binary-type-tree. There are some things I need to fix but overall the project is working great. You can see my setup for Jest in my package.json. Along with how to set up the types and the main.
Depending on what your library will be focused on you will want to choose the appropriate module system. Right now commonJS is the most common for npm packages. Although you can only compile to one file with system or amd.
As for compiling you do not need gulp/grunt you can use Webstorms IDE to compile your files. Simply open up the Webstorm settings "Languages and Frameworks" and select "Typescript" there you will see enable Typescript compiler.
The example given is very old. Typescript had a major update to how typings work back in October of 2016, they moved to Typescript 2 I think, or maybe it was November. Anyway when you google search Typescript I would set the filter to not before that time.
1.
The main in the package.json of the Typescript project should point to the entry point of your library, or your executable. Since mine is a library it points to the compiled folder's index file. The file does not exist in my repo but it is there upon compilation.
2.
This I believe is answered depending on your build. In my build as an example I use module system es6 as you can see in my tsconfig.json file. This uses the ES6 module system.
if you would like to use commonjs the structure of my project will still work properly except you will need something like Systemjs or Babel on the front end.
3.
This one is a bit unknown to me but what I have done for only testing is copy my directory into the node modules of another project I am working on. Now to require the project you do not need a #types since I have "declaration": true in my tsconfig.json file. The package.json of my project has a "types": section which points to the compiled .d.ts file. The project that is requiring this new TS package, if also written in TS, will have to have the typeRoots and types section in the tsconfig.json file. Once this is all set up you should be able to require it just fine.
Make sure that the src of all your TS files is declared in the includes section of the tsconfig if your files are not compiled to root. Otherwise your project will have to require in files in an odd format like import * as BTT from "lib/basic-node/avl-tree";. Which is not what I wanted, once I added this it became import * as BTT from 'binary-type-tree';.
The "main" field in your package.json tells Node's module system what file to require when calling require(), so you will definitely need it. You point that field to a transpiled file, which will also contained transpiled references to your other transpiled TypeScript files, so you shouldn't have to add anything to root.
If you're trying to use the package from another project, you simply reference it as a dependency using NPM the same way you would with any other JS project.
{
"name": "dependent-project",
"dependencies": {
"bar": "file:../typescript-project"
}
}
Again, Node will know how to load the TypeScript project because you've specified the transpiled entry point in the main field.
There are several things you must consider:
In package.json, you must set some things up (example):
main property to point to your UMD compatible bundle
module property for ES5 module. Then modern workflows can benefit from it, for example to apply Tree Shaking
typings pointing to your .d.ts file (which should be generated)
That counts on a build process, which can be made with a module bundler, such as RollupJS or Webpack. They can generate source maps and so on.
As per question 3: you can install packages from local or even from Git repos. In your package.json, for example:
"your-library": "git+https://github.com/alexjoverm/typescript-library-starter.git"
I'd suggest you to take a look at TypeScript Library Starter. You can find there everything you need. It has configured out of the box:
Automatic releases
Package.json configuration
Universal module bundles
Source Maps
Typings (.d.ts) auto generated
Docs using TypeDoc
Tests and coverage

Typescript Custom Node Modules

I'm trying to fully understand how Typescript works in a Node.js project. To accomplish this I have created my own custom_modules folder with a separate #types folder underneath for my declarations while the actual implementation is under the custom_modules attempting to mimic the structure of node_modules. My goal is to make this module usable in the project non-relatively with separate declaration and implementation. I have been able to setup a project that compiles with this setup, but running it errors with:
Cannot find module 'foo'
The source is available here:
https://github.com/anorborg/learn-ts
The node_modules folder is a somewhat special case in how typings get handeled. This is a result of how nodejs works. Take a look at the [module-resolution] doucmentation (https://www.typescriptlang.org/docs/handbook/module-resolution.html), it describes more in depth how module resolution work in typescript.
But in short to answer your question: you can not use non-relative module paths in this way. Node will look for the file in node_modules at runtime, and will not find it there. The paths property in the tsconfig.json is there to solve problems that can occur in other cases, as when targeting RequireJS or SystemJS for example, but not when targeting node.

Resources