How should a RequireJS transpilation plugin return its result? - requirejs

Transpilation plugins like es6!, es!, and cs! are more complicated than simple plugins like text! because they return javascript modules that have their own dependencies.
Specifically, the code I've seen loads the specified file through XHR, transforms it, and then returns the result via a call like
onload.fromText("define(['foo', 'bar', ...");
That works fine for small test cases but throws a "Mismatched anonymous define() module" exception when running in my actual app. It's a race condition that happens when RequireJS is simultaneously processing a bunch of normal JS requires at the same time as evaluating a bunch of plugin requires.
Is this just a RequireJS bug, or is the plugin doing it wrong? Or, is it just not supported? Despite multiple transpilation plugin examples on the web, the RequireJS doc on that error says that
If you use the loader plugins or anonymous modules (modules that call define() with no string ID) but do not use the RequireJS optimizer to combine files together, this error can occur.

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

requirejs: parse a file and return its dependencies

I have a situation where I need to load (via AJAX in a browser) a file that defines a requirejs module (without executing it) and get back a list of its dependencies.
Ie, given a file that starts with
requirejs(["foo/bar", "foo/baz"], function(bar, baz) {
I'd like the utility to return an array like
["foo/bar", "foo/baz"]
I've found some solutions that will do it using r.js (for example, the ones outlined here: https://groups.google.com/forum/#!msg/requirejs/4C0deWFqpZY/mkZFlw2r_k4J), but nothing to do it in a browser. I can just parse out the require statement myself, but that seems suboptimal. Has anyone come across any solutions for this?

How to use babel runtime with large nodejs/express app

I want to use babel runtime in a big/complex nodejs app. I don't want to use the babel require hook because the app is big and when I have tried to use it I get the following error:
RangeError: Maximum call stack size exceeded
And I only want to transpile a few JS files, at least for now.
The babel docs are a bit cryptic for the runtime support. After installing babel-runtime, they provide:
require("babel").transform("code", { optional: ["runtime"] });
Where does that code get included? And is "code" truly just a string? I have tried to add that to my main app.js file (express 3 app). Unfortunately, that doesn't work.
I cannot totally understand your questions, but I think I can answer part of it.
As explained in the babel api, transform() function takes a string that is supposed to be source code to be transpiled, and returns an object including three properties:
code the code generated
map the source map for the code
ast the syntax tree
This means, if you want to transpile your code in a folder, for each file you want to transpile, you should read the file with fs utility, give it to transform() function, and write the value of the code property in the object returned, to your output folder.
To simplify the step to read files, you could use the function transformFile provided by babel.
As for the problem you mention with your express app, I cannot help, unless you provide more information.

Is there any way to define global dependencies in Require.js?

Backstory:
I've currently got a Require.js and jQuery/Backbone.js using site. Until now, jQuery and Backbone have stayed outside of Require, letting me do:
define([], function() {
// NOTE: Using Backbone and $ without an import!
new Backbone.View(el: $('#foo');
});
That's worked really well: without that approach, just about every module in my site would have to add a Backbone/jQuery dependency.
But then the other day I needed to package up a portion of our code as an external library. I made a separate require config file for it, and everything seemed great, until I compiled ("optimized") all the files in to a single library file, and realized that Backbone/jQuery (and related plug-ins/libraries) weren't getting included.
So, I added a bunch of shims, and got Backbone, jQuery, and all the related libraries in to Require. However, I still have a ton of modules that expect $ and Backbone to just exist. That should be ok, because Backbone/jQuery both register their variables globally, but it's not because of Require's load order.
Basically, any module without dependencies is broken, because they load before Require loads the jQuery/Backbone shim. Any modules that have dependencies don't have this issue, because jQuery/Backbone have already been loaded by the time they get loaded.
It seems like my only option is to add an explicit Backbone/jQuery to every module without dependencies. I've got a bunch of modules like that though, and ideally I'd prefer not to have to import jQuery/Backbone anywhere.
Question
So, my question is: is there any way to tell Require "load these X modules/shims before you load everything else"? Or, to put it another way, is there any way to tell Require that all of my modules depend on certain other modules?
I thought putting Backbone at the top of my initial require:
require(['backbone', ...
but that didn't help; the other dependency-less modules still load before it.
I see no reason this would not work:
require(['backbone', 'jquery'], function () {
require(['main']);
});
The idea is to wrap what was your initial entry point to your application in a require call that loads Backbone and jQuery. If the modules of your application are loaded only because main is required (that is, if there is no require call elsewhere that loads any module needed by main), then with the code above both Backbone and jQuery are guaranteed to be loaded before any of the modules used by main are.

How to Stop a requireJS Module from Loading

What is a good strategy for stopping a requireJS module from loading from information you won't know until run-time?
The scheme I came up with involves using a loader plug-in that checks some run-time attributes and checks the "protected" modules against their attribute lists, and if they're not supposed to load, doesn't call load() from inside the loader plug-in load() function. However, this results in a browser error, which in older versions of IE, cause actual script errors, which is not what I want/need (it's actually a time-out error because load() is never called).
Is there a way to say, "Yeah, I got that you wanted to load this, but, um, we don't want to, and that's not an error, so go about your business with the rest of your loading business." Or perhaps a better scheme to achieve what I want?
I solved this by doing load(null) and checking for null in the places where the module that could possibly not be loaded is referenced.

Resources