如何在流星应用程序中集成requirejs并使用AMD模块,例如我的Backbone模块?有没有人这样做,可以告诉我需要哪些步骤来实现这个目标?
问题:有没有办法使用AMD支持(通过编译器)将jquery导入TypeScript模块,因此它包含jquery作为依赖项?
关键是获取import语句,这使得模块成为define语句中的依赖项(见下文).
define(["require", "exports", 'dataservice', 'jquery', 'knockout'],
function(require, exports, __ds__, $ , ko) {
...
}
)
Run Code Online (Sandbox Code Playgroud)
详细信息:我想将jquery(和其他第三方库)导入为AMD的TypeScript模块.目标是使它们在require列表中显示为依赖项.但是,使TypeScript执行此操作的唯一方法似乎是拥有一个import语句.要导入,您需要导入模块.但是......没有jquery模块可以指向.至.
解决方法:
所以现在我只是在main.js中预加载jquery.但又一次,但这不太理想.必须为任何没有模块的淘汰赛,骨干等图书馆做到这一点.
有什么更好的建议或我遗漏的东西?
更新/澄清:
我还可以在配置中使用填充程序来获取库之间的依赖关系.但这仍然预先加载第三方.例:
require.config({
baseUrl: '../',
paths: {
'jquery': 'lib/jquery-1.7.2',
'underscore': 'lib/underscore'
},
shim: {
jquery: {
exports: '$'
},
underscore: {
exports: '_'
}
}
});
Run Code Online (Sandbox Code Playgroud) 许多JavaScript库都有一个Builder工具,它允许您"塑造"您所依赖的库的哪些功能,包括客户端的下载带宽成本和隔离实际需要的功能.
例如,我喜欢sugar.js中的很多东西,但我根本不需要或想要片假名和平假名字符集处理.作为最简单的例子,我希望能够"塑造"sugar.js以仅导出string.isBlank().
有没有可以为我这样做的工具?在未来的JavaScript版本中,EcmaScript委员会是否正在继续努力做这样的事情?像TypeScript和CoffeeScript这样的高级语言是否为这种"整形"提供了隐藏的支持?我可以通过monolinker在C#for .NET DLL中进行这样的"整形" .
基本上,它看起来像AMD处理现代编译器的Loader方面,但不处理链接器方面.jquery和dojo的构建器只适用于特定的模块,并不是真正的连接器,只是构建器.
更新: Google Closure Compiler是一个编译器,它将JavaScript作为输入并生成JavaScript作为输出.的高级编译和实习医生文档建议有一个API调用来做到这一点:
如果将这些导出语句放在一起看起来太单调乏味,您可以使用函数为您进行导出.有关导出函数的示例,请参阅Closure Library函数goog.exportSymbol()和goog.exportProperty().
但是,这看起来很复杂,让我直接依赖于Google Closure Compiler.在这一点上,我正在寻找关于EcmaScript委员会关于CommonJS的未来标准的信息,以及那些思考这个问题并试图解决它的人的任何智慧.特别是来自TypeScript开发人员; 我不想在TypeScript中为sugar.js创建声明文件,然后对我的TypeScript编译器输出使用Google Closure Compiler.它听起来很复杂,难以调试.
我熟悉exportTypeScript中的关键字,以及使用TypeScript从Node模块导出内容的两种规范方法(当然,也可以使用TypeScript模块,但它们甚至比我正在寻找的更远):
export class ClassName { }
Run Code Online (Sandbox Code Playgroud)
和一系列的
export function functionName () { }
Run Code Online (Sandbox Code Playgroud)
但是,我通常编写模块的方式是:它们稍后作为可实例化的闭包导入,它是:
var ClassName = function () { };
ClassName.prototype.functionName = function () { };
module.exports = ClassName;
Run Code Online (Sandbox Code Playgroud)
有没有办法可以使用TypeScript导出语法执行此操作?
我的Backbone应用程序有一个名为schedule的视图,我对成功和错误调用正确函数的区别有点困惑,我尝试了下面列出的两个可能但我没有什么区别和什么是正确的从外部视图中放置的路由器调用函数的方法:
第一种方式:
require([
'app/collections/schedule',
'app/views/schedule'
], function(ScheduleCollection, ScheduleView) {
var scheduleCollection = new ScheduleCollection(),
scheduleView = new ScheduleView({
model: scheduleCollection
});
scheduleCollection.fetch({
reset: true,
success: function(){
scheduleView.successHandler();
},
error: function(){
scheduleView.errorHandler()
}
});
});
Run Code Online (Sandbox Code Playgroud)
第二种方式
require([
'app/collections/schedule',
'app/views/schedule'
], function(ScheduleCollection, ScheduleView) {
var scheduleCollection = new ScheduleCollection(),
scheduleView = new ScheduleView({
model: scheduleCollection
});
scheduleCollection.fetch({
reset: true,
success: scheduleView.successHandler(),
error: scheduleView.errorHandler()
});
});
Run Code Online (Sandbox Code Playgroud)
在scheduleView中
successHandler: function(){
console.log('success');
}
erroHandler: function(){
console.log('error');
}
Run Code Online (Sandbox Code Playgroud) 我正在使用karma,jasmine,typescript来编写来自https://angular.io/docs/js/latest/quickstart.html的helloworld应用程序的单元测试.
以下是测试代码:
///<reference path="../typings/jasmine/jasmine.d.ts"/>
import {
MyAppComponent
} from '../spray1';
describe("name is Alice", () => {
var comp = new MyAppComponent();
it("verify name", () => {
expect(comp.name).toBe("Alice");
});
});
Run Code Online (Sandbox Code Playgroud)
tsc(带"--module commonjs")将此测试代码转换为:
///<reference path="../typings/jasmine/jasmine.d.ts"/>
var spray1_1 = require('../spray1');
describe("name is Alice", function () {
var comp = new myAppComponent_1.MyAppComponent();
it("verify name", function () {
expect(comp.name).toBe("Alice");
});
});
Run Code Online (Sandbox Code Playgroud)
业力未能运行单元测试:
未捕获错误:尚未为上下文加载模块名称"../myAppComponent":_.使用require([]) http://requirejs.org/docs/errors.html#notloaded at /Users/spray1/web2/node_modules/requirejs/require.js:141
Chrome 43.0.2357(Mac OS X 10.10.3):执行0 0成功(0秒/ 0秒)
如果我使用tsc"--module amd",则转换后的测试代码为:
define(["require", "exports", '../spray1'], function (require, exports, spray1_1) { …Run Code Online (Sandbox Code Playgroud) 我想定义一个typescript接口来表示一个错误.像这样的东西:
enum MessageLevel {
Unknown,
Fatal,
Critical,
Error,
Warning,
Info,
Debug
}
interface IMyMessage {
name: string;
level: MessageLevel;
message: string;
}
Run Code Online (Sandbox Code Playgroud)
这样可以正常工作.但是,现在(也许)我想在.d.ts文件中声明该接口,以便其他人可以使用它进行输入.但我不想在.d.ts文件中定义枚举,因为那将是实现而不是简单的输入信息.枚举应该在.ts文件中,我们称之为messageLevel.ts:
///<amd-module name='MessageLevel'/>
export enum MessageLevel {
Unknown,
Fatal,
Critical,
Error,
Warning,
Info,
Debug
}
Run Code Online (Sandbox Code Playgroud)
此时我可以通过这种方式在我的d.ts打字文件中使用它:
import * as ml from "./MessageLevel";
interface IMyMessage {
name: string;
level: ml.MessageLevel;
message: string;
}
Run Code Online (Sandbox Code Playgroud)
我可以使这项工作,但我不喜欢将实现文件导入打字文件的级别混合.我也不喜欢在打字文件中实际实现枚举的想法.
是否有一种干净的方法来保持实施和声明严格分开?
我正在使用RequireJS和Backbone.js开发移动应用程序.我想通过向每个锚添加data-transition和data-direction属性来指定从一个页面到另一个页面的转换(与jQuery Mobile一样):
<a href="#home" data-transition="slide" data-direction="left">Go to the home page</a>
Run Code Online (Sandbox Code Playgroud)
我的所有视图都扩展了一个基本视图,它将一个单击处理程序附加到锚点并捕获这些属性的值:
define([
'zepto',
'lodash',
'backbone'
], function ($, _, Backbone) {
'use strict';
BaseView = Backbone.View.extend({
events: {
'click a': 'navigate'
},
navigate: function (e) {
e.preventDefault();
var href = $(e.currentTarget).attr('href'),
transition = $(e.currentTarget).attr('data-transition'),
direction = $(e.currentTarget).attr('data-direction');
Backbone.history.navigate(href, true);
}
});
});
Run Code Online (Sandbox Code Playgroud)
我的问题是我不知道如何将这些值传递给路由器的路由处理程序,定义为另一个模块:
define([
'zepto',
'lodash',
'backbone'
], function ($, _, Backbone) {
'use strict';
var Router = Backbone.Thumb.Router.extend({
routes: {
'': 'home'
}
});
var …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Typescript将Durandal与node.js服务器集成,以便在服务器端和客户端上定义模块.
我遇到的问题是Durandal强烈依赖于RequireJS和AMD风格的定义模块,我不想在服务器端引入,因为它使用RequireJS我没有任何机会运行CommonJS-ish模块在客户端上(node.js的默认值).
棺材中的最后一个问题是,我发现没有办法定义哪些文件应该编译为AMD模块,哪个文件作为CommonJS由tsc编写 - 这似乎是最简单的解决方案.
我不认为分离客户端部分和服务器部分是一种选择,因为很多代码对于这两个部分都是通用的.
所以,我的问题有三个:
有没有办法在相同的Typescript项目中混合AMD和CommonJS模块(最好使用NodejsTools)
如果没有,有没有办法强迫Durandal使用CommonJS文件来加载视图/视图模型等等
如果这一切都不可能,那么在node.js服务器上使用AMD模块是可能的(也是明智的)
任何想法都受到高度赞赏
我对在ember-cli中导入依赖关系感到困惑,尤其是关于标准AMD案例,正如官方Ember Cli文档中所提到的那样.该文档没有提供太多的例子,在我看来,它假设读者对AMD有很好的了解,但对我来说并非如此.我的直接用例是import math.js. 不幸的是,math.js的官方文档没有提供有关使用Ember Cli导入的示例.然后,我发现这篇文章有相对更清晰的例子,特别是下面的例子似乎非常相关.
app.import({
development: 'vendor/lodash/dist/lodash.js',
production: 'vendor/lodash/dist/lodash.min.js'
}, {
'lodash': [
'default'
]
});
Run Code Online (Sandbox Code Playgroud)
然后,我用math.js做了类似的事情,如下所示:
app.import({
development: 'bower_components/mathjs/dist/math.js',
production: 'bower_components/mathjs/dist/math.min.js'
}, {
'mathjs': [
'default'
]
});
Run Code Online (Sandbox Code Playgroud)
但是,它不起作用.当我尝试使用它时
import mathjs from 'mathjs'
Run Code Online (Sandbox Code Playgroud)
我收到了一个错误.最后,我使用了以下解决方案:
// Brocfile.js
app.import('bower_components/mathjs/dist/math.min.js');
// some controller.js
var math = window.math
Run Code Online (Sandbox Code Playgroud)
虽然上面的解决方案有效,但我不喜欢它,因为它可能会受到名称冲突的影响.此外,基于math.js的文档,在我看来它应该支持标准的AMD类型的导入.
所以,我的问题如下.
1.在lodash上面的例子中,'default'意思是什么?这是对相应模块中导出的任何内容的一般参考吗?如何判断我是否可以使用它(例如,math.js)?
2.如果模块支持require.js,那么它是标准的AMD模块吗?如果是这样,给出如下代码:
require.config({
paths: {
mathjs: 'path/to/mathjs',
}
});
require(['mathjs'], function (math) {
// use math.js
math.sqrt(-4); // 2i
}); …Run Code Online (Sandbox Code Playgroud) amd ×10
javascript ×6
typescript ×6
requirejs ×3
backbone.js ×2
node.js ×2
commonjs ×1
durandal ×1
ember-cli ×1
ember.js ×1
karma-runner ×1
mathjs ×1
meteor ×1
mobile ×1