AMD Module Shaping: How to load only one JS function? - javascript

Many JavaScript libraries have a Builder tool that will allow you to "shape" what features of the library you depend on, both in terms of download bandwidth cost to the client and in terms of isolating functionality you actually need.
For example, I like many things in sugar.js, but I simply don't need or want katakana and hiragana character set handling. As the most trivial example, I want to be able to "shape" sugar.js to only export string.isBlank().
Is there a tool available to do this for me? Is there any ongoing effort by the EcmaScript committee to do something like this in a future version of JavaScript? Do any higher-level languages like TypeScript and CoffeeScript, offer hidden support for such "shaping"? I can do such "shaping" in C# for .NET DLLs via monolinker.
Basically, it looks to me like AMD handles the Loader aspect of a modern compiler, but does not handle the Linker aspect. Builders for jquery and dojo only work for a specific module, and aren't true Linkers, just Builders.
UPDATE: Google Closure Compiler is a compiler that takes JavaScript as input and produces JavaScript as output. The Advanced Compilation and Externs documentation suggests there is an API call to do this:
If putting together these export statements seems too tedious, you can use a function to do the exporting for you. See the Closure Library functions goog.exportSymbol() and goog.exportProperty() for examples of exporting functions.
However, this seems pretty convoluted, and makes me directly dependent on Google Closure Compiler. At this point, I am looking for info about future standards from the EcmaScript Committee, with regards to CommonJS, and for any wisdom from people who have thought about this problem and attempted to tackle it. Especially from fellow TypeScript developers; I don't want to have to create declare files in TypeScript for sugar.js, then use Google Closure Compiler against my TypeScript compiler output. It just sounds impossibly complex and hard to debug.

Unfortunately, there's nothing built into Javascript to do this "shaping", and really what you want is a compiler anyway, since roughly one of the roles it serves is to automate "shaping" at many levels (not just with methods).
The Closure Compiler is mature and open source (JQuery is actually minified using the Closure Compiler). So if you're going to begin annotating your JS code for a compiler, it might as well be this one.
There a huge number of side benefits of using a compiler, btw. They will reduce your file sizes (and thus interpretation/run time) a great deal more than simply shaping your included libraries. And while you're developing it will produce a lot of helpful messages to catch bugs early.

Related

Using Typescript with transpiled, unsupported/custom language files

