Has anybody separated TypeScript from Node? - javascript

I'm working with V8 in C++ and was asked about supporting TypeScript, which I'm unfamiliar with. After poking around, it looks like TypeScript runs as JavaScript but seems pretty tied to Node (e.g., for accessing the filesystem). There is no O/S filesystem in my project, which doesn't bother V8 because it isolates itself from such things and lets me translate things like "module names" into database calls rather than filesystem reads.
I see Deno also embeds TypeScript, but since its the same guy that wrote Node, I'm guessing that was a big leg up in providing TypeScript all the Node-cruft it has its hooks into. Seems a shame that TypeScript runs as JavaScript but ends up tied to a particular project rather than being embeddable in any JavaScript environment.
Has anybody written a neat shim for insulating TypeScript from Node to reduce the work of embedding it in a different product? Any ideas/pointers/thoughts welcome...
To be clear: I mean to say "separate the TypeScript compiler from Node". And by embed Typescript, I mean "embed the TypeScript compiler", which I believe is (in its compiled form) a bunch of JavaScript with serious dependencies on Node.

TypeScript already is separated from Node. In fact, it has nothing whatsoever to do with Node.
As an example, see the TypeScript Playground, which is an online IDE written in TypeScript that runs in the browser (no Node in sight), including embedding the entire TypeScript toolchain (compiler etc.) which is also written in TypeScript and also runs in the browser (again, no Node in sight).
In fact, I wouldn't be surprised if while you were writing this question, there was actually TypeScript code running in your browser without Node. (Stack Overflow, Inc. is known to use TypeScript.)
You already mentioned Deno yourself, which includes the TypeScript compiler. No Node in sight.
Many, many web companies all over the world are using TypeScript to do browser-side scripting. Again, no Node in sight.
There is exactly one Node-specific thing in TypeScript, and that is that TypeScript knows how the Node.js module-lookup algorithm works. The only reason this exists is to ensure that if you use Node-style module lookup in your code, TypeScript will use the same algorithm to find the module for type-checking at compile time that Node.js will later use at runtime. Otherwise, it could lead to the situation that TypeScript will at compile-time find a module, type-check it and determine that is type-safe, but then at runtime, Node.js would actually load a different module.
This is undesirable, and that's why TypeScript knows about the Node.js module lookup algorithm. If and when another module lookup algorithm becomes popular, TypeScript will probably also implement that one. It doesn't seem likely, though, since e.g. the ECMAScript committee and the Denon developers have deliberately chosen to design much simpler module lookup. (In fact, ECMAScript and Denon arguably don't have "module lookup" at all, you always need to specify a URI resolving to the exact location of the module file.)
!!! NOTE !!! Whenever I wrote about "running TypeScript code" above, that was a simplification. As far as I know, there does not exist an interpreted TypeScript implementation, so you actually can't "run TypeScript" (in the same sense that you can't "run Go"). You have to compile it first. There are currently two compilers for TypeScript, tsc from Microsoft, and the TypeScript plugin for Babel. Both of those compilers compile TypeScript to ECMAScript. Also, both are delivered in ECMAScript (although tsc is written in TypeScript).
So, as long as you have some way of running ECMAScript, you can also run TypeScript.
There was a project to implement a native TypeScript implementation on top of the Rubinius Language Framework, but that project literally never produced more than a README stating the intention of implementing a native TypeScript implementation on top of the Rubinius Language Framework. I still think it would be nice to have a TypeScript runtime that isn't tied to ECMAScript, though.

Related

Are there any javascript testing frameworks that natively support ES6 imports without babel or another transpiler?

I've developed a node 13.12 application that uses only ES6 style module imports. Given that it's 2020, I'd like to use a testing framework that can natively support those imports without requiring Babel or any other transpiling. Does such a framework exist yet?
At this point (May 2020) I have been unable to locate a testing framework that fits the bill. I ended up rolling my own rudimentary one, wasn't as hard as I thought. Just reimplementing some of the common paradigms like "expect equals" and "expect error". Enough to get some testing done and move on with the real work.

What's the principle that TypeScript includes #types without JS library?

By referring to #types/foo we can use the functionalities of a JavaScript library in TypeScript code. But why? It just defines a bunch of data types and interfaces, but the actual logic is still in the JS code. How can the code run without including the original JS library?
For example, to implement map services in TypeScript, we just include #types/googlemaps without the JS library googlemaps. Why is it so?
The code cannot run without the actual library. In general, you would have a development dependency on the #types and a full dependency on the actual library.
The types are there to back-fill type information for the library to give you the autocompletion, hinting, and type checking - but they don't actually give you anything at runtime.
There are some cases where a package will supply its own types, so you won't need the #types development dependency, but there are almost no cases where the reverse is true (the only exception would where lib.d.ts didn't include a feature supported by browsers etc, and you temporarily used a #types definition to let the compiler know about it).

How to run a node.js application in vert.x?

I'm totally new to vert.x and I'm trying to see if it's possible to bring up an existing nodejs application in vert.x. Following the instructions at http://vertx.io/blog/vert-x3-says-hello-to-npm-users/, I used npm to install vert.x. I can run a simple hello-world app, but running our existing app is proving to be a little challenging. All the vert.x docs I've found talk about writing new apps, not porting existing code.
Oh, and the same code base needs to continue running on existing nodejs systems.
The trouble that I'm seeing is that vert.x won't load nodejs native modules correctly. For example, Vert.x choked on this require:
var fs = require("fs");
After a little searching I found the vert.x equivalent:
var fs = require("vertx-js/file_system");
Perhaps we could create an shim/abstraction layer to wrap the differences. I did a quick one for the file system API and it seems to load correctly. It does seem like writing an entire abstraction layer will be a fair bit of work. But it seems like it would solve the compatibility issue for APIs used within our source.
The real trouble is how to intercept all the require statements in the node_modules directories. Those modules are also going to be requiring lots of other native APIs like the file-system. This seems like a problem that others may have encountered and solved already. Better not to re-invent the wheel.
I could roll my own solution. I don't really want to sed/replace the node_module source except as a last resort. The only other alternative I have thought of is creating a directory of abstractions an inserting that directory name at the head of the NODE_PATH. This solution seems like it might work, but as I mentioned I'm a vert.x noob so I cannot forsee what kinds of pitfalls lie along that approach.
Does vert.x support a shim layer for running nodejs applications?
Short version TLDR:
You can't!
Long version:
Vert.x is not a Node.JS replacement or runtime. Although there are quite similarities and common design choices such as support for CommonJS modules and support for NPM the native libraries are not present. All I/O operations in Vert.x are done using Vert.x API and they do not always relate to the Node counter parts.
Also you should be aware that the JavaScript language version is not the same either, for example Node relies on V8 which nowadays is quite close to fully support ECMA2015 or ES6 for short, Vert.x as a framework running on the JVM relies on Nashorn (the JavaScript runtime from the JDK itself) which is still on ES5.
The idea of supporting NPM in Vert.x was not to emulate Node but to allow the usage of many of its modules (that do not depend on node native modules). For that reason there is a warning on the documentation. But I guess it is not clear.
There are some ways to get most out of NPM and Vert.x, one option is to go 100% ES6 and use a transpiler such as Babel to transpile back to ES5 which will run fine both with Node and Vert.x (until the moment you use a native module).
If you must to use Node, say that you already have an application built on node and the port is not worth (in terms of resouces/time/etc) then I'd suggest to look into the tcp eventbus bridge. This bridge will allow your existing application to produce and consume messages of an existing cluster of vert.x applications.

traceur compiler runtime vs build

As the ES6 spec is nearing completion, I'm investigating get a jump start on ES6 syntax and leveraging traceur compiler to do so.
My question is that I see that tracuer requires a 'runtime' file to be included on the page, is this a shim for some lacking 'core' features like Array/etc OR is this a runtime converter and then the build is just for deploying?
If its just a 'shim' per say, how do you deal with always compiling during development? I know you could do a watch in grunt but for large applications that seems very slow. I also saw you could use a node compiler, but node is not my backend/server tech ( I use IIS, ya i know ).
Thoughts/suggestions?

how to create an environment agnostic javascript library

I'm creating a javascript library, and i want it to be environment agnostic (It will not use DOM, AJAX, or NodeJS api. It will be vanilla javascript). So, it's supposed to run in any javascript environment (browsers, npm, meteor smart packages, V8 C bindings...).
My currently approach is creating git repo with the library, with all the library inside a single global variable, without thinking about patterns like CommonJS or AMD.
Later, i'll create another git repo, using my library as a git submodule, and create what is needed to release it as a npm module. I'm concerned if it's a good approach, i didn't found anyone doing this way.
Pros: code will be vanilla javascript, without awareness of environment patterns. It will not bind itself to CommonJS. It will be repackable (copy and paste or git submodule) to any javascript environment. It will be as small as needed to be sent to browsers.
Cons: I'll have to maintain as many git as environments i want to support. At least a second git repo to deliver on npm.
Taking jQuery as example, it runs in both browser and nodejs, with just one git repo. There is some code to be aware of the "exports" variable to run on nodejs or other CommonJS compatible enviroment.
Pros: Just one git repo to mantain.
Cons: It will be binded to CommonJS pattern (to achieve npm compatibility)
My question is: Am i following a correct (or acceptable) approach? Or should i follow jquery's path, and try to create a single git repo?
Update 1:
Browserify and other require() libraries are not valid answers. My question is not how to use require() on the browser, instead, it's about the architecture pattern to achieve enviroment agnosticism.
Update 2:
Create a browser/nodejs module is not the question, it's known. The question is: can make a real enviroment agnostic library? This example is binded to CommonJS pattern, used in NodeJS.
If you are looking for design recommendation for your future library work then in my opinion you can think-future and just use usual Object Oriented Practices well proven in other languages, systems and libraries.
Mainly concentrate on the UML view of your design.
Forget the "one variable" requirement.
Use features proposed in the planned next version of JavaScript.
http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes
http://wiki.ecmascript.org/doku.php?id=harmony:modules_rationale
There is an experimental compiler available that allows you to write ES6-style code even today (see https://www.npmjs.org/package/es6-module-transpiler-rewrite).
Node.js has a --harmony command line switch that allows for the same (see What does `node --harmony` do?)
So in my opinion correct approach is to follow best practices and "think future"
"Use a build tool" is the answer for this question. With a build tool, you can develop with the best code pratices, without accopling your code to some enviroment standard of today (AMD, commonjs...) and still publish your code to these kind of enviroments.
For example, I'm using Grunt.js to run some tasks, like build, lint, test, etc.
It perform tedious operations (minification, compilation...) like Make, Maven, Gulp.js, and various others.
The build task can handle standards (like commonjs) for the compiled code. So, the library can be totally enviroment agnostic, and the build process handle enviroment adaptations.
Note that i'm not talking about compiling to binaries. It's compiling source to another source, like CoffeScript to JavaScript. In my case, it's compilation of JavaScript without enviroment standard to JavaScript with commonjs standard (to run as a Node.js module).
The final result is that i can compile my project to various standards without messing with my code.
Aditionally, with a build phase i can "think-future", like xmojmr answered and use the EcmaScript 6 features on my JavaScript code, using Grunt plugins like grunt-es6-transpiler or grunt-traceur to compile JavaScript code from ES 6 to 5 (so it can run on enviroments of today)
According to modular your library (if you need modules). Read this question Relation between CommonJS, AMD and RequireJS?
Take bootstrap for example, it uses npm to manage project dependencies and use bower to publish as static content for other web apps.
Take a look at browserify as reference, it's a little heavy because it provides the capability to bundle dependent npm modules as resource for browsers.

Categories