Skip to content
This repository was archived by the owner on Nov 13, 2023. It is now read-only.

Create, Export and Publish typed (or untyped) libraries. #95

Closed
cristianoc opened this issue Nov 11, 2018 · 21 comments
Closed

Create, Export and Publish typed (or untyped) libraries. #95

cristianoc opened this issue Nov 11, 2018 · 21 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@cristianoc
Copy link
Collaborator

Investigate how to make genType artifacts available as part of a library.

First, find a good solution for TypeScript libraries, and separately Flow typed libraries.
Then, think about libraries that can be consumed from both TS and Flow (and vanilla).

This is an area of some complexity (and fragmented information), so the first step is to understand the landscape enough to come up with an initial design.

It seems that publishing typed libraries today seems quite complex, and this could be an opportunity to think about how to make this simple, at least as an initial goal.

Also, publishing libraries consumable by both TS and Flow makes it more difficult, because the shapes of the solutions are different, and there's the question of what is the source of truth. Each one has features that are not available in the other.

@cristianoc
Copy link
Collaborator Author

@cristianoc
Copy link
Collaborator Author

@cristianoc
Copy link
Collaborator Author

@nikgraf
Copy link
Collaborator

nikgraf commented Nov 11, 2018

From my understanding for libraries the best case is if untyped JavaScript is generated in combination the type definition files for the whole library (both for Flow and TypeScript). This would mean the same untyped JS code would need to be generated, which you mentioned is not the case.

I'm not sure if it's better to keep the definitions in the published npm package or if they better should be contributed to https://github.com/DefinitelyTyped/DefinitelyTyped and https://github.com/flow-typed/flow-typed

@nhducit
Copy link
Contributor

nhducit commented Nov 12, 2018

in my experience,
if a package is written in vanilla JS then authors often don't want/have the experience to maintain type definition, then the community create type bindings and submit them to DefinitelyTyped/DefinitelyTyped and flow-typed/flow-typed. for example react-router
if a package is written in typescript then type binding often placed in the same repo. for example formik

@nikgraf
Copy link
Collaborator

nikgraf commented Nov 14, 2018

Sounds way easier to maintain to publish the types with the npm package.

@nhducit
Copy link
Contributor

nhducit commented Nov 15, 2018

for genType, if people write a lib in Reason and integrate them in flow/typescript project. Then keep the definitions and published in same npm package is much easier

@rrdelaney
Copy link
Collaborator

I think that BuckleScript needs to separate it’s stdlib out into a separate npm package before this will be useful to a wider audience. It’s currently very difficult to distribute a Reason library on npm for JS consumers written in Reason because bs-platform is a hard dependency.

@cristianoc
Copy link
Collaborator Author

cristianoc commented Nov 15, 2018

@rrdelaney taking one of the BuckleScript libraries and try to publish it on npm as a typed library would indeed be an excellent first step.
ReasonReact would also be a great candidate later on.

@jchavarri
Copy link
Contributor

Fwiw, I started some time ago an attempt to make bs-platform dependency more modular: rescript-lang/rescript#2171

It was for different purposes (alleviate the dependencies size and complexity on serverless environments) but I got blocked at some point.

If I were to attempt that effort today, I would probably extricate first two separate packages: bs-core (with "everything but Belt" in it) and bs-belt (with just Belt), and then see how they can be retro-fed into Bucklescript.

@cristianoc
Copy link
Collaborator Author

This worked for me with Flow:

  1. Create directly a component exported to JS:
/* src/MyLittleLib.re */
let component = ReasonReact.statelessComponent(__MODULE__);

[@genType]
let make = (~name, _children) => {
  ...component,
  render: _ => <div> name->ReasonReact.string </div>,
};
  1. Import the component from JS:
const MyLittleLib = require("./../MyLittleLib.gen").default;
  1. Create node_modules/my-little-lib and add a bsconfig.json file to it
// node_modules/my-little-lib/bsconfig.json
{
  "name" : "my-little-lib",
  "bsc-flags": ["-bs-super-errors"],
  "reason": { "react-jsx": 2 },
  "bs-dependencies": ["reason-react"],
  "sources": [
    {
      "dir": "src",
      "subdirs": true
    }
  ],
  "package-specs": {
    "module": "es6",
    "in-source": true
  },
  "suffix": ".bs.js",
  "refmt": 3,

  "gentypeconfig": {
    "language": "flow",
  }
}
  1. move MyLittleLib.re from 1) to node_modules/my-little-lib/src

  2. change the import from 1) to:

const MyLittleLib = require("my-little-lib/src/MyLittleLib.gen").default;

@cristianoc
Copy link
Collaborator Author

I tried the same process with TypeScript starting from the sample project typescript-react-example, but I'm getting a runtime error:

InvalidCharacterError: Failed to execute 'createElement' on 'Document': The tag name provided ('/static/media/MyLittleLib.gen.3082084e.tsx') is not a valid name.

Somehow, this import

import MyLittleLib from "my-little-lib/src/MyLittleLib.gen";

produces a string with a path instead of importing the component

MyLittleLib /static/media/MyLittleLib.gen.3082084e.tsx

@aaronshaf
Copy link

Would be great to have the separate TypeScript declaration files!

@cristianoc
Copy link
Collaborator Author

@aaronshaf I hear requests for separate TypeScript declaration files, and I hear requests for removing separate Reason interface files. Wondering whether these requests come from different people, or whether the situations are different enough to make interfaces desirable in TypeScript and undesirable in Reason.

@cem2ran
Copy link

cem2ran commented Apr 17, 2019

@cristianoc perhaps the above project wonka written in Reason could serve as a test case for improving the usability of libraries created in Reason and exported for consumption in flow/typescript codebases.

@petegleeson
Copy link

Just adding some more information from the JS side. I created this example which shows a JS library that publishes both Flow and Typescript definitions. See the my-lib package in node_modules and look in src for consumption example. Not sure if creating Flow/TS definitions is the direction that genType wants to go but it's an idea.

@elnygren
Copy link

Hi I'd like to add some insights to the conversation here that build on #25. So basically a huge usecase for gentype is to create nicer ways for JS/TS/Flow people to access code written with ReasonML.

In a JS project we need to use "language": "untyped" and we can use "propTypes": true to get propTypes.

However, in if we're writing JS with modern tooling like a new version of VSCode, our tools can actually use TypeScript's .d.ts files even if we don't have tsconfig.json in the project at all.

It would be very useful if gentype would have something like "language": "untyped+ts" that would generate MyComponent.gen.js and MyComponent.gen.d.ts -- this way people writing vanilla JS can access ReasonML code with some typesafety provided by the editor (VSCode, in this case).

@oliversturm
Copy link

I read all related issues without understanding that the scenario described by @elnygren is not commonly considered.

However, in if we're writing JS with modern tooling like a new version of VSCode, our tools can actually use TypeScript's .d.ts files even if we don't have tsconfig.json in the project at all.

This is the most relevant point to me, and the main reason I've been looking into type definition files created for Reason code.

@cristianoc
Copy link
Collaborator Author

Relevant to publishing, or rather to consuming already-published libraries: #301.

@cristianoc
Copy link
Collaborator Author

This has an example of creating a library and use types from it: #301.

@gustavopch
Copy link

@elnygren Did you find a way to generate .d.ts files with genType?

@ryyppy ryyppy unpinned this issue Nov 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests