简体   繁体   中英

How to "publish" a private Typescript npm package in git?

I think this should be a standard problem but I can't find any answers...

I have two typescript projects - LibraryA and WebserverB. They are separate projects and each have their own git repository. They are also private projects - I don't want them to be available in public.

Obviously, I want to use LibraryA in WebserverB. The correct way to do it I think would be through npm, since it manages all other libraries. Luckily npm supports git URLs in dependencies, so I can point it to LibraryA's repository directly.

However that repository doesn't contain the compiled Javascript files, only the TypeScript files. How can I make this work? Or what is the correct approach in this situation?

If you don't want to install your dependency from the sources in a git repository, here are other solutions:

Solution #1 — Install the dependency from a local folder

A light solution is to install LibraryA via a git clone and to build it. Then, in WebserverB/ , you can do a npm install ../path/to/local/LibraryA :

  • npm install <folder>:

Install the package in the directory as a symlink in the current project. Its dependencies will be installed before it's linked. If <folder> sits inside the root of your project, its dependencies may be hoisted to the toplevel node_modules as they would for other types of dependencies. ( Source: NPM documentation )

Solution #2 — Install a private npm proxy registry

You can install a private npm proxy registry on your server, like Verdaccio . Then, you'll be able to publish your package with all compiled files.

Solution #3 — Pay NPM and publish a private package

You could publish a true package (also with the compiled files) in aprivate repository from a paid account.

Solution #4 — Publish as a release on your GitHub repository (not tested)

The NPM documentation indicates another option:

  • npm install <tarball url>

Fetch the tarball url, and then install it. In order to distinguish between this and other options, the argument must start with “http://” or “https://”

Then, publish a package consist to build, compress and upload it as a new release in your private Github repository. After that, it should be possible to access the tarball through an URL using a personal access token?

OK, I'll answer my own question with a summary of the other answers and some extra options.

After some thought I came to a realization. The question is - who and when runs tsc to compile the LibraryA's Typescript to Javascript? Essentially there are just a few choices:

  1. The developer of LibraryA runs it and publishes the compiled result (somewhere);
  2. LibraryA is published in source form and compilation happens when installing the package to WebserverB;
  3. LibraryA is published in source form and building WebserverB also compiles the library.

Let's look at each in detail.

1. Publish compiled result

The question then is - where is the published result stored? It has to be somewhere where NPM can access it. As such, there are only a few choices again:

  • npm registry (private, if you can afford it, public if you're OK with it). Drawback: well, you have to pay for it.
  • A tarball on some server where you can get a URL to it. Drawback: You have to get a server to host these. And take care of said server.
  • A new GIT repository. Not tarballed, because npm cannot untar from a git repository. Drawback: you now have two repositories for one project.
  • The same git repository where LibraryA lives. In essence, you not only commit your TypeScript source files, but also the compiled result. Drawback: committing compilation artifacts is just wrong . And you're publishing your sources together with the compiled results. You don't need those in WebserverB.
  • The same git repository where LibraryA lives, but in a separate, disconnected branch. Drawback: This gets confusing. How many repositories have you seen with two disconnected main branches?

Still, despite the drawbacks, they're all serviceable options.

2. Compile upon install

The main drawback here is that this immediately puts a dependency on typescript on WebserverB. And not just a development-dependency but a full runtime dependency. This may be OK, but it's getting really weird. How do you plan on deploying WebserverB? Will that too run the compilation? I don't think this is the way to go. But it's possible. See HB 's answer for details.

3. Compile together with WebserverB

Well, if you plan only on using it in typescript projects, this might be OK. I'm not sure about installing it though. You'll need to modify your tsconfig.json file to include node_modules/LibraryA in the compilation. That's weird. And will your IDE be happy about this? All in all, this doesn't feel like a good idea either. It feels like fighting/abusing the system and that rarely ends well.

In the end, I think I'll go with the "commit compiled JS" approach. Because " just wrong " isn't a good argument. And since it's a private project, the extra published sources aren't much of an issue either. In fact, maybe they'll even help to debug.

I guess you could add an install script in the library's package.json that compiles it. Then you just need to point main and types to the output files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM