Meteor + flowtype - javascript

I was playing around with all tools/technics I know to try to make Meteor and Flowtype to be friends. I made a meteor package to run flowtype checker as a linter. It works, but brings more troubles than help to my project so far. The problem is that flow does not have an easy way to declare all global libs interfaces, so when it checks my code, it of cause does not know anything about Meteor or Session global variables. Do I have to convert all Meteor API to an interface for Flow?
It also has troubles to understand the way we use to define global vars in Meteor.
Have anybody tried to fix this issues and how?

What you need is an interface file.
You need to do the following:
Declare the .flowconfig file (it's automatically created when you run flow init).
Create a folder to store your interface files that is ignored by Meteor so it doesn't try to parse it. Meteor ignores certain folder patterns, so you could try mkdir .interfaces. Add the folder to the [libs] section of your .flowconfig, comme ça:
[libs]
.interfaces/
Inside, you can create declarations for your global modules. To create one for Meteor, you can try to touch .interfaces/meteor.js and write something along these lines:
declare class Meteor {
isClient: boolean;
}
Let me know if that works. Still learning flowtype myself.

Related

Sharing global between JavaScript files without using modules/exports

I have a self contained JavaScript function in one file, and some Mocha BDD tests in another file that reference it using [nodejs] require(). So in my function under test I export using module.exports. That's all well and good, in the IDE/build.
Now my function under test is actually an external virtual endpoint, which when deployed into a cloud instance, runs standalone inside a JSVM sandbox (Otto) which has no support for exports or modules, and is ES5 based (it does however embed a version of the Underscore library). If I leave the nodejs module definition in there when I deploy to cloud, it kicks off an error at runtime (as Otto doesn't recognise modules). So I want to remove it, and use some vanilla JS mechanism for the linkage back to the Mocha tests and test runner.
So my question is, if I can't use nodejs or requirejs modules, how can I link my Mocha tests in one file to a JS function in another? I had a play with placing a function closure (which most module implementations use) in the file under test, and Otto is happy with this, as its vanilla JS, but any variable with global scope in the file is still not visible from my test file, so there is no linkage.
Any thoughts?
From a quick look at the Otto docs, it looks like Otto only wants whole files and (as you've said) doesn't recogise commonjs modules from node.
If you've got many files I would recommend bundling them into a single file with webpack/browserify/etc, which is how most people convert modules for use in the browser, which similarily doesn't recognise commonjs modules without tooling.
Alternatively, you could convert all the module.exports to simple var declarations, concatenate the files together and hope you don't have a naming collision.
I don't see anything in the docs about having access to a window or global object to hang globals onto, which limits your options
One of my colleague came up with a suggestion to use closure in the file under test which gets deployed into the cloud instance, if you are running under Nodejs, and conditionally do the export. I added the small anonymous closure below to do this, and Otto doesn't complain.
(function () {
if (typeof module != 'undefined') {
module.exports = pdp_virtual_endpoint;
}
}());
Not sure why I didn't think about this earlier :)

Why angular2 sources don't have typescript files in sources [duplicate]

When I work with angular2 code I often need to see the implementation of a class, let's say the Router class.
If I click on the Router type in my IDE WebStorm, e. g. inside the constructor of another class
export class myClass {
constructor(private router: Router) {}
// ...
}
my IDE takes me to the TypeScript definition file router.d.ts inside my node_modules folder. What I want is it to take me to the original router.ts file with the implementation of the router class, not just its definition.
The original .ts file is not included in the node_modules folder structure when you get angular2 from github via the standard package.json suggested in the Angular2 Quickstart. Currently, I have to look up the original code in the official github repo.
Any ideas how to get the .ts files into my node_modules/#angular folder instead of the .d.ts files?
Sadly, it's not possible since no TS files exist. Even if you add them it still not possible since you import real angular paths which always point to the definition files. On top of that the file structure of the project does not correlate to the structure of the import string literals.
Some background and more information
The NPM package does not include .ts files, this is by design from the angular team. Up until some time ago the .ts files were indeed supplied with the NPM package.
The reasoning for removing them is to disable abuse from users accessing private classes and #internal and private APIs which is public methods/properties in the API that are not supposed to be public but must be so other angular internal classes can use them.
We used to see a lot of code samples out there doing things like import { PromiseCompleter } from 'angular2/src/facade/lang'; (before RC0) but this was changed when the project structure had a big structure refactor in RC0. This abuse was wide and it's bad, very bad... For users and for Angular PR.
The Angular project has a complex and robust build process where all of the API is moved from .ts files into d.ts files using an automated process that limits exposure. (public_api_guard)
The end result is d.ts files only.
It's also not possible to clone the git repo and use it since, again, the file structure is way way different so imports will have to change. Most importantly without the build Angular will, most likely, not work.
A solution using a different approach
However, if you debug your app you notice that you reach actual angular core .ts files in the source view of the console, this is because the NPM package comes with source map files that include the whole TS source code. Nice trick they did there.
This is what I use to dig deep into angular, it works quite great and I get a lot from it.
It's not as nice as Goto Declaration but it something...
IMO it's also easier to understand when you step through code...

How to write typescript definition files for new library?

If you were to write your own open source typescript library how would you structure the typescript and the typescript definitions? From what I understand the definition files are really there for the compiler so that when your library gets consumed there is intellisense to help the consumer.
However, how do definition files work internally when developing a library? Would you put all of your types (interfaces, classes, etc) in a {module}.d.ts file and reference the definition file internally so that you don't have to write the types twice (once in the {module}.ts and once in the {module}.d.ts?
In the typescript compiler options what is the point of setting "declaration" to true? To me it doesn't seem helpful to automate the definition file creation if it won't be very helpful (i.e. comments).
If your library has multiple modules would you write a separate definitions for each module and add references between definitions then concatenate them with some automater (i.e. gulp, grunt)?
What is the recommended way to expose your library so that both typescript consumers and javascript consumers can use your library?
How would you write tests in typescript? Would you import the typescript modules in your test files?
When developing your library in typescript you do not use definitions of your own classes. They are 'self contained' and already provide all type information to transpiler/IDE. The definitions are as you have mentioned for external consumers.
The point of setting declaration to true is to get rid of tedious job of collecting type information from typescript classes and pasting it in definition files. As I have said this information is already present in typescript files and can be automatically extracted by transpiler.
Regarding the way of how to organize your definitions and expose them - I am sure there are multiple different ways, one thing for sure - you do not want to write the same class definitions manually in two places. Having said that I can give you a sample of how I expose library project and consume it in another one.
Pay attention to index.ts files there and how the root one is exposed in package.json -> typings field. There you will also find exampls of unit tests for the library via jasmine.
Hope this will give you some information of how to go process with your library development.

How to include external Javascript library in an Ionic 2 TypeScript project?

I build an Ionic Project using Ionic 2, Angular 2 and TypeScript to test the framework a bit. I need to include an external library (ntc.js) to my project, since I need it to name hex colors.
I know including a Javascript library to TypeScript should work, since whatever works in JS works in TS. I just don't want to include it the wrong way.
I tried to add the library to www/build/js, but it doesn't seem to work and it doesn't seem like the good way to do this. I tried to search for ways to do this but found nothing (might be because Angular 2 and Ionic 2 is still fresh).
Things like :
import * as ntc from '../../js/ntc';
doesn't seem to work as well, even if my library is located at the right place. TypeScript doesn't seem to read my file properly, if it reads it at all.
What is the good way to do this? Where should I place my .js file in my project directory?
You import it by adding it to your index.html like any other regular javascript file.
Then in your ts file you do:
declare var Tree:any;
Then in your code, you can use the Tree variable, albeit it exists in the Javascript file. this line of code is basically telling the typescript compiler there is a variable out there Tree which it should ignore.
Besides doing a declare var which tells ts that the variable exists you can use typings of typescript.
By writing
typings install libraryname
In your console you get a file that already has declare var/class and you can see all of its functions/properties when you import it.
import {lib} from 'libraryname';

Substitude one module for another in node.js

If I have a node.js application that has hundreds of files that reference a module (say underscore) and I want to replace that module with another (say lodash) then the obvious way to do this substitution would be a global name replace and switch out the modules in the package.json file.
Is there anyway to just change the module that a name refers to so that when node.js sees require('moduleA') it actually loads 'moduleB' instead? Now I know that this would cause naming hell because anyone working on the project would see require('moduleA') and wouldn't know that the real module being loaded was 'moduleB' so ultimately you'd probably want to go with the first solution. The use case that I'm thinking of is if you want to try a few alternatives for API compatible modules to measure your application's performance (for example) with each module.
If this is an on-going thing and you want to maintain the ability to programmatically switch between the options often, such as in tests:
Instead of using require("underscore"); throughout your codebase, require a local file instead like require("./lib/underscore");, and have that file conditionally re-export underscore or a different library:
if (global.USE_LODASH) {
module.exports = require("lodash");
} else {
module.exports = require("underscore");
}
If this is a one-off thing to try out an alternative library before making the decision to switch, and you want to do this test quickly first without find-and-replacing in all of your files:
Go inside your node_modules folder, delete or rename the underscore folder, and make a symlink named underscore to the replacement module's folder. I don't recommend this as a long-term solution: running npm install again will likely undo this hack, and most projects choose to avoid checking the node_modules folder into their source repository.
Try to use mock-require module.

Categories

Resources