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

Publishing module for both Node.js and browser #946

Closed
torkelrogstad opened this issue Dec 15, 2020 · 2 comments
Closed

Publishing module for both Node.js and browser #946

torkelrogstad opened this issue Dec 15, 2020 · 2 comments
Labels
kind: support Asking for support with something or a specific use case solution: duplicate This issue or pull request already exists topic: multi-entry Related to multi-entry support

Comments

@torkelrogstad
Copy link

torkelrogstad commented Dec 15, 2020

This question might be a bit misguided so please bear with me - I have never written a JS/TS module for other people to consume.


I'm trying to publish a library that will be consumed both in a Node.js context as well as browser context. I can't seem to figure out how to do that with Tsdx. Specifically, I'm trying to write a helper library that provides a nice integration with Storybook stories (browser context) and Jest (Node.js context).

It seems like all files are compiled into one big name-of-my-package.cjs.dev/prod.min.js file. This does not work for me, as that file contains an import of a library which in turn uses Node.js functionality. This then causes my browser code to crash.

I guess what I want to do here is to publish two versions of my library: one which exposes the browser methods, and one that exposes the Node.js methods. I want both to be part of the same package. Is this a very strange way of doing things?

Any help here is much appreciated.

@agilgur5 agilgur5 added kind: support Asking for support with something or a specific use case solution: duplicate This issue or pull request already exists topic: multi-entry Related to multi-entry support labels Dec 19, 2020
@agilgur5
Copy link
Collaborator

agilgur5 commented Dec 19, 2020

This is less a TSDX question and more a general library question.

There are two ways to go about doing this. One is to create two separate entrypoints, e.g. my-package/browser vs. my-package/node (or however you might want to organize those). You could also then use the browser package.json field to specify the browser entry. That would make this a duplicate of #751 which is effectively duplicating #175 and #367.
A simplified example (that does not use TSDX) can be found in one of my libraries physijs-webpack which has separate entries for Browserify vs. Webpack (I've also been looking to add a Node version too, but lack of workers in Node made that difficult; now worker_threads exists, but it works a bit differently).

The other way of going about this is environment or feature detection. Basically you conditionally use certain functionality if you're in Node.js vs. in a browser by e.g. checking if window exists or not. That would make your code isomorphic/"universal".
You can see an example of this in one of my libraries: agilgur5/mst-persist#15

There are other techniques as well, for instance one can compile the same bundle a bit differently and replace variables (like IS_BROWSER) with rollup-plugin-replace or one can stub Node functionality, etc. For Jest one could also check for the test environment.

@torkelrogstad
Copy link
Author

Thank you so much for a very detailed answer. Also, thank you for working on an excellent tool

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: support Asking for support with something or a specific use case solution: duplicate This issue or pull request already exists topic: multi-entry Related to multi-entry support
Projects
None yet
Development

No branches or pull requests

2 participants