Debug CoffeeScript sources with node-inspector - node.js

I'm using CoffeeScript for a while to write Node.js programs. It's ok to debug with node-inspector if I compile the sources with Source Maps.
However, when I try to create a mixed Javascript/CoffeeScript app by using coffee-script/register:
#!/usr/bin/env node
require('coffee-script/register');
require('../src/client');
Then, node-inspector shows the compiled Javascript.
Is there how to see the actual *.coffee sources in node-inspector when I'm not explicity compiling it?

Disclaimer: I am a maintainer of Node Inspector
In order to see the actual *.coffee file in Node Inspector, you need to provide a source-map file describing how to map the transpiled javascript loaded inside Node/V8 runtime to you coffee-script source. Additionally, the filename of the transpiled javascript must be different from the original script name (AFAIK).
This is the trouble with require('coffee-script/register'): it converts the coffee-script source to the javascript source while keeping the same file name. In other words, the runtime (and Node Inspector) see that your *.coffee contain the transpiled javascript, thus it cannot display your coffee script for that very same filename. Also AFAIK, the coffee compiler does not emit any source map in this case.
I see two possible approaches to fix the problem:
Modify loadFile() in coffee-script/register:
emit a source map and save it to a file
pass a different filename to module._compile, e.g. script.coffee.js
Modify coffee-script/register to emit an embedded source map. Fix Chrome DevTools and/or Node Inspector to support embedded source maps.
References:
loadFile() in coffee-script/register
A Node Inspector issue discussing why coffee --nodejs --debug app.coffee does not work now: https://github.com/node-inspector/node-inspector/issues/224
A Node Inspector issue discussing inline source maps: https://github.com/node-inspector/node-inspector/issues/401

Related

How do I write TypeScript tests that don't include the classes under test in the transpiled test code?

I have a TypeScript project that compiles down to a single JS file in /dist.
I have Jasmine tests, also written in TypeScript, that reference the various classes they test with references like:
/// <reference path="../../../src/script/classUnderTest.ts" />
When I compile the tests the TypeScript compiler pulls in all the referenced classes and I get a single JS file containing the test code and the code under test.
This actually works fine for just running the tests, but now I'd like code coverage too. From what I can tell, to get Istanbul to work I need to have the code under test separate from the test code. Also it would be nice to be testing exactly the JS file that will be live.
So, how can I get the type safety and autocomplete benefits of "/// reference" whilst using my compiled JS file when the tests are actually run?
(Or am I barking up the wrong tree entirely?)
Note, I am building this on a Mac, so from what I've read Chutzpah is not currently an option. I'm also currently using only npm scripts to do builds. I'd prefer to not bring in grunt or gulp unless it's absolutely necessary.
So, how can I get the type safety and autocomplete benefits of "/// reference" whilst using my compiled JS file when the tests are actually run?
Don't using TypeScript's --outFile option (few other reasons). Instead use modules e.g. --module commonsjs and a module loader e.g. webpack.
More
Browser quickstart : https://basarat.gitbooks.io/typescript/content/docs/quick/browser.html
Modules:
https://basarat.gitbooks.io/typescript/content/docs/project/modules.html

Debug concat/minified files with Grunt

I'm using grunt concat/uglify to reduce the number of calls being made to load JavaScript.
I removed all the hard-coded links to the actual javascript files, and now reference the one javascript file produced by grunt.
how can I continue to debug/view my javascript in my development environment?
Is that what source maps are?
i.e.
https://www.npmjs.org/package/grunt-concat-sourcemap
Yes. You will need to generate a sourcemap to continue debugging your code easily.
There are two types of sourcemap, but the sourcemaps need to be maintained through each transition. SO if you concat in one step an minify in a second step, the minify process needs to know that the concat step generated a sourcemap and generate it's own sourcemap based on that sourcemap, so that the minified code sourcemap corresponds to the original input, not the input from the concat step.
There are several ways around this -- the easiest way is to just not minify in your test/deveopment environment. There are also minifiers that will do the sourcemapping correctly for you, but they can be hard to configure.
You might also want to take a look at browserify -- this is a tool that lets you write your front-end browser code like it was node modules, and it will concat and generate sourcemaps for you!
Alternatively you can also just rely on gzip compression from your server and run your code through a minifier -- this works surprisingly well.

bower init - difference between amd, es6, globals and node

I am creating my first Bower component. After running bower init the script asks me 'what types of modules does this package expose?' with these options:
amd
es6
globals
node
what is the difference between these options?
If you don't know, it's quite likely globals is the right answer for you.
Either way, you need to understand:
what is and why AMD
what is a nodejs module
what is ecmascript 6 and especially es6 modules
[UPDATE]
This feature was introduced very recently in bower and is not documented at all yet (AFAIK). It essentially describes the moduleType, which states for what module technology the package is meant to be consumed (see above).
Right now, It doesn't have any effect apart from setting the moduleType property in the bower.json file of the package.
See https://github.com/bower/bower/pull/934 for the original pull-request.
[UPDATE #2]
A few additional points, to answer comments:
right now AFAIK there is no validation done on the moduleType property - which means that people are technically allowed to use whatever value they want for it, including angularjs if they feel inclined to do so
the bower committee seems to not be keen toward the inclusion of additional non-interoperable/proprietary moduleTypes (think composer, angular, etc) - which is easily understandable, but yet again, nothing really prevents people from using the moduleType value they want
an exception to the previous is the (somewhat) recent inclusion of the yui moduleType, so, there are "exceptions" to be made, assuming they are part of a concerted plan
What I would do if I were to author a package for a not-listed package manager and publish it on bower?
I would author an es6 module, and use / patch es6-transpiler to output the package format I need. Then I would either/and:
petition the bower guys to include my package technology as a choice (based on the fact it's supported by es6-transpiler as a target)
publish my package including both the es6 module version of it and the transpiled XXX version of it, and use es6 as a moduleType
Disclaimer: I don't have real-life experience authoring angularjs modules.
Initial
I'm using bower init for first time too.
The options should refer to the different ways to modularize some JavaScript code:
amd: using AMD define, like requirejs.
node: using Node.js require.
globals: using JavaScript module pattern to expose a global variable (like window.JQuery).
es6: using upcoming EcmaScript6 module feature.
In my case I wrote a Node.js module dflow but I'm using browserify to create a dist/dflow.js file that exports a global dflow var: so I selected globals.
Other Updates
The command I used to browserify dflow as a window global object was
browserify -s dflow -e index.js -o dist/dflow.js
I changed it cause I prefer to use require also inside the browser, so now I am using
browserify -r ./index.js:dflow -o dist/dflow.js
and so I changed the bower.moduleType to node in my bower.json file.
The main motivation was that if my module name has a dash, for example my project flow-view, I need to camelize the global name in flowView.
This new approach has two other benefits:
Node and browser interface are the same. Using require on both client side and server side, let me write only once the code examples, and reuse them easily on both contexts.
I use npm scripts and so, I can take advantage of ${npm_package_name} variable and write once the script I use to browserify.
This is another topic, but, it is really worth that you consider how it is useful the latter benefit: let me share the npm.scripts.browserify attribute I use in my package.json
"browserify": "browserify -r ./index.js:${npm_package_name} -o dist/${npm_package_name}.js"
Just for reference, this is precisely what bower specifies regarding the module types:
The type of module defined in the main JavaScript file. Can be one or an array of the following strings:
globals: JavaScript module that adds to global namespace, using window.namespace or this.namespace syntax
amd: JavaScript module compatible with AMD, like RequireJS, using define() syntax
node: JavaScript module compatible with node and CommonJS using module.exports syntax
es6: JavaScript module compatible with ECMAScript 6 modules, using export and import syntax
yui: JavaScript module compatible with YUI Modules, using YUI.add() syntax
Relevant link: https://github.com/bower/spec/blob/master/json.md#moduletype

'require' is not defined in console tab of node-inspector's repl

I tried to
require('fs').writeFileSync('o.json', JSON.stringify(anObject));
for debugging, and I got RefrenceError: require is not defined.
This is bizarre. What kind of an environment is it that doesn't have require?
In Node.js, the require function is not defined globally. When you require a module, its source code is wrapped by a function that takes several arguments and require is one of them:
(function (exports, require, module, __filename, __dirname) {/* your code */
});
You can see that wrapper in Node Inspector when you look at the content of any source file.
Now there are two different scenarios for evaluating code from Node Inspector's console:
The debugged process is running. Expressions are evaluated in the global context, i.e. you have access only to globally defined symbols. require is not among them.
The debugged process is paused on a break point. The expression is evaluated in the context of the select stack frame and have access too all variables in the current scope (which include variables captured by closures from by outer functions). However: most functions don't call require, therefore this variable is not captured in any closure and you can't access it.
I had a short chat with one of the Node core developers about exposing require as a global symbol, because it would simplify injecting code from Node Inspector, but my arguments were not convincing enough.
It is possible to use require in node-inspector, by hitting a breakpoint where 'require' is in scope (Tested with NodeJS v0.10.25, node-inspector#0.7.0-2):
An example (a super simple 2-byte 'REPL' for Node): create a file (for example r.js) containing just:
0;
then use
$ node --debug-brk r.js
and start node-inspector and the browser in the usual way,
-or- (using node-debug module from NPM) use:
$ node-debug r.js
Now switch to the node-inspector console in the browser and verify that require is indeed defined, then do something with it, like:
> typeof require;
"function"
> fs = require('fs');
undefined
> fs.writeFileSync('bla.txt', 'blup');
undefined
and verify that this file gets written in the directory where you started node.
Note: the browser part of node-inspector can be quite glitchy: when debuggong different scripts one after the other, I often need to refresh (causing a debugger disconnect), then restart Node until the script shows up correctly in the browser.
P.S. This method has an uncanny similarity to creating a Perl 'REPL' by running it as perl -de '0;'... Coincidence?
FWIW, just by starting with node-debug _mocha, stopping at a breakpoint and selecting the lowest frame on the call stack in the right-side panel, I got to a context where require() was available: require('fs') worked OK, but require('q') and other installed modules didn't, even if I specified an absolute path. Will get back if I come across the solution.
require() is implemented in all CommonJS environments, which include Node.js, but not in the browser's console, which is what node-inspector is based on (to be specific, the Blink Developer Tools):
> require
ReferenceError: require is not defined

How use dev and prod assets in NodeJS/Express/Jade properly

I have a NodeJS application with Express based structure and Jade module for a views. I need to use a full version my assets on a developer machine and min version in production machine.
Can you explain best practices of how should I do it properly?
EDIT: If you put a minus please describe the reason.
Not sure why there isn't an "official" way of doing this (compared to what Ruby on Rails does).
Here are a few suggestions:
DIY
Here's what I've been doing so far:
At server startup, I run uglify-js on all the js files (under .../js, and create the minified version under .../min) with something like so (leaving out the reading/writing of the files):
var jsp = require('uglify-js').parser;
var pro = require('uglify-js').uglify;
var ast = jsp.parse(code.toString('utf8')); // parse code and get the initial AST
ast = pro.ast_mangle(ast); // get a new AST with mangled names
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
var final_code = pro.gen_code(ast); // compressed code here
then in html templates, based on some environment variable to trigger production environment, I generate the path for the <script> tags to either point to .../js or .../min.
This leaves out quite a lot (where you would group all js files into one minimized one to reduce the number of browser queries and such), but hopefully this can help you craft your own strategy.
Piler
That said, I've been meaning to try piler (https://github.com/epeli/piler), which seems to be a better alternative to the DYI way.
Using Grunt
Grunt.js (http://gruntjs.com/) is also quite suitable to help preprocess files (html, js, css, ...)
Here are a few pointers:
grunt-recess: https://github.com/sindresorhus/grunt-recess (especially interesting if you use less)
how to config grunt.js to minify files separately
Grunt tasks to process HTML files and produce a deploy directory of optimized files (https://gist.github.com/necolas/3024891)
I view minification as a build step and prefer to not burden the application at runtime with it. Therefore, I would setup my HTML files to refer to file paths which are generated from the build tool and then use the build tool to figure out whether or not to minify.
I haven't actually needed to make it conditional myself because I haven't needed to have unminified code in the browser. With grunt setup to watch the source files and recompile automatically, I can edit a JavaScript source file and it automatically gets rebuilt and placed into the appropriate runtime location. However, I could see this being useful for stepping through code. IE 9 has a formatter in its dev console which is useful for debugging minified code, but I'm not sure how common that is across browsers.
If I were to skip minification in development, I would first check if I can make the grunt uglify task use a config setting like an environment variable or npm setting, etc. to decide whether to actually uglify or not. If that is not possible, I would make a separate grunt task called "devBuild" that does everything except uglify.

Resources