quicktype/PACKAGES.md

4.0 KiB

The packages

  • quicktype-core: This is the engine of quicktype. It takes JSON, JSON Schema, and GraphQL input and produces output in a variety of programming languages. We're trying to keep this lean in terms of download size so that it can be embedded, such as in quicktype-playground.

  • quicktype-typescript-input: This is a bit of code that allows TypeScript code to be fed as input to quicktype-core, by transforming it to JSON Schema with typescript-json-schema. It depends on quicktype-core.

  • quicktype-graphql-input: This is the GraphQL input module. It's split off into a separate package because it's not used in the web UI and quicktype-playgrounds, and it uses the moderately sized graphql dependency.

  • quicktype: This is the command line interface for quicktype. It's a monolithic package that doesn't depend on the other packages, but contains all their code directly. This is mainly for ease of development. Packages that want to use quicktype's CLI interface, such as json-to-azure-node-schema will have to use this package.

Module resolution

quicktype-typescript-input and quicktype-graphql-input have to work both as their own packages, depending on the quicktype-core package, as well as part of quicktype, referring to the files in the local src/quicktype-core directory.

In addition, since those two input packages depend on quicktype-core, we would have to first build quicktype-core, publish it, and then build the input packages, depending on the just published quicktype-core. This is bad for development, since we couldn't do modifications to all packages without publishing, if we want to test independent of the quicktype package. The same goes for CI. Therefore, the two have to build as packages depending on the local build/quicktype-core package, but have to be published depending on the proper quicktype-core NPM package. We solve this the following way:

  • All packages, including quicktype-typescript-input and quicktype-graphql-input, import files with local paths, such as "../quicktype-core". This seems the only way to make VSCode's TypeScript integration, as well as ts-node happy. Unfortunately, since local paths can's use tsc's path mapping, we have to rewrite those paths before compiling, which is done in build/quicktype-*-input/build.ts: it copies all the sources, rewrites them, compiles, and then deletes the copied sources again.

  • Depending on whether we build the input packages, or publish them, their package.jsons will have to refer to either the local quicktype-core package, or the NPM one. This is also done by the build script, which replaces the dependency with the right one for the job.

Issues

Module resolution in Node is such that if a package is not found in the local node_modules directory, it goes up the directory hierarchy and tries every node_modules directory it finds. We have a node_modules in the root directory of our repo, so a subpackage build will fall back to that if it can't find a package locally. The main consequence of that seems to be that the build won't catch missing dependencies in those packages if they're present in the root package. Moving the root package.json to build/quicktype screws with lots of tooling.

Building

The root quicktype package does everything from its package.json.

The other packages each have a build.js in their build/PACKAGE directory. It is required to build the root package before building the others, because it will install the semver package which the build script for the other packages depend on. It's also required to build quicktype-core before building the ones that depend on it. This is how to build everything:

npm install
( cd build/quicktype-core ; node build.js )
( cd build/quicktype-typescript-input ; node build.js )
( cd build/quicktype-graphql-input ; node build.js )