Skip to content
This repository has been archived by the owner on Jun 11, 2020. It is now read-only.

Why --save instead of --save-dev? #81

Open
dalgard opened this issue Jul 20, 2016 · 19 comments
Open

Why --save instead of --save-dev? #81

dalgard opened this issue Jul 20, 2016 · 19 comments

Comments

@dalgard
Copy link

dalgard commented Jul 20, 2016

In instructions on how to use @types, type packages are installed with --save and not --save-dev.

Why is this?

I wouldn't expect that I need the types outside of my development environment?

There should be a note about it in the various readmes.

@RyanCavanaugh
Copy link
Member

/cc @DanielRosenwasser

@blakeembrey
Copy link

blakeembrey commented Jul 20, 2016

The short answer would be for module authors - if, as an author, you want to publish your TypeScript package to NPM and the dependencies are in the development section, no one will be able to install it and use it without having to manually install your types dev dependencies. By using dependencies, they will be installed along with the package and consumers can use your NPM package without additional configuration. The definitions should follow however you installed the module.

@DanielRosenwasser
Copy link
Member

Using --save-dev is fine when you're writing a simple application, and it won't be used as a library. The problem comes along when you might have dependencies. If you stored your type declarations in your devDependencies, your consumers would not automatically get your type declarations. They'd then have to manually add your declaration file dependencies as their devDependencies.

Given that breaking consumers is a worse problem than slightly-larger packages, we've made --save the default in our documentation.

@unional
Copy link

unional commented Jul 20, 2016

If the types are exposed as dependencies, then it should be registered as dependencies. Otherwise, devDependencies.
But agree with @DanielRosenwasser that sometimes this distinction is not easy to make, especially for JS developer, so defaulting to dependencies is the better option.

@aluanhaddad
Copy link

I've been basically taking the same road as @unional. Like I'll do
npm install --save-dev @types/tape
or
jspm install --dev npm:@types/tape 😛

@demurgos
Copy link

demurgos commented Oct 24, 2016

Hi,
I was trying to learn how to use @types so I looked trough the code of some some big projects using Typescript and none of them was using dependencies for @types:

Is this because these projects are special ? Angular is more front-end oriented and types-publisher is a standalone project (I think), but Typescript can be imported as a library and consumed by others: why aren't some of its @types normal dependencies (like node) ?

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Oct 24, 2016

@demurgos With respect to TypeScript itself, it only uses declaration files for its build tools (like gulp utilities). It doesn't actually require those tools to run, so it doesn't need the declaration files for those tools either.

Edit: For the others, like Types Publisher, it doesn't matter what it's distributed as since it's a simple executable package that isn't meant to be used as a library.

@demurgos
Copy link

demurgos commented Oct 24, 2016

Thank you. So you mean that Typescript never require any of the Node's core libraries during runtime ? (outside of their tests/build process)

Basically, I am having trouble to know if I should install environmental types like @types/node as dependencies or devDependencies ? Should I list them as devDependencies and let the user provide them or should I list them as dependencies (and deal with #173) ?

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Oct 24, 2016

My thought is dependencies since you're written as a library with dependents. For any users using Typings with TypeScript 1.8 and below, they shouldn't be affected, but as you noted, 2.0+ users may run into problems (at which point the solution is trivial - just remove node from their typings.json - but still annoying).

@ivogabe
Copy link

ivogabe commented Oct 25, 2016

Wouldn't that cause trouble when two dependencies depend on different version of @types/node? We're currently looking to use @types in gulp-typescript, and I'm afraid that this could cause issues for a lot of people, since the types of Node are polluting the global namespace. Basically there are two scenarios that could give issues: (1) a project depends on gulp-typescript (which depends on @types/node@1) and on @types/node@2, (2) a project depends on gulp-typescript (which depends on @types/node@1) and on foo, which depends on @types/node@2. NPM will install the types of node twice. Will this cause duplicate-identifier errors?

@ghost
Copy link

ghost commented Oct 25, 2016

You could use a semver such as >= 4 to indicate compatibility with future node versions.

@jkillian
Copy link

Circling back to what @ivogabe asked - will TypeScript handle conflicting types in a way that works out okay? If I have packages depending on different versions of @types/react for example, can TS only apply those types where correct (based on their location in the node_modules tree? If it's not, it would be great to have a short write-up somewhere on the best way for library authors to include @types dependencies, I've heard a lot of questions about this from around my company.

@unional
Copy link

unional commented Jan 12, 2017

I have packages depending on different versions of @types/react for example, can TS only apply those types where correct (based on their location in the node_modules tree?

Add to that the even harder part is about module augmentation. Which version of react to augment?

@blakeembrey
Copy link

@jkillian I believe global definitions can and will conflict, while external module definitions follow module resolution. This is a bit of a pain point, because there's no guarantee a module in @types is external or global and that it won't change suddenly (lodash did this and generated a ton of build errors on various projects). I feel like there are better ways to solving this, but nothing that wouldn't break now.

@unional I think that one should be fine. You can kick in and use peerDependencies if you need to augment the parent. Type dependencies should mirror the regular dependencies for this reason.

@unional
Copy link

unional commented Jan 12, 2017

For react case, yes, because likely there are no direct dependency between react and the authoring package (e.g. react-redux).

But what if there is such a dependency? i.e.:

- app
  - package-a
    - package-b@2.0
  - package-c
    - package-b@1.0
  - package-b@??

And package-a and package-c both make an augmentation to package-b.

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

No branches or pull requests