2017-09-30 4 views
2

TL 컴파일 된 PureScript 모듈에 대해 TypeScript 입력을 만들고이를 npm 패키지에 배포하려고합니다. 필자는 수동으로 이러한 타이핑을 유지하는 것보다 행복합니다. tsconfig.json (up 및 downstream) 및 package.json에 넣어야 할 사항을 파악할 수 없습니다.PureScript에서 컴파일 된 JavaScript 모듈을 사용하는 TypeScript 프로젝트는 어떻게 구성합니까?


나는 핵심 기능은 타이프 CLI와 PureScript에서 구현되는 project를 가지고 있고,이 모든 것이 궁극적으로 NPM을 통해 자바 스크립트로 배포됩니다. 내가 안전하게 타이프에서 그들을 사용할 수 있도록 내가 PureScript 모듈에 타이프 라이터 유형을 정의 types/People.d.ts에서

module People where 

type Person = { name :: String } 

david :: Person 
david = { name: "David "} 

: src/People.purs에서

. 
├── cli     # TypeScript CLI project 
│   ├── main.ts 
│   └── tsconfig.json 
│ 
├── output    # Compiled PureScript modules 
│   └── People 
│    ├── externs.json 
│    └── index.js 
│ 
├── src     # PureScript source 
│   └── People.purs 
│ 
└── types     # TypeScript types for PureScript modules 
    └── People.d.ts 

내가 핵심 기능을 정의 : 나는 간단한 레이아웃과 similar project을 만들었습니다 :

declare module "People" { 
    export interface Person { 
     name: string; 
    } 

    export const david: Person; 
} 

마지막으로, cli/main.ts에, 나는 TypeSc로 컴파일 된 PureScript 모듈을 가져올

import * as People from "People"; 

console.log(People.david); 

내가이 구축 얻을 수 있지만 궁극적 인 자바 스크립트 (node cli/main.js)를 실행하려고 할 때 절대 paths-를 사용하지 않기 때문에, tsc에 의해 생성 된 require 호출이 실패 : ript 유형 I은 정의한 - require("People")은이 경우 require("./People")이어야합니다. TypeScript에서 import 문을 상대적으로 만들면 입력이 연결 해제됩니다.

나는이 목표를 달성 힘든 시간을 보내고 있습니다 :

  • 는 타이프에서 가져온 모든 PureScript 모듈에 타이프 라이터의 typings을 유지한다.
  • TypeScript가 유형 검사를하는지 확인하십시오.
  • 런타임시 require이 PureScript 모듈을 요구하는지 확인하십시오.
  • TypeScript 소비자가 이러한 입력을 사용할 수 있도록 npm 패키지로 TypeScript 입력을 배포하십시오.

TypeScript에서 PureScript 모듈을 필요로하고 npm을 통해이 모든 것을 배포 한 경험이 있다면 몇 가지 지침을 정말 고맙게 생각합니다!

답변

0

모듈이 아닌 네임 스페이스를 선언하면 모든 것이 작동합니다.예를 들어, types/People.d.ts에서 : PureScript 모듈을 컴파일 후

declare namespace People { 
    export interface Person { 
     name: string; 
    } 

    export const david: Person; 
} 

export = People; 
export as namespace People; 

와 타이프 라이터를 컴파일하기 전에, I cp types/People.d.ts output/People/index.d.ts. 이로 인해 TypeScript 코드는 동일한 절대 가져 오기 (예 : import * as People from "People";)에 만족하며 TypeScript 라이브러리는 추가 구성없이 이러한 유형을 볼 수 있습니다.

몇 가지 문제가 있지만, 남아 :

  • 나는 여전히 (빌드 후 단계에서 ../를 앞에 붙이는) 컴파일 된 타이프의 PureScript 모듈 수입을 상대화 할 수있다; 내 라이브러리의 소비자는 npm을 거쳐야 마술처럼 작동하므로이 작업을 수행 할 필요가 없습니다.
  • 마침표가있는 네임 스페이스를 내보내는 방법을 알아낼 수 없으므로 Data.Maybe과 같은 모듈은 Data_Maybe과 같은 네임 스페이스로 표시됩니다.
  • 네임 스페이스와 모듈에 대해 잘 모르기 때문에 다른주의 사항이있을 수 있습니다.
1

Purescript 모듈은 "사람"이라고하지만 "사람"이어야합니다. 내 생각에 상대 경로 가져 오기를 사용하면 부분적으로 가져올 수도 있지만 d.ts 파일에 상대 경로 입력과 같은 것이 있다고 생각하지 않습니다.

나는 프로젝트를 체크 아웃하고 모듈 이름을 변경, 그때는 참으로 allowJs를 설정하고 모듈 인라인 입력 :

import * as OutputPeople from "../output/People"; 

type Person = { 
    name: string; 
}; 

type PeopleModule = { 
    david: Person 
} 

const People: PeopleModule = OutputPeople 

console.log(People.david); 

여기 나뭇 가지에 내 수정을 넣어 : https://github.com/justinwoo/ps-js-ts-interop/commit/fc7c1239f9d1bac1cf2bea35f7a07d30c46a5f64

+0

아, 그래요, 오타가 있습니다.하지만 그건 문제가 아닙니다. 네가 제안한 수동 캐스팅을 시도했지만 효과가 있었다. 그러나 타이핑은 npm으로 배포되지 않았기 때문에 내 라이브러리의 클라이언트는 유형을 얻지 못했다. –

1

당신이 만약을 절대 경로를 사용하여 PureScript 패키지를 요구해야합니다.import * as People from 'People'), 노드 모듈 해상도 알고리즘을 해킹해야 할 필요가 있다고 생각합니다 (node_modules 서브 디렉토리에 PureScript 출력을 배치하여 예를 들어 ./output).

하지만 그건 중요하지 않다 당신이 상대의 수입으로 괜찮아요 경우 (같은 import * as People from './People'는) 다음과 같은 수행 할 수 있습니다 PureScript 모듈

  1. 사용 상대적으로 수입 :

    CLI를 /main.ts : 당신의 유형과 나란히

    import * as People from './People'; 
    
  2. 놓습니다 PureScript 유형 측 스크립트 소스 :

    export interface Person { 
        name: string; 
    } 
    
    export const david: Person; 
    
  3. 지금 :

    CLI/사람/index.d.ts :

    . 
    ├── People 
    │   └── index.d.ts 
    ├── main.ts 
    └── tsconfig.json 
    
  4. 이 PureScript 유형을 변경

    지역 대신 세계의 모듈 선언 할 수 노드 모듈 해상도로 작동하게하려면 두 컴파일러의 JS 출력을 같은 디렉토리에 배치해야합니다. 또한 TypeScript가 TS 파일에 대한 유형 선언을 내 보내야합니다 (npm에 게시 될 때 소모 가능). 우리는 또한 paths TS 컴파일러 옵션 (더 이상 필요하지 않음)을 제거하고 노드 유형에 대한 전역 유형 참조를 추가합니다.

    CLI/tsconfig.json :

    { 
        "compilerOptions": { 
        "target": "es5", 
        "lib": ["es2015"], 
        "moduleResolution": "node", 
        "baseUrl": ".", 
        "outDir": "./../output", 
        "types": [ 
         "node" 
        ], 
        "declaration": true 
        }, 
        "include": [ 
         "*.ts" 
        ] 
    } 
    
  5. 이 거의 완료. 이제는 PureScript 모듈의 유형 정의가 출력 디렉토리에 저장되어 소비 될 수 있도록해야합니다. TypeScript는 형식 정의 출력을 생성 할 때 출력에 .d.ts 개의 파일을 복사하지 않습니다 (TS 컴파일러에서 생성되지 않았기 때문에).이를 보완해야합니다. (? 또는 좋은) 나는이 최선인지 이것을 달성하는 방법을 알고하지 않습니다,하지만 나를 위해 일한 다음 :

    package.json :

    "scripts": { 
        "build": "pulp build && tsc -P cli/tsconfig.json && cd cli && rsync -am --include='*.d.ts' -f 'hide,! */' . ./../output" 
    }, 
    ... 
    
  6. 마지막으로

    package.json :

    "main": "output/main.js", 
    "typings": "output/main.d.ts", 
    "files": [ 
        "output/" 
    ] 
    ... 
    
  7. 012 이상, 우리는 NPM의 소비자 유형 정의 JS과의 엔트리 포인트를 지정해야

혼합 언어 및 혼합 유형 npm 패키지를 만드는 데 대한 모든 내용을 다루지는 않겠지 만,이 내용이 출발점이 될 수 있기를 바랍니다.

+0

그래, 내가 아는 한 다른 설정에서이 방법이 가능하다. 개별 유형에 맞는 유형이 있는지 확인하기 위해 필자는 Typescript codegen 라이브러리를 사용하는 것과 같은 접근 방식이 가장 좋을 것이라고 생각합니다. https://github.com/justinwoo/ps-js-ts-interop/tree/ ohyes-codegen – kakigoori

+0

아, 아마도이 '로컬 모듈'개념이 내 네임 스페이스 접근 방식보다 낫겠습니까? 하나가 다른 것에 이점이 있습니까? –

+0

@DavidSiegel 제 대답의 접근 방식을 통해 모듈과 파일 시스템을 일대일로 매핑 할 수 있습니다. 마치 TypeScript 또는 JavaScript로 작성하는 것처럼 말입니다. TypeScript에서이 모듈을 어떻게 가져올 지에 대한 올바른 매핑 wr/t도 있습니다 (올바른 경우 가져 오기는'import * as People from './People''입니다.). 네임 스페이스에 대한 접근 방식은 전역 적으로 사용할 수 있습니다 (예 : 어디서나 최상위 수준 모듈에서 가져올 수 있음). 완전히 평평하지 않은 모듈 구조 (네이밍 충돌, 네임 스페이스 오염)가있는 경우 원하는 것이 아닐 수 있습니다. – MisterMetaphor