Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Reserved properties in package.json #4825

Closed
tonylukasavage opened this Issue · 16 comments

8 participants

Tony Lukasavage Alex Kocharin Matt Apperson Eric Elliott Tim Oxley Domenic Denicola Fokke Zandbergen Forrest L Norvell
Tony Lukasavage

Adding new, custom properties to the package.json file is a fairly common practice. In my own practice, I want to do it so as to leverage npm as a package manager for another JS-based commonjs module ecosystem, of which would have a great deal of overlap with npm (i.e., don't want to reinvent the perfectly good wheel) and utilizes the same CLI tool, but needs some slight modifications to the package.json to make it more robust for our particular needs.

When we're extending the package.json it would be good to have safe, future-proof method of defining these new properties to ensure that npm never overwrites them or uses them for its own purposes. We can make this unlikely by using uncommon prefixes on our properties, but a genuine standard for defining custom properties would be ideal. Think data- for custom HTML5 attributes.

I'm opening this up for discussion to see if others find this worthwhile, and to see if others have their own ideas for a simple, extensible solution. The 2 that jump to mind are:

a "custom" property

This would personally be my preferred solution. Everything under the custom property would be considered reserved. It would never be used by npm for its own purposes and refers specifically to properties with which only the current module will use.

{
  "name": "someModule",
  "version": "1.0.0",
  "custom": {
    "foo": [1, 2, 3],
    "bar": {
      "quux": "yo"
    }
  }
}

The actual name of this property could be anything that was deemed descriptive of reserved section of custom properties, so I'm certainly not married to custom. I initially thought it would be nice to use the name of the module as the custom property name, but this has a much larger chance of eventually conflicting with some property in npm (i.e., a module name "bugs" or any other npm property).

a "custom-*" prefix

This is really just to throw out another alternative to see what people think, as I much prefer the first option. The only way I could think of this being preferable would be that fact that you could possibly nest it within non-custom attributes, like say for example engines.

{
  "name": "someModule",
  "version": "1.0.0",
  "custom-foo": [1, 2, 3],
  "custom-bar": {
    "quux": "yo"
  },
  "engines": {
    "node": ">=0.10",
    "custom-someOtherEngine": "0.3.0"
  }
}

Curious to see if others find this worthwhile, and if the proposed implementation seems reasonable.

Matt Apperson

What about something like this:

{
  "name": "someModule",
  "version": "1.0.0",
  "engineProperties": {
    "Alloy": {
        "type": "widget",
        "platforms": ["iOS", "MobileWeb"]
    }
  },
  "engines": {
    "node": ">=0.10",
    "Alloy": "0.3.0"
  }
}

In this example, each engine can have custom properties needed to use the module.

So to be clear, engineProperties is the new property with a dictionary of optional properties for each engine.
The perk of using it like this is that each engine would be able to use whatever properties they see fit without ever stepping on each others toes...

  • prevents any chance on conflict with other systems needing to use a property
  • allows for any property name to be used
  • no prefix (just not a fan myself...)
  • NPM will never need to worry about what the community might have done with custom properties
  • Allows for config options for libs based on usage (Node might need one config option, and Titanium another for example)
Tony Lukasavage

@mattapperson at that point, why not just put the properties as part of the engine definition, instead of just the version? In lieu of an officially supported reserved property, I might do just this.

{
  "name": "someModule",
  "version": "1.0.0",
  "engines": {
    "node": ">=0.10",
    "Alloy": {
      "version": "0.3.0",
      "type": "widget",
      "platforms": ["iOS", "MobileWeb"]
    }
  }
}

Also, @rlidwka, I don't think semantically overlay would accomplish the task of future-proofing a reserved property name. It could change the property as you needed, but that doesn't ensure that npm wouldn't use it for its own purposes, potentially with an entirely different purpose than you expected. Or am I missing something?

Matt Apperson

@tonylukasavage I like that better but that is/could be a breaking change for existing modules

That was my orig idea but assumed it would be rejected

Tony Lukasavage

@mattapperson yeah, true, definitely not worth that much of a headache, especially when most of this can be resolved with just a reserved property name.

Matt Apperson

@tonylukasavage my thought of linking it to the engine was that it would be like your custom except that it would alloy for more then one use case. but perhaps both use-cases are needed?

Alex Kocharin

Why do you even need that? Just get something like xpkg and compile all your config files out of it, since all package managers seem to use their own files anyway.

Eric Elliott

A bunch of front-end people seem to think they need custom properties to help with discovery of things like CSS and templates. I believe that's the primary justification for the Bower fragmentation.

Tim Oxley
Collaborator

The convention seems to be to simply nest non-obvious custom properties under a "your module name" key.

e.g.

"browserify": { "transform": [ "brfs" ] }

I'm not sure what the problem is with this practice unless your module is called "name", "version", "devDependencies", etc.

Tony Lukasavage

@timoxley the convention is understood, and what I use in lieu of an official reserved space, but it is also not certain that the current list of properties used by npm will not change. Making this assumption on a module-by-module basis doesn't seem that dangerous, but when trying to establish a convention that a large ecosystem of developers can use to distribute apps through npm, the fact that it probably won't be an issue just rings in my head as "shit, what happens if this changes/conflicts in the future...". It would seriously help assuage my fears if there was a sanctioned reserved space for this.

Domenic Denicola
Collaborator

I will personally guarantee you that npm will never have any official properties starting with any of the following. You can use these to avoid conflicts:

  • _____
  • $$$$$
  • $_$_$_$
  • asdf
Eric Elliott
  • omgwtf
  • qwerty
  • thisismynamespacestayaway
Fokke Zandbergen

@rlidwka having tools making it easier to maintain different meta-files is not dimissing you from trying to limit the amount of duplicate work people need to do to have their package support different pm's.

Fokke Zandbergen

@tonylukasavage @mattapperson of course both/all of your solutions only solve the problem of conflicting with future NPM properties, not with conflicting engine names. So IMHO, it might just not make that big of difference.

Domenic Denicola
Collaborator

My personal guarantee from 2 months ago still stands. Closing.

Domenic Denicola domenic closed this
Scott Ganyo theganyo referenced this issue in reverb/swagger-spec
Closed

Add vendor extensions #41

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.