순간 스크립트 모듈 시스템 입력이상하게 행동하는 JS
저는 타입스크립트에서 모멘트Js를 사용하려고 합니다: 타입스크립트를 컴파일하기 위해 사용하는 모듈 시스템에 따라 모멘트Js를 사용하는 방법에 대해 다른 동작을 발견합니다.commonJs로 typescript를 컴파일할 때 모든 것이 예상대로 작동하며 momentJs 문서를 따를 수 있습니다.
import moment = require("moment");
moment(new Date()); //this works
"moment"를 가져올 때 "system"을 유형 스크립트 모듈 시스템으로 사용하면 강제로 해야 합니다.
import moment = require("moment");
moment.default(new Date()); //this works
moment(new Date()); //this doesn't work
사용되는 스크립트 모듈 시스템에 관계없이 둘 다 작동할 수 있는 해결 방법을 찾았습니다.
import m = require("moment")
var moment : moment.MomentStatic;
moment = (m as any).default || m;
저는 이것이 마음에 들지 않고, 왜 이렇게 행동하는지 이해하고 싶습니다.내가 뭘 잘못하고 있나요?무슨 일이 일어나고 있는지 설명해 줄 사람?
교체하여 문제를 해결했습니다.
import moment from "moment";
가져오기 문 포함
import * as moment from "moment";
이것.
은 System의 때문에 일어나는 일입니다.는 자동으로 JS를 .moment
모듈 개체로 래핑하여 ES6 스타일 모듈로 이동합니다(공통).JS는 아닙니다.
공통인 경우JS가 들어오다moment
우리는 실제를 이해합니다.moment
은 우리가 친숙해 입니다.이것은 우리가 자바스크립트에서 한동안 해왔던 것이고, 매우 친숙해 보일 것입니다.마치 다음과 같이 썼습니다.
var moment = function moment() {/*implementation*/}
시스템의 경우JS가 들어오다moment
그것은 당신에게 모멘트 기능을 제공하지 않습니다.가 이이지속성할당모에함라는 된 객체를 .default
마치 다음과 같이 썼습니다.
var moment = {
default: function moment() {/*implementation*/}
}
왜그요? 가진 이어야 하기 입니다.ES6/TS에 따르면 모듈은 함수가 아닌 하나 이상의 속성을 가진 맵이어야 하기 때문입니다.가 ES6에서 자체적으로 내보내는 입니다.default
을 사용합니다.export default
(여기에서 자세히 읽어보십시오. ES6/TypeScript에서는 압축을 사용하여 다음과 같은 기능을 가져올 수 있습니다.import moment from "moment"
구문)을 선택합니다.
잘못된 것이 아니라 가져온 모듈의 형식을 선택하고 원하는 대로 선택하면 됩니다.CommonJS와 System을 모두 사용하려는 경우JS, 동일한 가져오기 스타일을 사용하도록 구성할 수 있습니다.'systemjs default import'를 검색하여 문제에 대한 이 토론을 시작했습니다. 이 토론에서 문제는 다음과 같습니다.--allowSyntheticDefaultImports
설정
다음을 수행했습니다.
는 습했니다를 설치했습니다.moment
정의 파일은 다음과 같습니다.
tsd install moment --save
그런 다음 main.ts를 만들었습니다.
///<reference path="typings/moment/moment.d.ts" />
import moment = require("moment");
moment(new Date());
그리고 나는 도망쳤습니다.
$ tsc --module system --target es5 main.ts # no error
$ tsc --module commonjs --target es5 main.ts # no error
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());
}
}
});
내 TypeScript 버전은 1.6.2입니다.
제가 알아낸 것은 다음과 같습니다.
Momentjs는 함수(즉, 함수)를 내보냅니다._moment = utils_hooks__hooks
그리고.utils_hooks__hooks
함수라는 것은 아주 분명합니다.
만약 당신이 내가 말한 장소에 브레이크포인트를 설치한다면,PLACE XY
위에서, 당신은 그것을 볼 수 있습니다.moment_1
개체(!)이며 함수가 아닙니다.관련 라인: 1, 2
TL;DR: 결론적으로 이 문제는 TypeScript와 관련이 없습니다.문제는 systemjs가 momentjs가 함수를 내보내는 정보를 보존하지 않는다는 것입니다.Systemjs는 내보낸 객체의 속성을 모듈에서 복사하기만 하면 됩니다(JavaScript에서도 함수는 객체입니다).그들이 버그(또는 기능)로 간주하는지 확인하려면 systemjs 저장소에 문제를 제기해야 할 것 같습니다.
System.js 및 Typescript 1.7.5를 사용한 방법은 다음과 같습니다.
import * as moment from "moment";
...
moment.utc(); // outputs 2015 (for now).
하지만 제가 사용하는 것은utc()
방법.사용할 수 없습니다.moment()
왜냐하면 mk.설명했지만, 이것은 로 변환됩니다.moment.default()
system.js에 의해.Of Cause 확실히 유형화된 유형은 다음을 하지 않습니다.default
방법, 그래서 컴파일 오류를 피하기 위해 다음과 같은 것을 사용해야 합니다.moment["default"]()
(알아요, 못생겼어요)
다음 단계에서는 System.js 구성에 다음을 추가해야 했습니다.
System.config({
paths: {
'moment': 'node_modules/moment/moment.js'
}
});
그 후, 모든 것이 매력적으로 작용했습니다.
제가 진행 중인 프로젝트에 참여하는 것은 힘든 일이었지만, 결국 다음과 같은 방법으로 해결했습니다.
import momentRef = require('moment');
var moment: moment.MomentStatic = momentRef;
내 system.config의 경우:
paths: {
'moment': 'node_modules/moment/moment.js'
},
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
구성 요소에서 momentjs를 가져오면서 moment.js 파일의 코드를 여러 개체로 처리하는 *를 제거했습니다.
변경:
import * as moment from 'moment';
대상:
import moment from 'moment';
나는 가지고 있었습니다
import * as moment from 'moment';
그리고 내가 생각했던 모든 것을 바꿨습니다.
var date: moment = moment();
로.
var date: moment.Moment = moment();
유형 스크립트를 사용하는 경우 다음과 같은 기본 가져오기import moment from "moment"
와 동일하게 행동함const moment = require("moment").default
https://www.typescriptlang.org/tsconfig#esModuleInterop 을 참조하십시오.
TLDR; 추가esModuleInterop: true
tsconfig.json에서
만약 당신이 TypeScript를 사용하고 있다면,import * as moment from 'moment
작동 중이지만 InSonarQube는 필요한 특정 멤버를 명시적으로 가져오기 때문에 중요한 오류입니다.
명확한 코드가 더 나은 코드라는 원칙에 따라 모듈에서 사용할 항목을 명시적으로 가져와야 합니다.가져오기 *를 사용하면 모듈의 모든 항목을 가져오므로 유지 관리자가 혼동할 위험이 있습니다.마찬가지로 "module"에서 *을(를) 내보내고 모듈의 모든 내용을 가져온 다음 다시 내보냅니다. 그러면 유지 관리자뿐만 아니라 모듈 사용자도 혼동할 위험이 있습니다.
언급URL : https://stackoverflow.com/questions/32987273/typescript-module-systems-on-momentjs-behaving-strangely
'programing' 카테고리의 다른 글
Select * (all) 문에 행 ID 표시 (0) | 2023.07.06 |
---|---|
동물원에서 월 및 연도 추출:: yearmon 개체 (0) | 2023.07.06 |
Firebase용 Cloud Functions에 대한 시간 초과 설정이 콘솔에서 유지되지 않습니다. 버그입니까? (0) | 2023.07.06 |
샘플 함수를 사용하여 데이터를 교육/테스트 세트로 분할하는 방법 (0) | 2023.07.06 |
장고 쿼리 세트를 딕트 목록으로 변환하려면 어떻게 해야 합니까? (0) | 2023.07.06 |