Skip to content

Npm package template #951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from

Conversation

spratmannc
Copy link

Includes a new project template named Blank Node.js NPM Package to simplify creating packages in TypeScript that are configured to easily publish to NPM.

In particular:

  • predefines entry point as index.ts, simply to follow NPM convention
  • modifies package.json:
    • main is mapped to lib/index (no file extension to support both TS and JS projects)
    • typings property is mapped to entry point for TS build/intellisense
    • files are pulled from lib folder, which will contain *.d.ts and *.js files
    • adds devdependency on typescript so tsconfig.json can be used
  • adds tsconfig.json:
    • builds to /lib folder
    • builds and includes declaration and source map files
    • sets lib\index.js as VS startup file so F5 steps into correct entry point. (source map is used for breakpoints)

After developer adds their own code, they can simply npm publish from project root to publish their package.

@msftclas
Copy link

Hi @spratmannc, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!

In order for us to evaluate and accept your PR, we ask that you sign a contribution license agreement. It's all electronic and will take just minutes. I promise there's no faxing. https://cla.microsoft.com.

TTYL, MSBOT;

@msftclas
Copy link

@spratmannc, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR.

Thanks, MSBOT;

@mjbvz
Copy link
Contributor

mjbvz commented May 24, 2016

Thanks for the contribution!

Could you help me understand the core problems you are running into and how this PR solves those problems, specifically what is missing from the Typescript console app template ? I'd prefer to fix the existing templates if possible instead of adding new ones.

@mousetraps
Copy link
Contributor

Hi @spratmannc, thanks for the contribution!

Just so we're on the same page here... would you mind enumerating the specific issues we're trying to solve with this PR? We're pretty restrictive on adding new templates, and we'd prefer to address the core issues in the experience rather than adding a new template to mitigate. Thx!

@mousetraps
Copy link
Contributor

@mjbvz yay race conditions! one second apart!

@spratmannc
Copy link
Author

@mjbvz @mousetraps Sure, I don't mind doing that at all. This PR is actually not an attempt to fix a problem with the console project, but to introduce a different usage scenario. We are establishing a private NPM registry that we will use for internal package distribution.

There are a few challenges. The package needs to be consumable from either Typescript or Javascript projects. That's solved pretty easily by including the declaration files in the package and, most importantly, specifying the entry point for the declaration file using the typings property in package.json.

Secondly, we only need to store the TypeScript files in source control. It is pretty common to output to a folder named lib to isolate your output (in fact the TypeScript npm package is set up this way).

Lastly, we needed the ability to build from the command line or from gulp, with a build script that will work across projects. So including a tsconfig.json file just makes sense. Once you introduce a tsconfig, sometimes the debugger in VS has trouble locating the entry point. Outputting source maps and setting the entry point to index.js in the output folder fixes that in a way that seems reasonable.

I'm pretty sure that combination of requirements will be the same (or very similar) for anyone building packages for distribution via NPM. That's why we thought it would be a good thing to share. The console project is excellent, but it is geared toward building a nodejs app, and we needed something geared toward building an NPM package.

Thanks for taking a look at it.

@mousetraps
Copy link
Contributor

mousetraps commented May 24, 2016

Gotcha, thanks for the detailed explanation. Followup Q - what's the difference between a Node.js app and an npm package? In my perspective, they should really be the same, and there's no reason for any project created w/ NTVS to be antithetical to npm in any way. What modifications would we need to make on the console project template in order to close that gap? And is there any reason we shouldn't make those modifications to every project type?

@spratmannc
Copy link
Author

@mousetraps I understand your question. The scenario I'm describing can be illustrated by comparing the differences between a .NET Console Application and a .NET Class Library. The former is meant to be the end product, and the latter encapsulates and exposes shared functionality that is intended to be utilized by an end product.

In .NET, the differences between the two are more concrete, as they are compiled into different types of assemblies. We don't have that physical distinction in the final output of NPM packages, but its important to model your components in a system as if the distinction existed. NTVS has excellent support for utilizing NPM packages, which expose shared libraries of functionality. Packages like backbone, knockout, angular...etc. are not intended to be end products. So we would never execute node.exe angular.js, which is exactly what you would do with a console application. Instead we import functionality from angular for use in our own products.

The project template I'm suggesting provides guidance for devs who are building the componentry that will be consumed by end products. A better name for the template could be Node.js Class Library or Node.js Shared Package.

The helpfulness of the template becomes very apparent when you build an library starting from a console application, publish it to a private NPM registry (try sinopia), and then immediately try to reference it in another project. I suspect you'll end up making the same configuration mods proposed in the template.

@spratmannc
Copy link
Author

@mousetraps I hope my description made sense. Any recommendations?

@jcansdale
Copy link
Contributor

@spratmannc I think using 'lib/index.js' is potentially a little confusing. By default Node looks for index.js at the root of a module diretory. If you put your index file in 'lib/index.js', Node won't find it if you require('mymod') but will if you require('lib/mymod').

Other packages name the file something different when they put it in a lib/ folder. For example the typescript package uses: "main": "./lib/typescript.js".

It's a subtle point and I'm just learning all this stuff myself. :)

@spratmannc
Copy link
Author

@jcansdale Interesting point. Node has no problem resolving the module reference, because it uses the entry point defined in package.json first. (see this link) ./index.js is actually a fallback when package.json is not defined.

When defining a project template, you have to pick something as the default file name for a project item, and index is the conventional entry point file name for NodeJS packages. It is also intentionally differentiated from app, which is default entry point for a NodeJS Console Application (that naming seems very appropriate, as the console application is actually an application).

That being said, nothing stops a user from changing that filename to be whatever they like, as long as they modify the package.json.

@jcansdale
Copy link
Contributor

@spratmannc After thinking about this more, I agree it makes complete sense to use index.ts. As you mentioned this is consistent with the JavaScript convention. It also seems to help the TypeScript compiler find type definitions (which is a bit hit and miss as the moment).

How about changing the following? (the trailing slash and "/index" are redundant)

(tsconfig.json) "outDir": "lib/" --> "outDir": "lib"
(package.json) "main": "lib/index" --> "main": "lib"

I'd also be inclined to include a separate app.ts startup file rather than overloading index.ts. Packages often include both library and executable content (corresponding to the package.json "main" and "bin" elements). Maybe this would address @spratmannc's reservations about including a separate template?

Does it make sense for a Node.js console app to take the form of a package? Would console apps tend to be distributed in this form?

@mjbvz
Copy link
Contributor

mjbvz commented Sep 15, 2016

Sorry we didn't have better follow up here. I'm going to close this PR since there are now conflicts that prevent us from taking it in and some open questions.

@spratmannc Please resolve the merge conflicts, answer any outstanding questions, and submit an update if you would still like to create this template. If someone else is interested and wants this template, please look into submitting some work based on this PR

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants