Reputation: 115
I've being trying to bundle my TypeScript "application" into a single javascript file.
I'm not using any bundler but TSC ( using TypeScript 2.2 ). Aside of my own ts files, my application also uses external modules such immutablejs.
I read every possible thread, documentation but I can't find a way to bundle external modules ( from node_modules ) into my compiled / transpiled javascript file using only TSC.
Down below you can find a sample of my latest code/ configu as well as the results of my attempts.
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "system",
"removeComments": true,
"sourceMap": true,
"allowJs": true
}
}
app.ts - note: ./something.ts is successfully bundled.
/// <reference path="../node_modules/immutable/dist/immutable.d.ts" />
import * as something from "./something";
import * as Immutable from "immutable";
console.log( something.test );
const map1 = Immutable.Map( { a: 1, b: '2', c: 'cu' });
console.log( map1.get( 'a') )
1#: using tsc-bundle (https://www.npmjs.com/package/typescript-bundle)
This method not only don't bundle immutableJs as well as thrown the error: require is not defined.
var dragonfly = (function () {
var main = null;
var modules = {
"require": {
factory: undefined,
dependencies: [],
exports: function (args, callback) { return require(args, callback); },
resolved: true
}
};
function define(id, dependencies, factory) {
return main = modules[id] = {
dependencies: dependencies,
factory: factory,
exports: {},
resolved: false
};
}
function resolve(definition) {
if (definition.resolved === true)
return;
definition.resolved = true;
var dependencies = definition.dependencies.map(function (id) {
return (id === "exports")
? definition.exports
: (function () {
if(modules[id] !== undefined) {
resolve(modules[id]);
return modules[id].exports;
} else return require(id)
})();
});
definition.factory.apply(null, dependencies);
}
function collect() {
Object.keys(modules).map(function (key) { return modules[key]; }).forEach(resolve);
return (main !== null)
? main.exports
: undefined
}
define("something", ["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.test = "oie";
});
define("app", ["require", "exports", "something", "immutable"], function (require, exports, something, Immutable) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
console.log(something.test);
var map1 = Immutable.Map({ a: 1, b: '2', c: 'cu' });
console.log(map1.get('a'));
});
//# sourceMappingURL=app.js.map
return collect();
})();
#2 - using TSC with module = system ( tsc src/app.ts -m system --outfile build/app.js )
This method also don't bundle immutableJs but also thrown the error: System is not defined
System.register("something", [], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var test;
return {
setters: [],
execute: function () {
exports_1("test", test = "oie");
}
};
});
/// <reference path="../node_modules/immutable/dist/immutable.d.ts" />
System.register("app", ["something", "immutable"], function (exports_2, context_2) {
"use strict";
var __moduleName = context_2 && context_2.id;
var something, Immutable, map1;
return {
setters: [
function (something_1) {
something = something_1;
},
function (Immutable_1) {
Immutable = Immutable_1;
}
],
execute: function () {/// <reference path="../node_modules/immutable/dist/immutable.d.ts" />
console.log(something.test);
map1 = Immutable.Map({ a: 1, b: '2', c: 'cu' });
console.log(map1.get('a'));
}
};
});
#3 - using tsc with module = amd ( tsc src/app.ts -m amd --outfile build/app.js )
This method not only don't bundle immutableJs as well as thrown the error: define is not defined.
define("something", ["require", "exports"], function (require, exports) {
"use strict";
exports.__esModule = true;
exports.test = "oie";
});
/// <reference path="../node_modules/immutable/dist/immutable.d.ts" />
define("app", ["require", "exports", "something", "immutable"], function (require, exports, something, Immutable) {
"use strict";
exports.__esModule = true;
console.log(something.test);
var map1 = Immutable.Map({ a: 1, b: '2', c: 'cu' });
console.log(map1.get('a'));
});
Conclusion: It's really important for the future of my project be able to bundle external libraries without the need of these popular bundlers such as webpack, browserify, gulp, etc...
Does anyone can help me?
Thanks in advance,
TF!
Upvotes: 7
Views: 4158
Reputation: 81
Just noticed your post, and disclaimer, I am the author of typescript-bundle. You can bundle ImmutableJS with the following.
tsc-bundle --project ./tsconfig.json --importAs immutable=Immutable
Some documentation about this switch here
This will create an additional resolver that attempts to resolve immutable from the window object. This is typically the case if you are including dependant scripts in your page (via a <script>
tag) and need that global name (Immutable in this case) referenced in your bundle (and you need to make use of .d.ts files pulled from @types/* with the ambient module named "immutable")
The above line results in the following resolve() function.
function resolve(definition) {
if (definition.resolved === true)
return;
definition.resolved = true;
var dependencies = definition.dependencies.map(function (id) {
return (id === "exports")
? definition.exports
: (function () {
if(modules[id] !== undefined) {
resolve(modules[id]);
return modules[id].exports;
} else if(id === "immutable") {
return window["Immutable"];
} else {
try {
return require(id);
} catch(e) {
throw Error("module '" + id + "' not found.");
}
}
})();
});
definition.factory.apply(null, dependencies);
}
This works against most declarations you will find in the npm @types/* repository (assumed UMD) and allows the bundle to effectively pull the module from the environment (global variable name).
Hope you find this helpful
Upvotes: 1