The Problem
I have JavaScript-like files with extension .gml
I can convert the source to valid JavaScript via magic-string, and can go back the other way using trace-mapping.
I want to leverage Typescript on my .gml files to get strong Intellisense, e.g. by:
Creating a Typescript "program" that acts on the .gml->.js transpiled files and reports issues back; and
Creating a VSCode extension that proxies functionality to the Typescript language server and reverse-source-maps the results back to the editor.
It feels like there should be a relatively straight forward and generalizable approach to this, but my experiments have not worked out. Reference projects are either for much-more-complex scenarios or much simpler ones, and documentation on the matter is very light.
Prior Art
VueJS and Svelte use custom filetypes (.vue and .svelte), which they pre-process into valid Typescript, HTML, and CSS prior to proxying through to those respective language servers.
Their use cases are far more complicated than mine, and their code bases to accomplish this are extensive. I'm hoping to find a much more streamlined approach.
Possible approaches
I've had a little luck following the Svelte approach of creating a Typescript service and hooking up VSCode operations onto it, but this is extremely tedious.
I suspect that there's some possibility of using a Typescript plugin, but as far as I can tell that approach doesn't support using non-js/ts extensions nor source maps.
In any case I know I'll have to do significant work with the to-and-from-sourcemap conversions, but ideally that's the only difficult work I'd need to do.
Questions
Have you seen any examples in the wild of people solving a similar problem, or solved similar problems yourself?
Are there any deep-dive write-ups about this (I've found a few shallow ones)?
Is the plugin approach viable?
What are the possible ways to get non-js/ts extensions recognized by Typescript?

React - using TypeScript vs Flow vs?

I'm currently learning React and I think I understand it pretty well. However, there's one thing that's been bothering me regarding development of robust React applications - what tools do developers use for static type checking?
I really like TypeScript. I think it reduces the pain of developing JavaScript applications quite a lot, thanks to type checking and other neat features. Visual Studio Code also offers a really nice code completion. And I know that I can make it work with React by using typings + DenifitelyTyped.
The thing is, there aren't many tutorials about using React + TypeScript. There also doesn't seem to be many articles about developing using this combo. On the other hand, many people seem to be using Flow, which is a project backed by Facebook (and I guess they also use it).
I've managed to find a discussion on Reddit with pros and cons about going the React + TypeScript / React + Flow way. However, to me, it appears to be quite outdated as it is about 10 months old now. I think a lot has changed since then.
I've also found two articles about using React + Flow and React + TypeScript. The author states some issues he's run into when using both of the options and concludes that TypeScript is "the best bet right now" (November 2015), especially because the Flow project has many issues and receives low developer activity from Facebook. He also mentions it doesn't play well with Babel?
So, I guess the question would be: Is it safe to use the React + TypeScript combo, or will I run into some difficulties? What about Flow? Are there some other similar tools I should check out? Which approach would you recommend?
Update September 2017:
Having more than a year of experience with daily use of TypeScript, and playing with Flow for a while, I've came to the following conclusions:
TypeScript is still painful to use to this very day. The problem is that the JavaScript world just moves so fast that TypeScript keeps lagging behind. Thinking about using that fancy new ES7 stage 3 feature? Nope, you can't. Wishing to get type hints for the latest version of some library? Wait a month, or two, maybe more...
Flow has come a long way, it has been improved a lot, it can catch some things that TS can't. Best of all, it finally works on Windows. Also, there's great plugin for VS Code (no idea why it has only 3/5 rating). And it works 100 % with React Native, TypeScript is not even 50 % there yet.
Most of the time, you don't need types at all. All the additional typing is rarely worth it. JS is a dynamically typed language, get over it :)
TL;DR: If you plan to use any type checker, I recommend using Flow.
Update February 2019:
I believe the recommendation above got out of date and is no longer relevant. Three reasons:
React Hooks are here. They make type-checking your code much easier. In most situations, no additional code is needed.
TypeScript's type inference has improved.
TypeScript has much bigger community than Flow. Even yarn, Facebook's package manager, is moving away from Flow, to TypeScript.
So, I think TypeScript is a much more pragmatic choice than Flow in 2019.
As to whether it's even worth using any type checker at all, I'd say it depends on the project size. Small projects probably don't need it.
I'm going to start this answer saying that I have never used Flow, so I can't say much about it. But, we are using React and TypeScript at work and it works great.
We have all the benefits I imagine you already know about, like refactoring, type safety, autocompletion, etc.
Sure, for what I have seen, the Flow syntax is cleaner than TypeScript, but you can add your types using TypeScript incrementally. I think, this is more a matter of taste. Some people prefer to have the code explicitly typed, others prefer to type less and have a stronger type inference.
About, the technologies I'd say TypeScript is a safe bet, Microsoft is pushing the language (there will be a version 2 soon), Angular is using it as well and there are a lot of Angular developers. Even here on SO, the tag TypeScript has more than 4K followers and it's rare to have an unanswered question.
The big issue with TypeScript, at least for us is that from time to time, we decide to use a component or a library that does not have the type definitions, so we have to create them ourselves. But I guess, that's a way to contribute back to the community.
I just asked myself the same question (though not with React) and found the following articles useful in evaluating the two:
http://michalzalecki.com/typescript-vs-flow/ (2016-07-15)
https://blog.wearewizards.io/flow-and-typescript-part-2-typescript (2015-11-20)
https://blog.wearewizards.io/flow-and-typescript-part-1-flow (2015-11-13)
The approach taken by the flow designers feels more functional with better type inference and a better approach for nulls. However, TypeScript has better community support especially with respect to pulling in types for third party libraries via http://definitelytyped.org/ which is important for having types flow through all your code for maximum type safety. TypeScript is created by Microsoft which has a rich history in writing compilers and evolving the technology in favorable directions - notable here is C# and the fact that they are already adding non-null types (2016-07-11): https://blogs.msdn.microsoft.com/typescript/2016/07/11/announcing-typescript-2-0-beta/
TypeScript seems like the safer bet today.
And for those trying TypeScript out in an existing codebase I found the following settings in my tsconfig.json file really helpful in allowing TypeScript to co-exist nicely with JavaScript (allowing transition one file at a time):
{
"compilerOptions": {
"allowJs": true,
"isolatedModules": true,
...
}
}
In my React development, I have quite a complex Babel / Webpack / Flow / Mocha toolchain set up and never had any issues with Flow. Takes some effort to set everything up (Webpack can be daunting at first), but afterwards, it just works. Flow is definitely the way to go as it is a narrower and more focused technology and as such more likely to play well with other tools. In contrast, TypeScript tries to be a lot more than just a type inference / static type checker tool and so it brings additional baggage and assumptions. So React is a specialized tool that does one thing well while TypeScript is effectively a language layered on top of JavaScript. To make sure Microsoft drives its point home, TypeScript files customarily have a different extension as well (.ts instead of .js) because you are now using a different language, got it?
TypeScript uses code generation to spit out JavaScript whereas in Flow the annotations are simply stripped off, there's no code generation as such. In the past, the Microsoft people promoting TypeScript used to make a statement to the effect that code generation is "file-local" (I don't remember the exact terminology used). This was supposed to provide a soothing reassurance that the TypeScript compiler isn't doing anything too magical. At any rate I can't find that statement prominently displayed any more. With Flow you don't need such assurances as you write in plain JavaScript (or whatever ECMA version you've configured Babel for) and the annotations are, like I said, simply stripped.
Not to mention that TypeScript is coming from a company that specializes in unethical and questionable technical practices (I don't rule out that TypeScript may eventually turn out to be the Mother of all Embrace-Extend-Extinguish ploys). Let's not forget that Microsoft did everything in their power to cause Javascript to fail as they (rightly, if belatedly) foresaw what a threat it represented, and still represents, to their crappy operating system and their bloated office suite.
Additionally, Flow's type system was much more powerful last time I bothered to evaluate TypeScript (circa 2015) and it was much easier to apply it incrementally or even sporadically in the sources. For integrating third party libraries I am using flowtyped and it is very rare that I need to complement those found there with my own definitions.
Finally, the fact that Angular uses TypeScript means absolutely nothing as Angular is not really relevant for new projects. React has won hands down, time to move on.
If you want type checks but would prefer to keep plain old javascript (to avoid compiling, or for portability, etc), here's one important distinction between the two (for React or in general):
With Flow the initial setup can run static analysis on vanilla js (it infers many types):
function square(n) {
return n * n; // Error!
}
square("2");
With TypeScript there's a migration effort and only some vanilla js static analysis without it:
noImplicitReturns which prevents you from forgetting to return at the end of a function.
noFallthroughCasesInSwitch which is helpful if you never want to forget a break statement between cases in a switch block.
TypeScript will also warn about unreachable code and labels, which you can disable with allowUnreachableCode and allowUnusedLabels respectively.
More Benefits To Flow
Flow's Comment Types and Error Suppression take support for vanilla js a step further, by allowing you to gradually incorporate type checks through legal js comments that annotate the type or suppress specific checks you might not be ready for yet. Comment types have been a feature request in TypeScript for quite some time, and only recently has there been a PR for it (see previous link).
Downsides To Flow
That said, all of Flow's simplicity does come at the cost of some pretty complex configuration with some annoying caveats, like how it type checks 3rd party libraries, etc. The best advice someone can give about Flow: try to cross-reference anything you read in their documentation as it's outdated and in some cases can be a little misleading.

Is it possible to mix TypeScript and CoffeeScript?

I've just started to explore new JavaScript ideas and I'm pretty impressed. At first sight both CoffeeScript and TypeScript have some great features. They're both compiled to JavaScript. CoffeeScript is great because it makes code shorter and clearer. TypeScript on the other hand gives us possibility to build complex applications.
Is it possible to mix TypeScript and CoffeeScript? I mean - take advantage of both of them in the same file?
Short answer: no.
You need to compile a CoffeeScript/TypeScript file to a JavaScript file, which means that this file, as a whole, must be syntactically correct for the given language.
CoffeeScript and TypeScript are not syntactically-interchangeable. At best, you would have to resort to some lowest common denominator in terms of syntax use, but that would completely defeat the purpose of using any of the two instead of plain JavaScript.
You can't and it is really a bad idea.
Let's suppose that you can have CoffeeScript and TypeScript in one file, then you need developers who can program in both of them, so your product will be more expensive. Moreover, you will lose any reasonable chance of using lints to check your code.
I can't even imagine what kind of troubles you would go through with modules (commonjs, AMD, ES6, ...) when combining CoffeeScript and TypeScript.
If you use one language, you typically get from its authors tutorials how to do things in the language properly. When you mix languages, you would have to come up with "what is proper way to do X in my environment". These challenges sounds petty but for any serious project they can be deadly.
If you can choose, I would recommend TypeScript because it saves you from a ton of runtime errors. It's not that visually nice as CoffeeScript but that's not what you are paid for typically.
Have a look at compiled-coffee wich states:
Do you like the type safety of TypeScript and the concise syntax of
CoffeeScript? In that case CompiledCoffee is for you! It combines
CoffeeScript with TypeScript's type system via the definition files.
You create a *.coffee file and a *.d.ts file with the same name, in
which you (optionally) type stuff. Rest is handled automatically.
Not currently, both CS and TS have a bunch of incompatible syntax. You'd need a dedicated compiler for those types of CoffeeTypeScript files and that compiler does not exist.
I'm very interested in how a language like that would look but I'm afraid it will have too many options and be hard to learn (relative to either CS or TS). I would imagine programming in it would be somewhat similar to python.

Tools and tips on migrating a large user-defined JavaScript codebase?

I help develop and manage software in which (among other things) users can provide their own JavaScript scripts to run macros and the like. We're using Mozilla Rhino in a Java context. We have quite a large "API", wherein there are a variety of well known variables and utility functions we place in the scopes a priori. For example, things like "cellObject.assignTo(name)" which are widely used, but obviously only make sense within the scope of our product.
This all works quite well, but now we're close to releasing a newer and better version of the software. Among other things, it will drastically update the API of various objects, and even change the names of some of the variables that are placed in scope (e.g. "cellObject" to "plot.getCell(0)").
Along with this new version, we're going to be including some automatic migration for user-defined scripts. So I was wondering, what would you guys suggest to be the best plan of action? Are there any reliable tools out there that might help? Currently we're looking into basically executing a number of very complex regular expressions on the scripts as a best-effort attempt at migration. Has anyone else ran into something similar?

Node.js how to implement polymorphism?

I'm trying to implement an application using node.js and other related technologies. Heading from java land polymorphism but natural, but for the classical programmer node works differently.
The application will load new code during run-time provided by the user. In order for the main core to use this code "we" need to agree on some kind of a convention. Knowing how new Node is I wasn't that surprised that I didn't find the answer. The problem is this issue is rather vague in JS too.
Requirements:
Strong decoupling.
loading new code in run-time.
The solution should be applicable so I can share as much code as possible with the browser.
Update:
I did fiddle around with duck-typing, I've also encountered ideas from Clojure in regards to protocol based implementation.
I would appreciate some code in the answer.
JavaScript, just like most other scripting languages (i.e. no compile-time type checking) does polymorphism through duck typing.
If you're from Java-land you're probably looking for Dependency Injection which generally provides uber decoupling. You can probably use google to find a good dependency injection framework for Node, like this one.
Although truthfully you can probably just make a single Javascript/Coffeescript file that does all the wiring and config loading.
Because of the flexibility of Javascript just about every form polymorphism has been implemented (traits, interfaces, inheritance, prototypes). Each have their advantages/disadvantages but almost all are runtime check (if any) and not compile time.
Personally I would probably just use either Coffeescripts inheritance, traits.js or Javascript's builtin prototype chain.
EDIT: However since you're talking about allowing users to extend the system then callbacks and/or custom events are the preferred approach (i.e. higher order functional programming and event-bus). If you're looking for something substantial like a plugin system then loader-js looks rather complete (tip of the hat to #Larry Battle).

Categories