Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
browser field spec for package.json
@jhnns

This comment has been minimized.

Copy link

@jhnns jhnns commented Feb 13, 2013

Nice! I'd love to see this spec implemented in all bundlers 😄

@wilmoore

This comment has been minimized.

Copy link

@wilmoore wilmoore commented Feb 23, 2013

Added to "Complementary Resources" section of "Front-End Package Manager Comparison":
http://git.io/_ZWfVA#complementary-resources

@kirbysayshi

This comment has been minimized.

Copy link

@kirbysayshi kirbysayshi commented Nov 13, 2013

How would a module author provide the following:

  • themod.js (authored directly, CJS style)
  • themod-amd.js (generated at publish time)

Given a package.json that had a browser field, should the module author even attempt to provide both files? Should the author specify transforms, and rely on the consumer using a tool the author specified a transform for? It would be nice if the consumer could use the same identifier in both scenarios.

@thomasfr

This comment has been minimized.

Copy link

@thomasfr thomasfr commented Nov 7, 2014

It is not completely related to this, but i want to extend the concept of client side (only) libraries npm. Imo the problem of client side dependencies with js, css, etc. is still not solved yet. There are tools for some parts of it but no common specification or configuration etc. What about other client side assets like css, less or images? At the moment thats completely missing in my opinion.

