In some code I'm working on I have a mixture of Coffeescript, Javascript and Typescript files.
In my Typescript file, I access the type definitions using
/// <reference path="foo.d.ts" />
import {FooA, FooB} from "foo";
var a:FooA = new FooA() // etc...
This results in the Javascript
var foo_1 = require("foo");
var a = new foo_1.FooA();
Which is fine. However, my workflow is such that I don't use a module system. All the non-JS files are handled by Grunt and compiled to JS and then bundled together.
Ideally I would want my Typescript to compile to
var a = new FooA();
as I can guarantee they would be in the global namespace.
How can I do this?
Ideally I would want my Typescript to compile to ... as I can guarantee they would be in the global namespace. How can I do this?
I am sure you know that global is bad and susceptible to subtle ordering issues (beyond just name collision) : some notes
That said. A file will become a module as soon as you have a root level import or export (some docs).
So :
/// <reference path="foo.d.ts" />
import {FooA, FooB} from "foo";
var a:FooA = new FooA() // etc...
Should be something like:
/// <reference path="foo.d.ts" />
var a:FooA = new FooA() // etc...
i.e. FooA should be available globally. You need to review your foo.d.ts. This will help: https://basarat.gitbooks.io/typescript/content/docs/types/migrating.html
Related
How to include an entire file into my bundle main.js?
ES6 can import/export functions and classes. But what if i want to include the whole content from another file into my bundle main.js? how to do it?
I came across the query on Stackoverflow: Managing jQuery plugin dependency in webpack.
I'm not sure about this question though. Those options given there seem to target injecting implicit globals, configuring this, disabling AMD, to include large dists. I don't think this is what i want.
Let's say i have two files in src directory
1- rough.js
const rgh = "qwerty"
2- index.js
import './rough.js' //something like this
console.log (rgh)
Now what i expect in bundle.js is
const rgh = "query";
console.log(rgh)
I just want all the content inside one of my file to get all transported to index.js for webpack to bundle them
Those options given there seem to target injecting implicit globals,
configuring this, disabling AMD, to include large dists. I don't think
this is what i want.
To understand this you need to understand what webpack is doing for you. Web pack takes a series of Javascript files (and more importantly their contents) and parses these into one file. That's what it does from a file point of view, but if you ignore the file and think about what it does from a code point of view, it takes each one of the imported objects and makes them available to other objects depending upon the rules you define in your code (using import and export). You can think of this from a closure point of view something like this:
if you have some code like:
import a from 'a.js';
export default b(){
console.log(a.test());
}
This will be turned into something like, in one js file:
var a = (function() {
var testStr = "test";
function test(){
return testStr;
}
return {test:test};
})();
var b = (function(a) {
console.log(a.test());
})(a);
So you can see that the file isn't really important. What's important is the scope. b can use a because it is injected into it's scope (In this instance as a IIFE).
In the above example a and b are in the global scope but testStr isn't.
So when your talking about "importing my file", you need to forget about that and think about what objects in that file you want to import how. Any variables "in that file" declared directly var a = ....; are in the global scope. So it sounds like what you want to do is import the objects in that file into the global scope.
you just need to import that file in main.js
like this way
Running a node.js app provides a means to load an included js script as a class/variable.
--- app.js ---
var mine = require('myClass');
mine.DoSomething();
How does node know that MyClass is the file "js/MyClassFile.js"?
What is the HTML <script> equivalent?
It use something called modules.
For example in js/MyClassFile.js there must be something like
exports.myClass = function (r) {
return {DoSomething: function(){} };
};
What is the HTML equivalent?
If by html, you mean browser, then there is options like browserify, systemjs, requirejs, etc, etc
for more info check Writing Modular JavaScript With AMD, CommonJS & ES Harmony by Addy Osmani out.
When you require a file in say app.js, you should use its relative path and export it using module.exports. That's how Node.js knows where to look for it.
--- app.js ---
var mine = require('../myClass')
mine.doSomething();
--- myClass.js ---
var myClass = {
}
module.exports = myClass;
How does node know that MyClass is the file "js/MyClassFile.js"?
Node decides it on basis of relative path so if you are in js folder and try to use var mine = require('myClass'); then it means then myClass is in js folder
for html equivalent you need to use modules but you can do it in es6 like this, please note es6 support is still limited
// lib/math.js
export function sum (x, y) { return x + y }
export var pi = 3.141593
// someApp.js
import * as math from "lib/math"
console.log("2π = " + math.sum(math.pi, math.pi))
// otherApp.js
import { sum, pi } from "lib/math"
console.log("2π = " + sum(pi, pi))
otherwise you can look at this How do I include a JavaScript file in another JavaScript file?
I am facing a weird issue. In my (lets say) a.ts I have -
/// <reference path="../typings/mocha/mocha.d.ts" />
/// <reference path="../typings/should/should.d.ts" />
import should = require('should');
import something_else = require('../something-else');
Now when I compile using command -
tsc -m commonjs --outDir "./build" "src/test/a.ts"
My generated javascript is not having require for should -
/// <reference path="../typings/mocha/mocha.d.ts" />
/// <reference path="../typings/should/should.d.ts" />
var service_manager = require('../routes/service-manager');
This seems like a bug in typescript compiler, but I may be doing it incorrectly. Or if there is some workaround, please share.
It does that because you are not using it. It will stick as soon as you you actually use the should variable. e.g.
/// <reference path="../typings/mocha/mocha.d.ts" />
/// <reference path="../typings/should/should.d.ts" />
import should = require('should');
var persist = should;
Reason: It allows you to use type information on its own without taking a runtime dependency on require('should'). It also allows you to do lazy loading in AMD scenarios.
As the comment by Eric Nicholson, just require without import.
require('should');
// use should
Besides, those reference path would be bundled at typings/tsd.d.ts by default and no need to write in individual file.
I want to switch from JavaScript to TypeScript to help with code management as our project gets larger. We utilize, however, lots of libraries as amd Modules, which we do not want to convert to TypeScript.
We still want to import them into TypeScript files, but we also do not want to generate definition files. How can we achieve that?
e.g. The new Typescript file:
/// <reference path="../../../../definetelyTyped/jquery.d.ts" />
/// <reference path="../../../../definetelyTyped/require.d.ts" />
import $ = require('jquery');
import alert = require('lib/errorInfoHandler');
Here, lib/errorInfoHandler is an amd module included in a huge JavaScript library that we do not want to touch.
Using the above code produces the following errors:
Unable to resolve external module ''lib/errorInfoHandler''
Module cannot be aliased to a non-module type.
This should actually produce the following code:
define(["require", "exports", "jquery", "lib/errorInfoHandler"], function(require, exports, $, alert) {
...
}
Is there a way to import a JavaScript library into TypeScript as an amd Module and use it inside the TypeScript file without making a definition file?
A combination of the 2 answers given here worked for me.
//errorInfoHandler.d.ts
declare module "lib/errorInfoHandler" {
var noTypeInfoYet: any; // any var name here really
export = noTypeInfoYet;
}
I'm still new to TypeScript but it looks as if this is just a way to tell TypeScript to leave off by exporting a dummy variable with no type information on it.
EDIT
It has been noted in the comments for this answer that you can achieve the same result by simply declaring:
//errorInfoHandler.d.ts
declare module "*";
See the github comment here.
Either create your own definition file with following content:
declare module "lib/errorInfoHandler" {}
And reference this file where you want to use the import.
Or add the following line to the top of your file:
/// <amd-dependency path="lib/errorInfoHandler">
Note: I do not know if the latter still works, it's how I initially worked with missing AMD dependencies. Please also note that with this approach you will not have IntelliSense for that file.
Create a file in lib called errorInfoHandler.d.ts. There, write:
var noTypeInfoYet: any; // any var name here really
export = noTypeInfoYet;
Now the alert import will succeed and be of type any.
Typically if you just want to need a temporary-faster-solution, that could be done by defining a new index.d.ts in the root of the project folder, then make a module name like described inside package.json file
for example
// somefile.ts
import Foo from '#awesome/my-module'
// index.d.ts on #awesome/my-module
declare module '#awesome/my-module' {
const bind: any;
export default bind;
}
Ran into that that problem in 2020, and found an easy solution:
Create a decs.d.ts file in the root of your TS project.
Place this declaration:
declare module 'lib/errorInfoHandler';
This eliminates the error in my case. I'm using TypeScript 3.9.7
I dont understand what i'm doing wrong. I've create a TypeScript project in VS2012, and created a file named "Vector.ts", in a sub-directory named "Physics":
// Module
module Physics {
// Class
export class Vector {
constructor(public x: number) { }
}
}
Also, I have the following app.ts file:
/// <reference path="Physics/Vector.ts" />
window.onload = () => {
var vector = new Physics.Vector(6);
};
The project is successfully compiled, but when i launch it, i get the following exception:
0x800a1391 - JavaScript runtime error: 'Physics' is undefined
I don't understand what am i doing wrong...
Thanks.
If you are using AMD style modules with a module loader such as Require.Js, you need an import statement. See Steve's accepted answer here: https://stackoverflow.com/a/14919495/1014822 Your code will look something like:
import Physics = module("Physics/Vector");
var vector = new Physics.Vector(6);
... and you won't need this: /// <reference path="Physics/Vector.ts" />
If you are not using a module loader, you just need to make sure you include your Vector.js output file somewhere in your html page, and make sure it loads before your app file. In this case, you use /// <reference path="Physics/Vector.ts" /> to tell TS where to find your module for intellisense etc. to work.
Just for completeness, if you're using System then you'd use the import function:
System.import("Physics/Vector");
If you're doing this for Angular 2 then you'd want to do this before your bootstrap import