Typescript RequireJs Shortcuts + Navigation - javascript

I am having these requireJs options defined:
require.config({
baseUrl: '/js/',
paths: {
jquery: '/components/jquery/dist/jquery',
foundation: '/components/foundation/js/foundation',
fastclick: '/components/fastclick/lib/fastclick',
angular: '/components/angular/angular',
angularRoute: '/components/angular-route/angular-route',
socketIO: '/components/socket.io-client/dist/socket.io'
},
shim: {
'foundation': {
deps: ['jquery', 'fastclick']
},
'angular': {'exports': 'angular'},
'angularRoute': ['angular']
},
priority: [
'angular'
]
});
these are working all fine, if i am using requireJs in the javascript syntax. Then the base url and all these nice shortcuts for external libraries work.
But I am asking you now if i can also use these shortcuts in the Typescript way.
Because If i am saying: for instance in a file
import angular = require('angular');
it isnot importing the file. I am ofc compiling the source with the amd option.
Also can someone provide me links how to navigate through the project with these import statement.
this structure is what i am using for my current project. There I have a client (public) folder and if i want to access a js file for instance in the browser. I have to write: localhost/js/file.js
Now when i am using requireJs in the js syntax I can easily write things like controllers/userController and it navigated to the right folder, but how do i have to navigate within my import/require?
currently I have to use relative paths from the file i am using the import but that is not very wise

I did this to make it work :)
/// <reference path="./types/angular/angular.d.ts" />
declare module 'angular'{
var angular:ng.IAngularStatic;
export = angular;
}
// now you can do:
import angular = require('angular');

Related

How to import from nested module?

I have a Typescript library I've written which is being emitted as follows. I'm not sure how to import from this module, though.
node_modules/my-module/dist/index.js (partial)
define("services/UserService", ["require", "exports", ..., "services/BaseService"], function (require, exports, ..., BaseService_31) {
"use strict";
var UserService = (function (_super) {
// ... stuff here ...
return UserService;
}(BaseService_31.BaseService));
exports.UserService = UserService;
});
I've installed this package with npm and configured JSPM as follows:
config.js (partial)
System.config({
defaultJSExtensions: true,
transpiler: "none",
paths: {
"*": "dist/*",
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*",
"npm-ext:*": "node_modules/*"
},
map: {
...
"my-module": "npm-ext:my-module/dist/index.js",
...
}
});
I was expecting to be able to import this class as follows...
import {UserService} from "my-module/services/UserService";
I expected SystemJS to resolve the path to my-module and then locate the services/UserService module, and grab the single export UserService. But in the Chrome Console I see this is the path which is being loaded:
node_modules/my-module/dist/index.js/models/UserService.js
What's the correct way to import a module such as this?
Bonus: how can I get around including the full path to index.js?
Your library code was emitted using named define
define("services/UserService",
And it looks like there are several such modules defined in the index.js file, that is, index.js is a bundle.
The only way to import such module using SystemJS is
import {UserService} from "services/UserService";
That is, imported module name must match exactly the name given to define. In your case, the location of the file does not affect module name in any way.
Now, SystemJS has to be configured to load library file, node_modules/my-module/dist/index.js, when it sees that import. For bundles, the preferred way to to it is via bundles config:
bundles: {
"npm-ext:my-module/dist/index.js": ["services/UserService.js"]
}
Module name here, services/UserService.js, must have .js extension because it must match imported module name after defaultJSExtesions:true is applied.
If you want the module to be imported as my-module/services/UserService.js, then you need to make sure it is registered with that name. The easiest way is to have corresponding source file structure when compiling the library - that is, have UserService.ts in my-module/services folder.
You can find more information about named define in SystemJS module format docs, which says in particular
Named defines are supported and will write directly into the loader registry.
A single named define will write into the loader registry but also be treated as the value of the module loaded if the names do not match. This enables loading a module containing define('jquery', ....
P.S. Your browser tries to load
node_modules/my-module/dist/index.js/models/UserService.js
where does models come from?

Using webpack to process an AMD library with external dependencies

I have a library written in AMD style that can be used with RequireJS. jquery and jquery-ui are assumed to be provided by the user of the library. Say it looks like this:
// main-lib.js
define(['jquery', './aux-lib.js'], function ($) { ..(1).. });
// aux-lib.js
define(['jquery', 'jquery-ui'], function ($) { ..(2).. });
I'm trying to figure out how webpack works. For example, say I want to bundle these files into a single AMD style library file that still assumes jquery and jquery-ui from the outside:
// out.js
define(['jquery', 'jquery-ui'], function ($) { ..(1)..(2).. } );
How is this accomplished?
When I run webpack with main-lib.js as entry-point, it will complain that it can't find jquery and jquery-ui. If I configure the correct paths with resolve.alias, it bundles jquery and jquery-ui into out.js, which is not what I want. I tried using output.externals to no avail.
This was a pretty simple, stupid mistake on my part. The relevant field is not output.externals, but simply externals. See here. The other two relevant fields introduced there are inside output, but externals is not.
PS: externals can also be an array. Here is my current configuration:
{
entry: './main-lib.js',
output: {
path: './',
filename: 'out.js',
libraryTarget: 'amd'
},
externals: ['jquery', 'jquery-ui']
}
It's working quite nicely.

How to use require.js with complicated source tree, or import something else from CommonJS'es main.js?

My JS code is Backbone.js based, so I think it is a good idea to separate "classes" with this logic as shown on picture (though I'm not sure where to place templates - in this packages or in global templates folder, and do not mind main.js - it is not related to CommonJS packages) :
Now since there is fairly lot of them - I've decided to use require.js to deal with this bunch of <script src=... tags but got stuck with app.js config file (which is the only one that I include like this -
<script data-main="/static/js/app.js" src="/static/js/libmin/require.js"></script>
What do I mean with stuck - of course I can iterate all this js files in require statement using names like PlayerApp/PlayerAppController.js, or using paths directive (not sure if it will make the code look not that ugly), but it would be cool if I can use something like python's from package import *, and of course there is no such thing in require.js.
The most similar thing is packages directive, but seems like it allows you to import only main.js from each package, so then the question is - what is the most correct way to load other files of concrete package from CommonJS's main.js? I have even found a way to determine current .js file's name and path - like this, and given that I can make up other files names in current package(if I will keep naming them with the same pattern), but still do not know how to import them from main.js
Edit:
There might be an opinion that it is not very clear what exactly am I asking, so let me get this straight: how on Earth do I import a huge amount of javascript files with that project structure in the most nice way?
You are mis-understanding the purpose of a module loader. require.js is not there to make it easy for you to import all of your packages into the current namespace (i. e. the browser). It is there to make it easy to import everything you need to run app.js (based on your data-main attribute). Don't try to import * - instead, just import thingYouNeed.
Configuration
What you will want to do is set up your require.config() call with all the necessary paths for libraries like Backbone that don't support AMD and then update your code to explicitly declare its dependencies:
require.config({
// Not *needed* - will be derived from data-main otherwise
baseUrl: '/static/js/app',
paths: {
// A map of module names to paths (without the .js)
backbone: '../libmin/backbone',
underscore: '../libmin/underscore',
jquery: '../libmin/jquery.min',
jqueryui.core: '../libmin/jquery.ui.core'
// etc.
}
shim: {
// A map of module names to configs
backbone: {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
underscore: {
exports: '_'
},
jquery: {
exports: 'jQuery'
},
// Since jQuery UI does not export
// its own name we can just provide
// a deps array without the object
'jqueryui.core': ['jquery']
}
});
Dependencies
You will want to update your code to actually use modules and declare your dependencies:
// PlayerAppModel.js
define(['backbone'], function(Backbone) {
return Backbone.Model.extend({modelStuff: 'here'});
});
// PlayerAppView.js
define(['backbone'], function(Backbone) {
return Backbone.View.extend({viewStuff: 'here'});
});
// PlayerAppController.js
define(['./PlayerAppModel', './PlayerAppView'],
function(Model, View) {
// Do things with model and view here
// return a Controller function of some kind
return function Controller() {
// Handle some route or other
};
});
Now, when you require(['PlayerApp/PlayerAppController'], function(Controller) {}) requirejs will automatically load jQuery, underscore, and Backbone for you. If you never actually use mustache.js then it will never be loaded (and when you optimize your code using the r.js compiler, the extra code will be ignored there as well).

Working with breeze and requireJS

So there have been similar questions floating around, but I am hoping to get an up-to-date answer on this.
Versions-
breeze: 1.4.0
Knockout: 2.2.1
RequireJS: 2.1.5
I am trying to load breeze in a requireJS project with knockoutJS. Our requireJS config is very simple-
require.config({
waitSeconds: 15,
paths: {
'templates': "/ist-common/templates",
'lib': '/ist-common/js/lib',
'ist': '/ist-common/js/ist'
}
});
So I loaded the breeze libs into the following directory structure-
lib
---->q.js
---->breeze.debug.js
I am trying to define a "dataservice" module to use breeze and set it up like so-
define(['lib/knockout', 'lib/q', 'lib/breeze.debug'], function (ko, Q, breeze) {
var serviceName = '/ist/rest'; // route to the endpoint
var manager = new breeze.EntityManager(serviceName);
manager.enableSaveQueuing(true);
var query = new EntityQuery("missions");
manager.executeQuery(query, function(data) {
console.log("success");
});
});
Is this configuration possible? I am trying to keep my scripts tags down to a minimum and load only requireJS and then load knockout, jquery etc. as I need them inside my module definitions.
This config currently fails with a message-
Error: Unable to initialize Q. See https://github.com/kriskowal/q
EDIT*
I was able to get it to load Q with the following config for require, however this feels wrong. Why should I be setting window.Q? Shouldn't I be able to access Q as a named module?
var require = {
waitSeconds: 15,
deps: ["/ist-common/js/lib/q.js"],
callback: function(Q){
window.Q = Q;
},
paths: {
'templates': "/ist-common/templates",
'lib': '/ist-common/js/lib',
'ist': '/ist-common/js/ist'
}
};
You also need a shim for breeze (from Using Angular with breeze and require)
breeze: {
deps: ['ko', 'jquery', 'Q']
},
This is required because although breeze does define itself it does not define its dependencies, it just expects them to be there (RequireJs cant interpret it's dependancies in a variable instead of a string?).
The shim is also required because breeze requests 'jQuery' but the jQuery code defines itself as 'jquery'

Requirejs, almond, backbone, handlebars

Here's my situation, using Backbone and Handlebars with Requirejs.
I'm following CommonJS module definition style, because I find myself to be more comfortable with it:
define(function(require) {
var Backbone = require('Backbone')
var Item = require('model/item')
// ...
})
And this is my requirejs config:
require.config({
baseUrl: "/javascripts/",
paths: {
jquery: 'components/jquery/jquery',
underscore: 'components/underscore/underscore',
backbone: 'components/backbone/backbone',
handlebars: 'components/handlebars/handlebars',
text: 'components/text/text'
},
shim: {
underscore: {
exports: "_"
},
handlebars : {
exports: "Handlebars"
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
Everything is running smooth before optimization, no problem occurs.
But, after optimization with r.js dependencies seem to break.
I'd like to use Almond js in production, so here's my build file:
({
baseUrl: ".",
paths: {
jquery: "components/jquery/jquery",
underscore: "components/underscore/underscore",
handlebars: "components/handlebars/handlebars",
backbone: "components/backbone/backbone",
text: "components/text/text"
},
// we use almond minimal amd module loader
name: "components/almond/almond",
// the application entry point
include: ['app/init'],
// we need to teel almond to require app/init
insertRequire: ['app/init'],
out: "main.js",
cjsTranslate: true,
wrap: true,
optimize: "none"
})
Now, when I run the optimized javascript in browser, all I get are error messages, saying me that jQuery and Handlebars are undefined (neither Backbone.$ is, of course).
A simple workaround was to force jQuery loading, and assigning it to Backbone, like this:
var $ = require('jQuery')
var Backbone = require('Backbone')
Backbone.$ = $
But it sounds very silly and redundant to me.
I feel like I'm doing something wrong but cannot figure out what.
After optimization Handlebars fail to load as dependency too.
If I force its loading (as I did with jQuery), I get an error message during the build process, saying me that the module fs (a npm package) cannot be found.
I googled but found only this topic on Google groups (https://groups.google.com/forum/?fromgroups=#!topic/requirejs/lYwXS-3qjXg) that seems to be related to my problem, even if proposed solutions are not working at all.
I think you should add the Shim's config in your build file too.

Categories

Resources