I am very happy to see new Aurelia packages move towards a simple NPM based build, and Typescript the language of choice! Hopefully existing packages will slowly migrate.
That said I have a few comments on the tsconfig.json
.
I see you use most strict options for maximum safety but you might have missed some:
noImplicitThis
, which is quite helpful at detecting non-obvious errors.
noFallthroughCasesInSwitch
I also suggest the following relaxation: suppressImplicitAnyIndexErrors
.
It avoids ugly code such as this example (found in aurelia-webpack-loader
):
(PLATFORM as any).Loader = WebpackLoader;
By allowing dynamic access:
PLATFORM['Loader'] = WebpackLoader;
Of course you should properly type everything, but I find that it's nice to have an escape hatch for those occasions when you need one.
A big problem with the current TS build is that it emits its helpers at the top of each and every file (when they're used of course).
This is large, see aurelia-webpack-loader
again for example:
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t;
return { next: verb(0), "throw": verb(1), "return": verb(2) };
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Aurelia is very modular, having those helpers repeated again and again would contribute a large bloat.
I suggest that you use the new option importHelpers
. It does pretty much what it says:
import { __extends, __awaiter, __generator } from 'tslib';
And tslib
becomes an additional dependency of Aurelia.
That way the helpers are only included once in the final build, and even shared with my own TS code! 🙂
That works at least fine when you use NPM as your package manager, not sure about others (Bower?).