如何在带有 SystemJS 的 TypeScript 中使用 momentjs?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33938561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use momentjs in TypeScript with SystemJS?
提问by Dror Weiss
My project's setup includes 'jspm' tool for libraries and 'tsd' tool for typings.
我的项目设置包括用于库的“jspm”工具和用于打字的“tsd”工具。
After installing moment's TypeScript d.ts file (these), I can't find a way to load and actually use a moment instance.
安装 moment 的 TypeScript d.ts 文件(这些)后,我找不到加载和实际使用 moment 实例的方法。
In my file (using SystemJS module loading)
在我的文件中(使用 SystemJS 模块加载)
/// <reference path="../../../typings/tsd.d.ts" />
import * as moment from "moment";
import * as _ from "lodash";
...
...
const now = (this.timestamp === 0) ? moment() : moment(this.timestamp);
I get a "TypeError: momentis not a function"
我得到一个“ TypeError:momentis not a function”
The definitions are structured the same as lodash, which works fine, so I don't know what might be the cause.
定义的结构与lodash相同,效果很好,所以我不知道可能是什么原因。
Can anyone help?
任何人都可以帮忙吗?
回答by Martin Vseticka
I did the following:
我做了以下事情:
I installed moment
definition fileas follows:
我按如下方式安装了moment
定义文件:
tsd install moment --save
Then I created main.ts:
然后我创建了main.ts:
///<reference path="typings/moment/moment.d.ts" />
import moment = require("moment");
moment(new Date());
And I ran:
我跑了:
$ tsc --module system --target es5 main.ts # no error
$ tsc --module commonjs --target es5 main.ts # no error
main.js
looks like this:
main.js
看起来像这样:
// https://github.com/ModuleLoader/es6-module-loader/blob/v0.17.0/docs/system-register.md - this is the corresponding doc
///<reference path="typings/moment/moment.d.ts" />
System.register(["moment"], function(exports_1) {
var moment;
return {
setters:[
function (moment_1) {
// You can place `debugger;` command to debug the issue
// "PLACE XY"
moment = moment_1;
}],
execute: function() {
moment(new Date());
}
}
});
My TypeScript version is 1.6.2.
我的 TypeScript 版本是 1.6.2。
This is what I found out:
这是我发现的:
Momentjs exports a function(i.e. _moment = utils_hooks__hooks
and utils_hooks__hooks
is a function, that's quite clear.
Momentjs 导出一个函数(即_moment = utils_hooks__hooks
并且utils_hooks__hooks
是一个函数,这很清楚。
If you place a breakpoint at the place I denoted as PLACE XY
above, you can see that moment_1
is an object (!) and not a function. Relevant lines: 1, 2
如果你在我PLACE XY
上面表示的地方放置一个断点,你可以看到它moment_1
是一个对象(!)而不是一个函数。相关线路:1, 2
To conclude it, the problem has nothing to do with TypeScript. The issue is that systemjs does not preserve the information that momentjs exports a function. Systemjs simply copy properties of the exported object from a module (a function is an object in JavaScript too). I guess you should file an issue in systemjs repository to find out if they consider it to be a bug (or a feature :)).
总结一下,这个问题与 TypeScript 无关。问题是 systemjs 不保留 momentjs 导出函数的信息。Systemjs 只是从模块中复制导出对象的属性(函数也是 JavaScript 中的对象)。我想你应该在 systemjs 存储库中提交一个问题,以确定他们是否认为它是一个错误(或一个特性:))。
回答by Philippe Plantier
Since version 2.13, moment includes Typescript typings. No need to use tsd
(or typings
) anymore.
从 2.13 版开始,moment 包括 Typescript 类型。不再需要使用tsd
(或typings
)。
In the systemjs.config.js
file, just add the following:
在systemjs.config.js
文件中,只需添加以下内容:
var map = {
// (...)
moment: 'node_modules/moment',
};
var packages = {
// (...)
moment: { main: 'moment.js', defaultExtension: 'js' },
};
And in the module:
在模块中:
import moment = require('moment')
回答by RichL
I had immense trouble getting this to work, as I could not use npm due to proxy restrictions (therefore had to manually install the libraries). Provided the versions of moment and definitelytyped files are installed in appropriate locations in your project, you can get this to work with a bit of fiddling around.
我在让它工作时遇到了巨大的麻烦,因为由于代理限制我无法使用 npm(因此必须手动安装库)。如果在您的项目中的适当位置安装了 moment 和绝对类型文件的版本,您可以通过一些摆弄来使其工作。
There is a useful note here on the moment.js website on configuring typescript with moment. The key aspect which helped in my case was adding the following in the compilerOptions section of my tsconfig.json file:
在 moment.js 网站上有一个关于使用 moment配置打字稿的有用说明。对我有帮助的关键方面是在我的 tsconfig.json 文件的 compilerOptions 部分添加以下内容:
"allowSyntheticDefaultImports": true
回答by Josh Werts
This works with Angular 2 but shouldn't be specific to it. You're basically just telling the System loader where to find moment.min.js
.
这适用于 Angular 2,但不应特定于它。您基本上只是告诉系统加载程序在哪里可以找到moment.min.js
.
In system.config.js
:
在system.config.js
:
// map tells the System loader where to look for things
var map = {
'app': 'app', // 'dist',
'@angular': 'node_modules/@angular',
'rxjs': 'node_modules/rxjs',
// tell system where to look for moment
'moment': 'node_modules/moment/min'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
// tell system which file represents the script when you import
'moment': { main: 'moment.min.js', defaultExtension: 'js'}
};
In your module:
在您的模块中:
import moment from 'moment';
OR (Edit 10/13/2016):
或(编辑 10/13/2016):
import * as moment from 'moment';
Some commenters have posted the import *
syntax above and I had to switch to that as well after some upgrades (not sure why).
一些评论者发布了import *
上面的语法,在一些升级后我也不得不切换到那个语法(不知道为什么)。
回答by Jojo
In my typescript file, when I use
在我的打字稿文件中,当我使用
import moment from 'moment';
it says cannot find module 'moment'. I have installed moment as npm package and it referenced properly but for the reason, that moment.d.ts exports the moment as namespace not module as below, i cannot reference it.
它说找不到模块“时刻”。我已经将 moment 安装为 npm 包并且它被正确引用,但是由于这个原因,moment.d.ts 将 moment 作为命名空间而不是模块导出,如下所示,我无法引用它。
export = moment;
So if i change it to
所以如果我把它改成
declare module 'moment' {
export default moment;
}
importing works perfectly. What I am doing wrong here?
导入工作完美。我在这里做错了什么?
回答by Mark Dolbyrev
It's a bit not clear if you try to use moment for the client-side development or for the server-side (e.g. node.js). But, if your case is front-end, then I was able to use moment pretty ease:
如果您尝试将moment用于客户端开发或服务器端(例如node.js),则有点不清楚。但是,如果您的案例是前端的,那么我可以非常轻松地使用 moment:
1) I just added files to my project:
1)我刚刚将文件添加到我的项目中:
2) Wrote a simple test code:
2)写了一个简单的测试代码:
window.onload = () =>
{
var timestamp: number = 111111111111111;
var momentResult: moment.Moment = moment(timestamp);
alert(momentResult.toISOString());
};
And my project was built OK and I saw a test alert in the browser.
我的项目构建正常,我在浏览器中看到了一个测试警报。
回答by smajl
Just done it in my project. It's angular, but I don't think that matters and might put you on the right path. It's easy as:
刚刚在我的项目中完成了。它是有角度的,但我认为这并不重要,可能会让你走上正确的道路。这很容易,因为:
import MomentStatic = moment.MomentStatic;
class HelpdeskTicketController {
constructor(private moment: MomentStatic) { // angulars dependency injection, you will have some global probably
let d = this.moment(new Date()); // works
console.log(d.add(2, 'hours').format()); // works
}
...
回答by LazerBass
I assume moment was installed using
我假设 moment 是使用安装的
jspm install moment
This should add an entry in the map section of your config.js.
这应该在 config.js 的 map 部分添加一个条目。
...
"moment": "npm:[email protected]",
...
This way you can access moment in your js files via
这样您就可以通过以下方式访问您的 js 文件中的 moment
import moment from 'moment';
console.log(moment().format('dddd, MMMM Do YYYY, h:mm:ss a'));
When you import * as moment
you import the module namespace. So moment will be an object which properties are module exports. That way the default export does not get imported as moment but as moment.default.
So something like
导入时,* as moment
您会导入模块命名空间。所以 moment 将是一个属性是模块导出的对象。这样默认导出不会作为 moment 导入,而是作为 moment.default 导入。所以像
moment.default().format('dddd, MMMM Do YYYY, h:mm:ss a')
might actually work in you code but is not the way it is intended to be used.
可能实际上在您的代码中工作,但不是它的预期使用方式。
回答by Thomas.Benz
For my stuffs, I use Webpack with VS 2015 (Update 3). So after adding codes for the package.json and webpack.config.vendor.js files, I just need to call import moment = require('moment') on the very top of my component (TypeScript, Angular 2).
对于我的东西,我将 Webpack 与 VS 2015(更新 3)一起使用。因此,在为 package.json 和 webpack.config.vendor.js 文件添加代码后,我只需要在组件(TypeScript、Angular 2)的最顶部调用 import moment = require('moment') 即可。