Live data from Hacker News

If you write JavaScript tools or libraries, bundle your code before publishing

medium.com

11–20 of 25 posts

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#11
Can someone clarify what would happen in this scenario:

- My app requires React.

- My app also requires FooBarComponent whose dist is just a giant index.js which includes its own copy of React.

- Now I get a bunch of errors because FooBarComponent and MyApp can't share anything between themselves. React really doesn't like it when two copies are running.

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#12

Can someone clarify what would happen in this scenario: - My app requires React. - My app also requires FooBarComponent whose dist is just a giant index.js which includes its own copy of React. - Now I get a bunch of errors because FooBarComponent and MyApp can't share anything between themselves. React really doesn't like it when two copies are running.

FooBarComponent shouldn't have been packaged that way (it can include such a dist file for some people to use, but the npm package shouldn't export that). The typical way is for it to not include React as a `dependency` at all but a `peerDependency`. Then everything will be importing the same instance.

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#13
post #12

Can someone clarify what would happen in this scenario: - My app requires React. - My app also requires FooBarComponent whose dist is just a giant index.js which includes its own copy of React. - Now I get a bunch of errors because FooBarComponent and MyApp can't share anything between themselves. React really doesn't like it when two copies are running.

FooBarComponent shouldn't have been packaged that way (it can include such a dist file for some people to use, but the npm package shouldn't export that). The typical way is for it to not include React as a `dependency` at all but a `peerDependency`. Then everything will be importing the same instance.

> (it can include such a dist file for some people to use, but the npm package shouldn't export that)

I think that is exactly what the article is suggesting we do.

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#14
Ugh, no. Bundling should be done at the very end, when you're trying to build maintainable software. It's a mistake to bundle in the middle, because then even loosely-dependent modules will be limited to updating only when every intermediate dependency updates. Don't take these decisions out of the hands of the coders who are actually coding software.

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#15
This is a terrible advice - please don't do it.

Say, your app depends on libraries foo & bar, and both of them depend on baz. Say, foo is bundled with baz v.1.1 and bar is bundled with baz v.1.2. If you used package manager you'd get baz v.1.2 and everything would work fine because baz 1.2 is API compatible with 1.1.

However, it does not mean you can use them interchangeably! If you pass an object created in baz 1.2 to baz 1.1 things might break because internal implementations of the two are different. Even having two instances of the same exact library may not work - e.g. if that library keeps some sort of internal cache.

NPM must be fixed so that packages that we depend on can't just be unpublished. Bundling everything together is not the right solution.

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#16
No, de-duplication and conflict resolution is much harder if dependencies are in a bundle. There are many better solutions to this problem:

* Fix NPM and make it immutable. If there's a legal problem allow a package to be flagged with a warning and redirected to its new name.

* Use bundleDependencies in npm

* and maybe even back-up your entire code directory

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#17
post #15

This is a terrible advice - please don't do it. Say, your app depends on libraries foo & bar , and both of them depend on baz . Say, foo is bundled with baz v.1.1 and bar is bundled with baz v.1.2 . If you used package manager you'd get baz v.1.2 and everything would work fine because baz 1.2 is API compatible with 1.1. However, it does not mean you can use them interchangeably! If you pass an object created in baz 1…

> If you pass an object created in baz 1.2 to baz 1.1

How could that ever happen? Foo and bar are separate deps. How do they pass something between each other? You can't pass something between the two baz versions because they are implementation details inside two different respective modules, foo and bar. The only way I can see is: bar passes you a baz 1.2 object, you pass it to foo, and foo passes that to baz... But if that could cause a bug, the whole setup is just wrong if there's any kind of contract saying that what you're passing is a baz object. If that's the case, baz needs to be a top level dep of your code, and foo and bar might just mention it as a peer dep. And I'm sure the OP wouldn't argue for bundling peer deps.

Maybe we need a real example :)

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#18
post #15

This is a terrible advice - please don't do it. Say, your app depends on libraries foo & bar , and both of them depend on baz . Say, foo is bundled with baz v.1.1 and bar is bundled with baz v.1.2 . If you used package manager you'd get baz v.1.2 and everything would work fine because baz 1.2 is API compatible with 1.1. However, it does not mean you can use them interchangeably! If you pass an object created in baz 1…

> If you pass an object created in baz 1.2 to baz 1.1 How could that ever happen? Foo and bar are separate deps. How do they pass something between each other? You can't pass something between the two baz versions because they are implementation details inside two different respective modules, foo and bar. The only way I can see is: bar passes you a baz 1.2 object, you pass it to foo, and foo passes that to baz... Bu…

If I depend on Frobnicator 1.2 and Frobnicator-utils x.y, and that version of the utils depends on and bundles Frobnicator 1.0, then Frobnicator objects created with the utils lib may not be compatable with Frobnicator 1.2.

Moreover, if the lib has internal state, then even if its the same version it will be broken

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#19
post #18

Earlier quoted context omitted.

> If you pass an object created in baz 1.2 to baz 1.1 How could that ever happen? Foo and bar are separate deps. How do they pass something between each other? You can't pass something between the two baz versions because they are implementation details inside two different respective modules, foo and bar. The only way I can see is: bar passes you a baz 1.2 object, you pass it to foo, and foo passes that to baz... Bu…

If I depend on Frobnicator 1.2 and Frobnicator-utils x.y, and that version of the utils depends on and bundles Frobnicator 1.0, then Frobnicator objects created with the utils lib may not be compatable with Frobnicator 1.2. Moreover, if the lib has internal state, then even if its the same version it will be broken

That's a broken system regardless of whether anything is bundled or not. If module X has a dependency on module Y, this is an implementation detail of module X and should be completely encapsulated in module X. If for some reason the system needs every copy of module Y to be the same singleton object in memory, then you need to create that instance centrally and pass it around to whoever needs it, not just rely on the Node's require cache mechanism to hopefully return the same copy for two separate require calls in different places. That may be how the require cache works, but that's an implementation detail of Node and not the right way to ensure something is a singleton.

Re: If you write JavaScript tools or libraries, bundle your code before publishing

#20
post #15

This is a terrible advice - please don't do it. Say, your app depends on libraries foo & bar , and both of them depend on baz . Say, foo is bundled with baz v.1.1 and bar is bundled with baz v.1.2 . If you used package manager you'd get baz v.1.2 and everything would work fine because baz 1.2 is API compatible with 1.1. However, it does not mean you can use them interchangeably! If you pass an object created in baz 1…

Then you aren't understanding how bundling works, or NPM for that matter, and probably writing bad code.

If you have `foo` that depends on `baz 1.1` and `bar` that depends on `baz 1.2`, then the bundle will consist of `foo`, `bar`, `baz 1.1` AND `baz 1.2`. However, `foo` will not be aware of `baz 1.2`, `bar` will not be aware of `baz 1.1`. They work with their respective dependencies and all is well.

`foo` and `bar` should not even reveal implementation and should not even care of each other's implementation. What `foo` cares about is `bar`'s API, `bar` should care about is `foo`'s API, not their implementation, dependencies etc.

An analogy would be jQuery and it's dependency to Sizzle (which, coincidentally, is bundled with jQuery). Would it matter to you if jQuery 1.7 used Sizzle 1 and jQuery 1.8 used Sizzle 10? No. What matters to you is you're using jQuery, and what you see is a 0.x.x bump of jQuery, not the x.x.x bump of Sizzle.

Post reply on HN