There is already the directories property in the CommonJS spec, but it is missing keys for static assets like css, less, images, etc. (http://wiki.commonjs.org/wiki/Packages/1.0#Optional_Fields and https://www.npmjs.org/doc/files/package.json.html#directories)

There are tons of great client side libraries on npm but every single one is different to use / consume in the frontend when it comes to css, less, sass, images, fonts, etc. How to include them? What files should be included? In which order? It would be great if package maintainers could clearly describe what additional assets, besides javascript are shipped with the npm package and how to consume them.

Lets take bootstrap as an example (original https://github.com/twbs/bootstrap/blob/master/package.json)
Why not?


{
  "name": "bootstrap",
  "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
  "version": "3.3.0",
  "homepage": "http://getbootstrap.com",
  "author": "Twitter, Inc.",
  "scripts": {
    "test": "grunt test"
  },
  "directories": {
    "assets": {
       "css": ["dist/css/bootstrap.min.css","dist/css/bootstrap-theme.min.css"],
       "js":["dist/js/bootstrap.min.js"]
       "font":["dist/fonts/glyphicons-halflings-regular.eot","dist/fonts/glyphicons-halflings-regular.eot","dist/fonts/glyphicons-halflings-regular.svg","dist/fonts/glyphicons-halflings-regular.ttf", "dist/fonts/glyphicons-halflings-regular.woff"]
    }
  },
  "main": "./dist/js/npm",
  "repository": {
    "type": "git",
    "url": "https://github.com/twbs/bootstrap.git"
  },
  "bugs": {
    "url": "https://github.com/twbs/bootstrap/issues"
  },
  "license": {
    "type": "MIT",
    "url": "https://github.com/twbs/bootstrap/blob/master/LICENSE"
  },

  "jspm": {
    "main": "js/bootstrap",
    "directories": {
      "example": "examples",
      "lib": "dist"
    },
    "shim": {
      "js/bootstrap": {
        "imports": "jquery",
        "exports": "$"
      }
    },
    "buildConfig": {
      "uglify": true
    }
  }
}

This could be even further extended to configure which assets are already "compiled", minified or packaged for usage or which assets are optional (bootstrap-theme.min.css).

Here are some very popular packages with js, css and/or other assets on npm without any further configuration:

Package Managers like bower, component, npm or other tools like browserify, etc. could use this information only or in addition to their separate configuration files.

What do you think?
cheers

@majgis

This comment has been minimized.

Copy link

@majgis majgis commented Dec 31, 2014

It would be great if we could expand this spec with subarg syntax:
browserify/browserify#1046

@adjavaherian

This comment has been minimized.

Copy link

@adjavaherian adjavaherian commented May 4, 2015

So this currently doesn't exist in Webpack?

@djfm

This comment has been minimized.

Copy link

@djfm djfm commented Jun 15, 2015

Nice spec.

When you write:

"browser": {
    "module-a": false,
    "./server/only.js": "./shims/server-only.js"
}

Are the relative paths in "./server/only.js": "./shims/server-only.js" relative to the location of the package.json file or to the directory of the file that calls require('./server/only.js')?

In other words, lets say root stands for the directory where the package.json is located and root/deep/file.js does require('./server/only.js'), should it resolve to:

  • root/deep/shims/server-only.js
  • or to root/shims/server-only.js?
@adjavaherian

This comment has been minimized.

Copy link

@adjavaherian adjavaherian commented Jul 23, 2015

A regex option would be cool, so you don't have to explicitly define each module of type to be false.

@zeke

This comment has been minimized.

Copy link

@zeke zeke commented Sep 8, 2015

@balupton

This comment has been minimized.

Copy link

@balupton balupton commented Sep 19, 2015

Is this added to anything besides browserify? Would be cool to see support in webpack and jspm.

@watsoncj

This comment has been minimized.

Copy link

@watsoncj watsoncj commented Sep 25, 2015

Verified this works in webpack. The property is overloaded so you sometimes have to get creative if you have a client-only entry point and want to specify a module location.

"main": "index.js",
"browser": {
  "index.js": "bytebuffer/dist/ByteBufferAB.js",
  "Long": "bytebuffer/node_modules/long/dist/Long.js"
}

The index.js mapping is equivalent to "browser": "dist/ByteBufferAB.js"

@chauthai

This comment has been minimized.

Copy link

@chauthai chauthai commented Oct 6, 2015

@balupton It's already supported in JSPM: jspm/jspm-cli#1062

@TotallyInformation

This comment has been minimized.

Copy link

@TotallyInformation TotallyInformation commented Mar 7, 2021

This use of the browser property seems to be at odds with the npm specification? It seems dangerous to me and has already caused problems with the Axios package.

https://docs.npmjs.com/cli/v7/configuring-npm/package-json#browser

@ljharb

This comment has been minimized.

Copy link

@ljharb ljharb commented Mar 7, 2021

It’s not at odds with it at all; they should be used in concert.

@TotallyInformation

This comment has been minimized.

Copy link

@TotallyInformation TotallyInformation commented Mar 21, 2021

Sorry, not quite getting that. The npm docs appear to say that the browser property should contain a single string pointing to the main entry point for when the package is consumed by a browser. But this spec is using an object with a different meaning? How can that not be at odds? Am I missing something?

Having two wildly different specs on the same property makes it very much harder to use the property for anything unless you already know how a package is going to use it. Not much help when you are trying to automate things.

@ljharb

This comment has been minimized.

Copy link

@ljharb ljharb commented Mar 22, 2021

Both are part of the browser field spec (the npm docs are not an authority on this subject). if a string, it replaces the “main”; if an object, it provides mappings to replace anything.

@TotallyInformation

This comment has been minimized.

Copy link

@TotallyInformation TotallyInformation commented Mar 24, 2021

OK, can you please point me to the authoritative definition for the package.json file? Thanks.

@ljharb

This comment has been minimized.

Copy link

@ljharb ljharb commented Mar 24, 2021

There is not one such definition, since many tools look at that file. For npm, it's https://docs.npmjs.com/cli/v7/configuring-npm/package-json/; for the "browser" field, it's https://github.com/defunctzombie/package-browser-field-spec.

@TotallyInformation

This comment has been minimized.

Copy link

@TotallyInformation TotallyInformation commented Mar 27, 2021

Hmm, an interesting viewpoint. Not one I share I'm afraid. I see that we won't agree on this subject sadly. Having two different definitions for this field is confusing and counter-productive. As far as I am aware, npm created the package.json file and defined its schema including the browser property. If more flexibility was needed for that field, it should have been (and maybe was for all I know) raised with npm. What we have now is some scripts failing because of competing specifications for the field. Adding complexity and wasting people's time while they try to work out what is wrong.

Anyway, thanks for responding.

@ljharb

This comment has been minimized.

Copy link

@ljharb ljharb commented Mar 27, 2021

You’re incorrect; npm did not create or define the browser field, they merely (partially) document it. If it’s confusing for you, I’m sure we could get npm to remove that, or link to the actual spec for it.

@TotallyInformation

This comment has been minimized.

Copy link

@TotallyInformation TotallyInformation commented Mar 27, 2021

If that is the case then it would indeed be better for the npm documentation to be updated so that it is correct.

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