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

build/distribute as UMD #616

Merged
merged 13 commits into from May 23, 2018
Merged

build/distribute as UMD #616

merged 13 commits into from May 23, 2018

Conversation

jayphelps
Copy link
Contributor

@jayphelps jayphelps commented Mar 29, 2018

I still need to adjust tests--still trying to figure out if I can change things while still keeping the existing makefile setup, is that the preference? Ready!

This was requested before #592 can be merged.

package.json Outdated
},
"files": [
"LICENSE",
"fetch.js"
"dist/whatwg-fetch.js"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's desired we could build to ./fetch.js instead of putting things inside dist (and naming it something else). I did it this way as it's more traditional in the community, but otherwise your call.

output: {
filename: 'whatwg-fetch.js',
path: path.resolve(__dirname, 'dist'),
library: 'WHATWGFetch',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't sure what to call the global object. Any preferences?

src/index.js Outdated
@@ -0,0 +1,476 @@
'use strict';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way github is displaying this isn't great (it doesn't realize the file move/rename and changes). Here is the separate commit with whitespace ignored (?w=1 flag) a5ec273?w=1#diff-1fdf421c05c1140f6d71444ea2b27638

@mislav
Copy link
Contributor

mislav commented Mar 30, 2018

Thank you for working on this! What do you think about skipping webpack dependency altogether (it might be an overkill), and wrap current fetch.js with something like this:

(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], function(){ return factory({}, root) })
    } else if (typeof module === 'object' && module.exports) {
        factory(module.exports, root)
    } else {
        factory({}, root)
    }
}(typeof self !== 'undefined' ? self : this, function(exports, global) {

    // current fetch.js contents

    if (!global.fetch) {
        global.fetch = fetch
        // ...
    }

    exports.fetch = fetch
    exports.Request = Request
    // ...
    return exports
}))

@jayphelps
Copy link
Contributor Author

@mislav based on our PM conversations I've updated the PR to have the UMD preamble inline. I also added a simple test to verify the exports are there in CJS. ✌️

@jayphelps jayphelps changed the title WIP: build/distribute as UMD build/distribute as UMD Apr 6, 2018
fetch.js Outdated
(function(root, factory) {
/* jshint strict:false */
/* globals define, module */
if (typeof define === 'function' && define.amd) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially tried to use/* jshint ignore: start */ (and end) but it didn't work in 2.8.0 jshint (maybe jshint/jshint#2411). After upgrading to jshint 2.9.0 it works, but then it says factory is unused, and everything I tried to ignore that caused even more issues, and 2.9.0 also detects other undefined variables like Promise/Symbol. So this seemed to be the solution with the least amount of changes.

mislav
mislav previously requested changes Apr 6, 2018
Copy link
Contributor

@mislav mislav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great start!

fetch.js Outdated
searchParams: 'URLSearchParams' in self,
iterable: 'Symbol' in self && 'iterator' in Symbol,
blob: 'FileReader' in self && 'Blob' in self && (function() {
searchParams: 'URLSearchParams' in global,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep the diff to a minimum, could global simply continue to be called self like before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

script/test Outdated
@@ -7,3 +7,5 @@ if [ -n "$SAUCE_BROWSER" ]; then
else
./script/phantomjs
fi

./node_modules/mocha/bin/mocha test/cjs.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this separate file needed?

These tests could be in test.js. That file already jumps through hoops to exercise both native and polyfilled fetch, and this module approach could potentially clean it up.

Copy link
Contributor Author

@jayphelps jayphelps Apr 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A separate file was used as it is testing whether the CJS exports are available and the easiest and foolproof way seemed to be to do it inside a real CJS environment. test.js is evaluated in the context of a browser, where no require exists, and I did not see any other tests running inside a CJS env. Sorry about that, am I missing an easier solution? I could make an ajax request then eval it inside a fake CJS environment stub but this seemed harder and more brittle. lmk what you had in mind.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mislav any thoughts? 🕺

Copy link
Contributor Author

@jayphelps jayphelps Apr 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mislav hey there. Anything I can do to move this forward? I'm truly sorry to be that nagging person 😞I realize OSS is mostly volunteer and super appreciate what you've done for everyone! We're approaching a company deadline for getting in dependencies and we really need abort polyfill support for fetch so it's important for us to get this in so we can then get #592 in as well. I'm happy to do any leg work, just need to know what to do 😃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump

@phil-lgr
Copy link

Hey let us know if we can help here! This is a much needed feature!

@graingert
Copy link
Contributor

fyi https://www.npmjs.com/package/fetch-ponyfill already provides a module for this

@jayphelps

This comment has been minimized.

@jayphelps jayphelps mentioned this pull request May 7, 2018
3 tasks
@stefanpenner
Copy link

@mislav anything I can do to help get this, or something similar landed? I would hate to have rely on a fork long-term.

Prior to this change, `test.js` had to be loaded before `fetch.js` so it
can nulify the native implementation of `window.fetch` to force testing
of the polyfill. Now that we have exports from the UMD file, we can
abandon this hack and simply access the exports to juggle between native
and polyfilled versions of the implementation.
@mislav mislav dismissed their stale review May 17, 2018 14:28

Outdated

@mislav
Copy link
Contributor

mislav commented May 17, 2018

Hi @jayphelps, I've just pushed my proposed changes to this branch. Thank you for waiting.

Everything was OK with the state of the PR as you've left it. The static UMD wrapper looked good. However, on our side, some new requirements to how we package our open source libraries have crept in. Specifically, we want our packages to support a module keyword in addition to the main keyword in package.json. The module file would be an entrypoint that is an ES5 file with ES6 export syntax. This is compatible with build tools such as Rollup.

I have made a call to have fetch.js be a plain, unwrapped implementation of the polyfill with ES6 exports, therefore suitable to be pointed to by module. This would mean, however, that it would be best to have a build step that converts that into a UMD file, like you've first proposed in the initial version of this PR. Instead of Webpack, I use Rollup here because its what we use in our other open source projects (sometimes we use Babel to generate the UMD file if the project already uses Babel).

Because jshint was giving me trouble through this transition, I've switched to eslint & prettier like we also do in our other open source projects. This resulted in a lot of apparent code changes that are mostly just prettier adjusting whitespace. This makes the diff of this PR look huge, but I think the transition is worth it in the long run. The diff is best viewable while ignoring whitespace changes.

I would appreciate a review. Thank you! 🙏

@stefanpenner
Copy link

I've switched to eslint & prettier like we also

Good call!

Copy link

@koddsson koddsson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me :)

@jayphelps
Copy link
Contributor Author

LGTM :shipit:

@jayphelps
Copy link
Contributor Author

A somewhat related offshoot concern I still have is that the current proposed abort support in #592 won't polyfill window.fetch if window.fetch is already assigned but doesn't itself support aborting. My gut says that would be non-obvious to people and potentially cause an issue where aborting works as expected in one browser but doesn't in another. With this PR adding modules, is there potential to reconsider #592's behavior or alternatively provide a way to opt-in to it always polyfilling if something isn't 100% supported? e.g. it would override window.fetch if any only if it doesn't support abort signals. If that as the default behavior isn't acceptable, perhaps an opt-in module? import 'whatwg-fetch/polyfill-with-abort';

The approach we took in yetch was that the default import/export of the project didn't polyfill anything so it could be used as a library without side effects. If they wanted to instead polyfill you use import import 'yetch/polyfill';. My intent isn't to advertise yetch, just using it as a reference.

@graingert
Copy link
Contributor

graingert commented May 22, 2018 via email

@keithamus
Copy link

@jayphelps I do not disagree - but I think this is a good first step. Let's wait for this patch to land and then look into those subsequent issues.

@mislav
Copy link
Contributor

mislav commented May 23, 2018

The approach we took in yetch was that the default import/export of the project didn't polyfill anything so it could be used as a library without side effects.

There's definitely value in the ponyfill approach, especially in the world where using modules is becoming more and more standard. However, you have to consider the existing whatwg-fetch user base which is very wide and far-reaching in terms of history. We've advertised this as a polyfill from the start and I would guess with relative confidence that a large slice of our user base is simply including fetch.js in their project and using window.fetch after that.

I'm not ready to pull the plug on this behavior and make the polyfill an opt-in just yet, even through a major version bump, especially because this library didn't provide exports in the past. So, my plan is to first provide the exports (while keeping the implicit polyfill functionality), have our users get used to that, and possibly switch to the ponyfill approach months down the line through another major version bump.

Thanks for your input!

@mislav mislav merged commit f83e371 into JakeChampion:master May 23, 2018
xg-wang added a commit to xg-wang/pretender that referenced this pull request May 24, 2018
Github/fetch has merged PR for UMD distribution:
JakeChampion/fetch#616

Also abort support has been added:
JakeChampion/fetch#592

We can use Github fetch instead of yetch now.
But AbortableFetch is still not supported, see comment
in test.
MattiasBuelens added a commit to MattiasBuelens/yetch that referenced this pull request Jul 5, 2018
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants