One can use external libraries like Moment.js via eval & UrlFetchApp in the "standard" Apps Script projects because the variables exports and module are not defined, so the library installs itself into the global context
Indeed, we can verify the result by inspecting this in the Apps Script Editor:
Code.gs
var momentURL = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.4/moment.min.js";
function main() {
eval(UrlFetchApp.fetch(momentURL).getContentText());
Logger.log(this["moment"]);
}
Executing main yields
function e() {
return Qe.apply(null, arguments);
}
For transpiled TypeScript, because exports and module are globally defined, the initialization of eval'd libraries assumes that it has a more recent runtime / package management system than that provided by Google Apps Script.
Code.ts
import * as moment from "moment";
const momentURL = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.4/moment.min.js";
function main() {
eval(UrlFetchApp.fetch(momentURL).getContentText());
Logger.log(`this['moment']: ${this["moment"]}`);
Logger.log(`this.module: ${this.module}`);
for (let key in this.module)
Logger.log(`this.module[${key}]: ${this.module[key]}`);
}
$ clasp push -->
Code.gs
// Compiled using ts2gas 1.6.0 (TypeScript 3.2.2)
var exports = exports || {};
var module = module || { exports: exports };
//import * as moment from "moment";
var momentURL = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.4/moment.min.js";
function main() {
eval(UrlFetchApp.fetch(momentURL).getContentText());
Logger.log("this['moment']: " + this["moment"]);
Logger.log("this.module: " + this.module);
for (var key in this.module)
Logger.log("this.module[" + key + "]: " + this.module[key]);
}
Which yields a log of
this['moment']: undefined
this.module: [object Object]
this.module[exports]:
function e() {
return Qe.apply(null, arguments);
}
Solutions
So the eval is successful, but binds to module.exports and not moment. You can (in the transpiled Apps Script) refer to module.exports instead of moment:
Logger.log(module.exports().format("YYYY")); // 2019
Probably you will need to use a different method than clasp, since it seems ts2gas (as of v1.6.0) does not support import / export transpiling. This observed behavior wherein module.exports in transpiled TS is the eval'd import seems heinously fragile, and will certainly not be easy to work around when writing the actual TypeScript.
Related: