Transforming TypeScript into JavaScript - javascript

I'm wondering how is it possible to transform the TypeScript into JavaScript in a cross platform manner. I'm aware about availability of node package manager for typescript, but are there any other alternatives which can be used on the server side?

The TypeScript compiler is built in TypeScript, and hence is available as a JS file (tsc.js) that can be run using just about any ES3-compiliant VM or JS implementation.
That said, the compiler's current file I/O infrastructure only supports Node and Windows Scripting Host file APIs. If you'd like to recommend for support for another environment, feel free to reach out to the team at our GitHub site (Formerly CodePlex)

Short version: use Node if you can. It's becoming unavoidable nowadays.
Maybe it's not the answer you want, but as everybody mentioned, the compiler is a JS file, so, your options are the options of executing a JS file.
In Windows, there are 2 obvious ones, Node, and Windows Script Host.
You know about node already, the other option is a component that comes with all versions of Windows (I think), you can do it like this:
cscript path/to/tsc.js source-file.ts
You can see all compiler options by just:
cscript path/to/tsc.js
On Linux I assume you should be able to use (in addition to node):
V8 standalone shell, replace node or cscript with v8-shell
ExecJS https://github.com/sstephenson/execjs
Any other JS runner available on the selected platform (another answer mentioned Rhino for example)
Update: Another answer suggests the compiler API is only compatible with node and Windows Script Host (cscript tool), so, if correct, then on Linux you'll need Node to compile TypeScript.
If you are looking for something like apt get tsc (or whatever the Linux/Mac package managers are like), I think there isn't.
I remember reading somewhere that the I/O is optimized for Node and Windows Script Host, so, if you have problems with options, you'll probably end up with Node if seeking platform independence.
Update: Another answer here confirms the same about compatibility.

Concretely, on the server (assuming your server has Node.js available), you'd simply run:
node path/to/tsc.js yourFile1.ts yourFile2.ts [etc]
You can run that command without any input filenames to see the command-line help for tsc.js.

From the command line you can use ts-node:
npm install ts-node
Then call the command like this:
tsc file.ts --outFile file.js

I have a project which compiles Typescript to Javascript in Java:
https://github.com/martypitt/typescript4j
As discussed in other answers, this makes use of Rhino, so has no dependencies on npm or node.
Here's an example:
// Instantiate the compiler:
TypescriptCompiler compiler = new TypescriptCompiler();
// Compile a string:
String output = compiler.compile("class Greeter { greeting: string; }");
// Or, compile and output to a file:
compiler.compile(new File("example.ts"), new File('output.js'));
I use it in another project - 'Bakehouse' to perform on-the-fly compilation of typescript resources within Spring environments

If it's Java that you need to target then you could run tsc.js with the Rhino engine as part of your build process.

To compile ts -> js: node is available for all common platforms, so I fail to see why you'd want to have a tsc.java when you already have a tsc.js. Installing node is no big deal. In fact, it's easier than Java.
Once you have your proj.js file, you can then copy it to which ever deployment platform you wish to use.
From my point of view, JavaScript - or more accurately ECMAScript is an alternative to Java. So I'm happy that I don't have to wrangle JVM etc to use the tool. But if you prefer Java, then why even bother with JS?

SublimeText2 Trick
You can transpile typescript to javascript directly from SublimeText2 (you need node) :
Create a Typescript.sublime-build file in /Sublime Text 2/Packages/User with this content :
{
"cmd": ["tsc", "$file"],
"selector" : "source.ts",
"path": "/usr/local/bin:$PATH"
}
then, now, you can transpile your code with ctrl+B or cmd+B

I've been playing around with this, and can compile TypeScript with javascript with the following code:
<script src=typescript.js></script>
<script>
var scriptText = ""
+ "/// <reference path=\"test.ts\"/>" + "\r\n"
+ "class Car {"
+ " constructor (private name: string) { } "
+ " getName() { "
+ " var juice = new Juice();"
+ " return name; "
+ " } "
+ "} "
+ "var car = new Car('Subaru Impreza');"
+ "console.log(car.getName());";
var TextWriter = function () { };
TextWriter.prototype = {
collected: '',
Write: function (sc) {
this.collected += sc;
},
WriteLine: function(sc) {
this.collected += sc + '\n';
},
toString: function() {
return this.collected;
}
};
var output = new TextWriter();
var tsc = new TypeScript.TypeScriptCompiler(output);
var script = tsc.addUnit(scriptText, "");
tsc.emit();
console.log(output.toString());
</script>
It's not exactly ideal though. I'm trying to get something running so I can convert TypeScript to JS within C# (using Javascript .NET), but i'm getting a stack overflow on the ts.addUnit call.

You probably don't wanna use ts-node, because it is slow, instead follow following steps for fast .ts files compilation (Make sure node is installed):
npm i -D #types/node typescript nodemon
npx tsconfig.json and select node from the list. You are free to modify it as per your needs.
Create a file names src/index.ts in your project root.
Then in your package.json, add the following 2 scripts:
"scripts": { "watch": "tsc -w", "dev": "nodemon dist/index.js" },
Then use:
npm run watch
npm run dev
And, it will automatically look for changes in .ts files and you can see the compiled file output in the terminal as you go!

This is what worked for me:
First, installed the typescript node module >> npm install -g typescript. This gives a command line utility tsc.
Next, tsc gulpfile.ts gulp-config.ts typings/tsd.d.ts
this will transpile the gulpfile.ts and gulp-config.ts files to gulpfile.js and gulp-config.js. We supply the typings/tsd.d.ts file as reference for correct transpilation.
The typescript node module covers many options >> tsc -h to specify output directory or file, etc..

If you are using "firebase -tool" you can use
npm run build
inside your functions directory.

Related

Generate Javascript source map without adding NPM to project

My web project serves static web pages and scripts. There is no preprocessing done at all. All changes are done in the client.
It has a main page that lists some other pages. When the user clicks a link, jQuery-UI will load the associated HTML page and any linked Javascript/CSS files.
This works great, and gives us flexibility to add/remove new pages with ease. The problem is when we want to debug the loaded JS and the browser appears not to know about it.
Took me a while to find out about Source Maps, and then find out they are all geared towards framework projects like Angular and React.
We don't want that in this project. Just basic HTML & JS that we can plug in and reload. I realize we may need to run an external command to generate the source maps, but it must be a free standing tool - no NPM or frameworks.
It's an internal web project, so security/privacy is not a concern. We want the clients to see the source code if they need to.
I know there are a lot of Questions about JS source maps, but every single one that I've found assumes using some framework tools. We have no framework and do not want one in this project.
Any suggestions on how we can generate the source maps we need, or do you know of any alternative to debug simple JS loaded via jQuery?
First and foremost, you do not need to use Angular/React for sourcemaps to work. These are just a common use case.
Secondly, NPM is exactly what it says it is; a package manager. So you don't need NPM either.
What you need is a build process. You're quite clear that you don't want to minify the js, but you do want sourcemaps. This is a common configuration used to debug js, and is typically accomplished by "building" or "Uglifying" the code with all of the optimizations disabled.
You could likely avoid NPM entirely if you were willing to use the Closure Compiler, but that is a can of worms and I'd suggest you avoid.
Instead I suggest using installing Uglify* globally* (per dev machine) with NPM. This is a "once per machine" step.
npm install uglify-js -g
*: Hopefully this side steps your NPM-less requirement. I did experiment with cloning the Uglify repo directly, but even then you'd need to get it running, and to do that, at a minimum, you'd want to install its dependencies with NPM). I'd love to be proven wrong about this, but I figured it was very unrelated to this post.
And then writing a build script using that. I've attempted to gather the parts for you here:
File: gen-map.sh
#!/usr/bin/env bash
uglifyjs file1.js --config-file gen-map.json \
-o file1.min.js \
--source-map "root='http://foo.com/src',url='file1.min.js.map'"
cat file1.min.js
File: gen-map.json
{
"compress": false,
"output": {
"beautify": true
},
"sourceMap": {
"content": "content from file1.js.map",
"url": "file1.js.map"
}
}
File: file1.js
var b = function() {
console.log('b');
};
function c() {
console.log('c');
};
console.log('a');
b();
c();
(function() {
console.log('d');
})();
File: file1.min.js
var b = function() {
console.log("b");
};
function c() {
console.log("c");
}
console.log("a");
b();
c();
(function() {
console.log("d");
})();
//# sourceMappingURL=file1.min.js.map
File: file1.min.js.map
{"version":3,"sources":["file1.js"],"names":["b","console","log","c"],"mappings":"AAAA,IAAIA,IAAI;IACNC,QAAQC,IAAI;;;AAGd,SAASC;IACPF,QAAQC,IAAI;;;AAGdD,QAAQC,IAAI;;AACZF;;AACAG;;CACA;IACEF,QAAQC,IAAI;EADd","sourceRoot":"http://foo.com/src"}
*: Uglify-es if you're using ES6 features.
After that the only thing left to do would be to update the paths, filenames, and actual script tags. Using this config you must still serve the min.js file, although it seems possible that manually tagging your JS file to point to the map might work...
With this config, you'll need to keep your built files up to date by running:
🐚 ./gen-map.sh
Doing this with npm and gulp would be simpler, but, if you don't mind another package, there are 2 generic "files been changed watchers" that I can suggest;
Nodemon:
🐚 nodemon gen-map.sh
entr
🐚 entr gen-map.sh

How to compile npm package from src (source) for both lib (module) and dist (browser)?

I'm writing a small class object in JavaScript that I wish to be able to use both for node applications but also as a standalone browser JavaScript file.
I think I've found a solution, but I'm not really sure if that's how it's supposed to be.
Let me try to explain how the directory looks.
Ok, I've got my main file inside a directory called src/index.js.
This file consists of a simple ES6 Class, which I export with ES6 export (following AirBnb Use Import/Export).
export default Person class {
constructor() {
// some code here...
}
getExampleMethod() {
// some code here...
}
}
Okay. So this code will not run in the browser because browsers do not support "export default" and it's ES6 so I should transpile it to ES5 using Babel.
But using Babel with --presets=es2015 will not cut out the "export default" so browsers will still throw an error. So I solved this using a package called "replace" which simply search and replaces that string before transpiling it using Babel.
In my package.json it looks like this:
"build:dist": "babel src -d dist --no-babelrc && replace 'export default ' '' dist/index.js && babel dist -d dist --presets=es2015",
So basically first moving the file, then removing the "export default " line, and the transpiling it... And this works!
For the lib directory I do this:
"build:lib": "babel src -d lib --plugins=add-module-exports,transform-es2015-modules-commonjs",
So basically move the file and transpile it, adding "module exports" and into a "commonjs" module.
This works... But it does not really feel like the way to do it? I've tried using Browserify, Webpack etc, but when doing that, I do not seem to be able to initiate a new object from my class? It gives me an error message saying "new Person()" is not defined or something similar to this.
How am I suppose to write my source code in plain ES6 style, transpiling it to both to be used in the browser and for node usage, while being able to have an API that looks like this: "var person = new Person();"?
Really, my question is maybe more aimed to be: How do I turn src/index.js into both browser and node compatible files?
Thanks a lot!

Using a JavaScript npm Package

tl;dr: I come from a Python background - where I would basically use pip install foo, then use the python interpreter to run code that uses foo. How does this translate to the world of JS?
I'm trying to use this package: https://github.com/skatejs/dom-diff
And execute this simple code example given by the author -
/** #jsx h **/
import { diff, h } from 'skatejs-dom-diff';
const source = <div><span>source</span></div>;
const target = <div><span>target</span></div>;
const instructions = diff(source, target);
Now I'm extremely new to the world of JS and just cannot figure out how I can run this code.
I was of course able to install this using npm install skatejs-dom-diff, but what now? I figured I might be able to run the code using node. So I saved the above code into foo.js and then executed node foo.js
% node foo.js
/Users/foo/Dev/DomDiff/skatejs_dom-diff/foo.js:2
import { diff, h } from 'skatejs-dom-diff';
^^^^^^
SyntaxError: Unexpected token import
When I tried to debug this, I kept going down the rabbit hole of Babel, JSX, ES6 etc etc, but to no real benefit since I'm even more confused still can't understand how to run this JS code.
What you are trying to use here is a syntax for EcmaScript, which is a super-set of JavaScript. In order to execute your ES code you need a transpiler like Babel in order to convert your code from EcmaScript to Pure JavaScript, which can then be understood by node or your browser.
But, I recommend you to use pure JavaScript if you don't need to follow an Object-Oriented paradigm or the salient features of EcmaScript, that allow JavaScript to become a multi-paradigm language.
You can check out the major differences between the 2 here.
You can visit this website to understand more about jsx and how to use it.
----Edit----
To fix your code you can follow these steps:
Open cmd and change directory to your project.
Type the command npm i -g browserify
Type the command npm i -D babelify babelify-preset-2015
Add the following code and save it as test.js
test.js
/** #jsx h **/
import { diff, h } from 'skatejs-dom-diff';
const source = h('div', h('span', 'source'));
const target = h('div', h( 'span' , 'target'));
const instructions = diff(source, target);
console.log(instructions);
Type the command browserify test.js -o bundle.js -t [ babelify --presets [ es2015 ] ]
Create a file index.html and add the following code to it.
index.html
<html>
<body>
<script src="bundle.js">
</script>
</body>
</html>
Open index.html in your browser and check the output in console (Right click->inspect->console)
Tada! :)

How to compile or check syntax error in Node.js application

I have created a node.js application. I need to compile or do a check whether syntax error occurs before running the node.js service.I need to integrate this in jenkins. Kindly guide me to validate the node.js application
Look into TypeScript. It is a language which allows you to get autocomplete with types and fails compilation if you have some syntax errors. It is a superset of JavaScript and transpiles to JavaScript.
Node.js provides CLI option --check or -c for checking a given file for syntax errors without running it. When working with Linux or MacOS a command like the following one helps with checking all obvious javascript files in a folder for containing basically working code:
find -name "*.js" | xargs node -c
using eslint package https://www.npmjs.com/package/eslint
It's a very common library to check the syntax of any JS/TS framework
You can use 'node-syntax-error' module.
it helps you to detect and report syntax errors in source code strings.
When you type node src.js you get a friendly error report about exactly where the syntax error is. This module lets you check for syntax errors and report them in a similarly friendly format that wrapping a try/catch around Function() or vm.runInNewContext() doesn't get you.
For example:
var fs = require('fs');
var check = require('syntax-error');
var file = __dirname + '/src.js';
var src = fs.readFileSync(file);
var err = check(src, file);
if (err) {
console.error('ERROR DETECTED' + Array(62).join('!'));
console.error(err);
console.error(Array(76).join('-'));
}
Using
node --check
Only finds very grave errors and can be tricky to execute.
I would suggest to use a linter like 'eslint'. Because:
It integrates easily with (npm lint or yarn lint)
It catches almost all possible errors (way more than node -check)

How to do JSLint in Vim

I spend my days in vim, currently writing a lot of JavaScript. I've been trying to find a way to integrate JSLint or something similar into vim to improve my coding. Has anyone managed to do something like this?
I tried this: Javascript Syntax Checking From Vim, unfortunately the output is very crude.
The best-practice way IMO is:
Install Syntastic Vim plugin - Best syntax-checker around for plenty of languages, plus it integrates with Vim's location-list (==quickfix) window.
I recommend cloning from the GitHub repo and installing using a plugin manager like Vundle or Pathogen, since it's more frequently updated.
Choose one of the two options below:
JSLint
Install jsl (JSLint executable) using your favorite package manager (Ubuntu's apt-get, Mac's home brew, etc.).
Community-driven jshint.com (better than JSLint)
Install node.js using your favorite package manager.
Install Node Package Manager: 'curl https://npmjs.org/install.sh | sh' EDIT: npm IS PART OF node.js NOW
See http://npmjs.org for more info.
Install jshint globally: 'npm install jshint -g'
Put your jshint config file in your $HOME dir: '~/.jshintrc'
Here's JSHint-Node's example configuration file, they pulled from mine and added more stuff.
Here's my original copy, which you can also start from.
Overwrite Syntastic's syntax_checkers/javascript.vim file with this one - EDIT: NO LONGER NECESSARY WITH NEWEST SYNTASTIC VERSION.
Script copied from FactorayLab's really helpful Vim GitHub page, which I recommend every Vim user to check out.
Enjoy! :)
You can follow the intructions from JSLint web-service + VIM integration or do what I did:
Download http://jslint.webvm.net/mylintrun.js and http://www.jslint.com/fulljslint.js
and put them in a directory of your choice.
Then add the following line to the beginning of mylintrun.js:
var filename= arguments[0];
and change last line of code in mylintrun.js ("print( ...)") to:
print ( filename + ":" + (obj["line"] + 1) + ":" + (obj["character"] + 1) + ":" + obj["reason"] );
This makes in mylintrun.js output a error list that can be used with the VIM quickfix window (:copen).
Now set the following in VIM:
set makeprg=cat\ %\ \\\|\ /my/path/to/js\ /my/path/to/mylintrun.js\ %
set errorformat=%f:%l:%c:%m
where you have to change /my/path/to/js to the path to SpiderMonkey and /my/path/to/mylintrun.js to the path where you put the JS files.
Now, you can use :make in VIM and use the quickfix window (:he quickfix-window) to jump from error to error.
Another option is jslint.vim from Jesse Hallet. It's available on GitHub and works with or without Vim's QuickFix window. It's a nice plugin!
I've been very happy using node-lint
sudo npm -g install jslint
Then whack this somewhere in your .vim
set makeprg=jslint\ %
set errorformat=%-P%f,
\%E%>\ #%n\ %m,%Z%.%#Line\ %l\\,\ Pos\ %c,
\%-G%f\ is\ OK.,%-Q
Now a :make will run jslint. Errors appear in the quickfix window.
Here are the Mac OS instructions updated for Nov. 2012. Assumes you have Homebrew installed in order to get Node.js, and that you've already installed Syntastic for Vim (I use https://github.com/carlhuda/janus which provides this automatically):
$ brew install node.js
$ npm install -g jshint
Then add '/usr/local/share/npm/bin' to your PATH (probably in ~/.bashrc). For example, add the line:
export PATH="$PATH:/usr/local/share/npm/bin"
restart your Terminal and check that
$ jshint
is executable from the command line. Syntastic will discover jsHint automatically. Restart MacVim and enjoy!
Much better is to pipe the results through Lynx to deal with JSLint's unfortunate choice of HTML for output format. I have a blog post on how to do it here:
http://www.fleegix.org/articles/2008-09-06-jslint-in-vim-through-lynx

Categories