Skip to content
This repository

jQuery AMD Module Issues #58

Closed
seanhess opened this Issue · 12 comments

3 participants

Sean Hess Felix Jorkowski Diullei Gomes
Sean Hess

Maybe there's some really easy way to make this work in TS that I'm not seeing.

I want to load jQuery as an AMD module, not as a global. jquery.d.tsas currently defined does not export a jquery external module. Instead it defines the $ and jQuery variables as global variables.

Is there a simple way to declare an external module that has the same signature as JQueryStatic?

If not, is it possible to change jquery.d.ts to support external module loading?

Here's how I have it working so far. The problem is I have to manually copy the whole JQueryStatic definition into jquery.d.ts. I don't want to do this. I want to take advantage of your work. Is there something I should do differently, or something that should be changed in jquery-1.8.d.ts?

folders

public/
  components/
    DefinitelyTyped/ (etc)
lib/
  jquery.d.ts
main.ts
config.js

config.js

requirejs.config({
    paths: {
        'lib/jquery: 'path/to/jquery/lib',
    }
})

main.ts

import $ = module("lib/jquery")
console.log("HI", $.ajax)

lib/jquery.d.ts

///<reference path="../components/DefinitelyTyped/Definitions/jquery-1.8.d.ts" />

declare module "lib/jquery" {
    export function ajax(settings: JQueryAjaxSettings): JQueryXHR;
    export function ajax(url: string, settings?: JQueryAjaxSettings): JQueryXHR;

    export function (selector: string, context?: any): JQuery;
    export function (element: Element): JQuery;
    export function (object: { }): JQuery;
    export function (elementArray: Element[]): JQuery;
    export function (object: JQuery): JQuery;
    export function (func: Function): JQuery;
    export function (array: any[]): JQuery;
    export function (): JQuery;
}
Felix Jorkowski

Hi Sean,

I have the same issues with TS... the way I would like to see it work is that at the bottom of the jQuery def file you could add something along the lines of:

export module 'lib/jquery' : jQueryStatic;

and then we would go

///<reference path="../components/DefinitelyTyped/Definitions/jquery-1.8.d.ts" />
import $ = module('lib/jquery');

and of course it would get translated to

define(['lib/jquery'], function($) {})

Unfortunately it does not work like that :( The closest I can get to that is the following. You only have to define a single property in your export like (I put it at the bottom of the def file, but you could just as easily but it in a seperate d.ts file where ever you like)

module 'lib/jquery' {
    export function (): JQuery;
}

Then in your actual file

///<reference path="../path/to/module/def.d.ts" />
import jQuery = module('lib/jquery');
var $ = <jQueryStatic>jQuery;

The reason you need to have a single property is because ts completely ignores the module if you dont.

I know the casting sucks... and the module def sucks... The problem is that everyones requirejs path might be different (I use 'jquery' instead of 'lib/jquery' for example) so I don't think we could put it into the base definition.

The positive is that even as the definitions change it means you don't have to keep copying into your module. Also you can place the module definition anywhere you like... so it fixes that.

Hope that helps

Sean Hess
Sean Hess

Ok, this works, but it's lame. If we chose a convention, at least until TS is fixed, we could avoid having to cast everywhere.

If we changed this repo to either use declare module instead of defining a global variable, or duplicated the static definition or something, we could just settle on standard module names and get on with our lives.

I would switch to using "jquery" instead of "lib/jquery" if the files in this repo supported amd.

Maybe we can make separate amd files in this repo?

Felix Jorkowski

Yeah... I agree... I will give it another go and see if we can combine it. I mean it wouldn't matter if we had the global dec and the module dec. One case would be used by AMD peeps and the global will be used by everyone else.

I think it might actually be better to define all the modules as 'lib/jquery'. That way it is more flexible. In this case if jquery is in your base path you can always add the path { lib: './' } to make it all match up. And if not you can use whatever path you want. Does that make sense?

Sean Hess
Sean Hess

We should collaborate with this guy on a standard. https://github.com/Diullei/tsd#readme. Looks like he's dropping everything into a "d.ts" folder.

It sounds like maybe you know something about TS that I don't know though. If we pick "lib/jquery" wouldn't that mean you MUST put jquery.d.ts into a "lib" folder?

Felix Jorkowski

Yeah... I think in require you could configure a lib path, so something like

path: { lib: './' }

But I think lib is a common name... so maybe just 'def/jquery'. The reason why I think it would be worth doing it like that is because say you are using multiple defs, and they are not in your base path, you would have to define each one seperately in require like

path: { jquery: './path/to/jquery', knockout: './path/to/knockout' }

If all the modules are defined in 'def/module' then you can just go

path: { def: './path/to' }

Anyways... I tried to hack the crap out of it and it is no use. I think the only way to make it work is to add a module 'jquery' {} copy everything into it and make them all exportable. This makes it all work though... you just have to go

import $ = module('jquery');

and it will be properly typed. Also it doesn't matter if they are both defined in the same file.

EDIT: I tried this route but it is not going to work... if you define a module 'jquery' then the import will be of type 'jquery' and not JQueryStatic. This has issues because you cannot extend the module. Say for instance you add a new method to jquery you can usually go

interface JQueryStatic {
    myNewMethod: any;
}

you cannot do this with the module approach :(

import $ = module('jquery');

// Can't work out anything to add here to extend def of $

I don't think there is any way to do the import while still getting the type JQueryStatic. I think just have to wait till the TS people fix it...

Sean Hess
Sean Hess

I added an issue on the TS site: http://typescript.codeplex.com/workitem/388 that I feel would solve the problem. Feel free to vote up.

That really sucks about not being able to extend it with the module approach. Basically module aren't powerful enough yet. I think I'm going to just use globally loaded 3rd party libs until this is fixed by someone else. Wasted too much time already :)

Diullei Gomes
Collaborator

I Saw in this link that the ES6 import module pattern will change. I hope this issue be solved with this change.

Diullei Gomes
Collaborator

This is a typescript issue. I'll close this issue. I hope the typescript team solve this problem in the next version.

To follow this issue on typescript project go to: http://typescript.codeplex.com/workitem/388

Sean Hess
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.