Skip to content
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

Alternative for "browser" key with higher priority #1694

Open
nazar-pc opened this issue Feb 28, 2017 · 20 comments
Open

Alternative for "browser" key with higher priority #1694

nazar-pc opened this issue Feb 28, 2017 · 20 comments

Comments

@nazar-pc
Copy link

I've stumbled upon this issue in mwilliamson/mammoth.js#106

browser key is widely used for defining which file should be used in browser environment. Some tools might use this field optionally, but they also have an alternative which is tool-specific, for instance, in webpack.

Could you add support for something like browserify.browser with higher priority in addition to browser?

@nazar-pc
Copy link
Author

I'm wondering why no one responded on this yet.
Reserving generic browser key by browserify is rude and there should be a way to use it for something else.

@goto-bus-stop
Copy link
Member

i don't understand why a different field would be necessary. the way the browser field works is documented here: https://github.com/defunctzombie/package-browser-field-spec and AFAIK pretty consistently implemented by all major bundlers.

@nazar-pc
Copy link
Author

There are also projects that use browser key for different purposes and do not use any bundlers

The issue is that browser is too generic and is sometimes used for specifying what should be used in browser environment instead of main, but with browser monopolized by browserify it becomes unreliable and sometimes (when an object is specified under browser key) unusable, which leads to multiple different implementations, I'm personally resorting to jspm.main.

This is especially true since Bower is basically dead and all of the front-end development is either moving or moved already to NPM.

@ljharb
Copy link
Member

ljharb commented Feb 15, 2018

What projects use the browser field and don’t follow (at least a subset of) the linked spec?

iirc, browserify invented the browser field long before anything else in the ecosystem looked at custom package.json fields - imo that makes any tools that deviate objectively wrong. But I’m interested to hear how it’s being misused :-)

@nazar-pc
Copy link
Author

nazar-pc commented Feb 15, 2018

jQuery used browser field at some point, D3 was another notable example (seems to use file from dist directory, possibly also because of conflicts with browserify).

To be clear, I'm not suggesting to drop browser key immediatel, just add another key with higher priority that is scoped to browserify to allow both specifying a ready to use bundle for browsers and configuration for browserify.

@goto-bus-stop
Copy link
Member

goto-bus-stop commented Feb 15, 2018

jQuery used browser field at some point, D3 was another notable example (seems to use file from dist directory, possibly also because of conflicts with browserify).

I still don't understand. what sort of conflicts? I don't see how those change anything, were they using the browser key for something other than providing a CommonJS-capable entry point?

just add another key with higher priority that is scoped to browserify to allow both specifying a ready to use bundle for browsers and configuration for browserify.

A key for a ready to use bundle for browsers seems fine, but this is not what the browser key is used for in the ecosystem. Even if we wanted to change it, that ship has sailed long ago because of how widely in use the browser key is.

all of the front-end development is either moving or moved already to NPM.

Exactly why the browser key was invented :+)

@nazar-pc
Copy link
Author

Let's assume you have a project that uses module X as dependency and you use browserify to compile it. But what if you also want to add a key that specifically points to the file that is ready to use in browsers? browser is the key I found in a few projects in the past and that is very natural to use for this purpose. However, there are 2 issues here:

  • I will not be able to use browserify CLI anymore in the project itself
  • when it is used as dependency in some other project which uses X, then X will be included in the final build twice

Can you name another commonly accepted option for specifying browser bundle in package.json?

Webpack seems to acknowledge this limitation and supports additional key as there is no reason not to do this, so I'm naturally asking you to add the same thing here and let people avoid this kinds of conflicts. At the end of the day, less project-specific keys in global namespace of package.json is better.

@ljharb
Copy link
Member

ljharb commented Feb 16, 2018

Why wouldn’t you be able to use browserify in your repo? You can make the “browser” entry point be generated gitignored output, for example.

@nazar-pc
Copy link
Author

If I point browser key to bundled file then browserify will try to use it as an entry point and bundling will stop working properly, see PR linked in the very first comment.

@ljharb
Copy link
Member

ljharb commented Feb 16, 2018

ah, gotcha. Browserify is really for apps tho, not published packages. Why would you need to publish a bundle?

@nazar-pc
Copy link
Author

Sometimes libraries have dependencies that are primarily targeted at Node.js and not loadable in browser directly, yet I want to make sure users can call my library from browser and don't enforce on them any build system at all, so that then can just <script src="node_modules/lib/dist/lib.js"></script> or requirejs(['lib'], ...).

One of such libraries I'm developing is https://github.com/nazar-pc/webtorrent-dht and it has dist/webtorrent-dht.browser.js for direct usage in browser using globals or RequireJS/Alameda.

@ljharb
Copy link
Member

ljharb commented Feb 16, 2018

For users who don’t want a build system at all (those stuck in the previous half decade), your readme - not your package.json - should tell them the path to those built files.

The browser field is only for browser build systems to select alternate entry points.

@ljharb
Copy link
Member

ljharb commented Feb 16, 2018

Put another way, if there’s no build system, you’d have no need of a programmatically identifiable location for the path, since a human would be the one manually including the JS.

@nazar-pc
Copy link
Author

In my case by build system I mean process of converting files from one format to another, bundling files together, etc.

There is nothing that prevents you from configuring RequireJS in a way that will allow to just requirejs(['lib'], ...) (like reading corresponding package.json and extract browser field from there) with zero manual configuration and no manual inclusion of scripts on the page.

Enforcing someone to use a build system and configure it in particular way just for my small library is a bit rude in my opinion. User of my library should be able to use it with minimal effort regardless of build system or other aspects, the code provided with library package should "just work" in browser. If code can't "just work" - it is a bad code.

@nazar-pc
Copy link
Author

I understand that it might not be your workflow, but I don't really see how proposed change might hurt anyone in any way.

@ljharb
Copy link
Member

ljharb commented Feb 16, 2018

While i don’t agree with your premise (i think that all npm modules should assume a CJS-compatible build system at this point) j totally agree that your library should be able to offer a drop-in script if you like.

However, i think it’s on you to document that in your readme (or your own custom package.json field if you want) for those users who are still consuming libraries via script tag.

@nazar-pc
Copy link
Author

The whole reason I've started this discussion is because I don't want to create yet another custom field for other people to figure out on their own and wanted to use something generally accepted and found a few projects that used browser for this exact purpose, which makes perfect sense to me.

But turned out browserify breaks this workflow while not offering any workaround in contrast to other build systems.

@ljharb
Copy link
Member

ljharb commented Feb 16, 2018

jQuery and d3 use the browser field properly; what projects have you found that use it to mean “pre-bundled entry point that can be dropped in a script tag”?

@nazar-pc
Copy link
Author

Right now D3 doesn't use browser field at all. Not sure why, but in past they have clearly used it for specifying browser build separately from Node.js build: https://github.com/d3/d3/blob/c57952f349dff8bb8035316cedc8878bf7d8b97e/package.json#L18-L19

  "main": "build/d3.node.js",
  "browser": "build/d3.js",

I did a mini-research on common fields about ~1.5-2 years ago and wouldn't bother to do it again, but back then there were more projects like that.

I think if at this point you are still not convinced to scope browserify's stuff under browserify key (which by the way already exists) even optionally as other projects do, then I'm disappointed and have really nothing to add.

@ljharb
Copy link
Member

ljharb commented Feb 16, 2018

I don’t see any harm, other than added complexity, of adding such a key - but since all the bundlers and ecosystem tools expect this definition of the “browser” field, i don’t think it would be beneficial for authors - anyone using the browser field for the purpose you describe would end up getting bug reports from the majority of the ecosystem.

In other words, adding a “browserify” key won’t change the reality that “browser” already has a permanent meaning, and that for your use case, you’d want a custom field name regardless.

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

No branches or pull requests

3 participants