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

util: expose the WHATWG Encoding API globally #20662

Conversation

MarkTiedemann
Copy link
Contributor

This PR makes util.TextEncoder and util.TextDecoder available on the global object.

Currently, this is work-in-progress, but I am looking for feedback.

See: #20365

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

This commit makes `util.TextEncoder` and `util.TextDecoder` available
on the global object.
configurable: true,
enumerable: false
}
);
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs a new line at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mscdex mscdex added the wip Issues and PRs that are still a work in progress. label May 10, 2018
@AyushG3112
Copy link
Contributor

Personally, I don't like the idea of polluting globals. That aside, in this case, I have a particular concern: the names are too ambiguous and potentially confusing to users. TextEncoder does not, in any way signify what it encodes the text to(base64, hex, etc).

I would prefer defining 2 classes on the URL class, and having them being available globally as URL.TextEncoder and URL.TextDecoder.

@devsnek
Copy link
Member

devsnek commented May 10, 2018

@AyushG3112 the names and global-ness are part of whatwg spec: https://encoding.spec.whatwg.org

Copy link
Member

@devsnek devsnek left a comment

Choose a reason for hiding this comment

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

code looks good, the docs for them should probably be moved to a separate file though. you might also want to consider moving the whole implementation to a separate file, although I don't know how complex that will make it.

@AyushG3112
Copy link
Contributor

@devsnek I see, thanks for the link!

@vsemozhetbyt vsemozhetbyt added the i18n-api Issues and PRs related to the i18n implementation. label May 10, 2018
@vsemozhetbyt
Copy link
Contributor

Thank you. doc/api/intl.md also needs updating as well as all posible cross-links inside our docs.

@vsemozhetbyt
Copy link
Contributor

  1. Is adding globals semver-major?
  2. Are these classes no more available as the util properties? If so, this is semver-major despite adding globals policy, right?

doc/api/util.md Outdated
<!-- YAML
added: v8.3.0
changes:
- version: v11.0.0
pr-url: https://github.com/nodejs/node/pull/TO_DO
Copy link
Contributor

Choose a reason for hiding this comment

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

these need updated

doc/api/util.md Outdated
<!-- YAML
added: v8.3.0
changes:
- version: v11.0.0
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure this should be specified here, I think we use a placeholder that gets filled in later?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, please use REPLACEME here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same for the other v11.0.0 uses in this file and globals.md.

@@ -771,9 +771,13 @@ added: v8.0.0
* {symbol} that can be used to declare custom promisified variants of functions,
see [Custom promisified functions][].

## Class: util.TextDecoder
## Class: TextDecoder
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is confusing if util.TextDecoder is still accessible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mscdex I did this for consistency since, in the url docs, the class heading is URL instead of url.URL: https://nodejs.org/dist/latest-v10.x/docs/api/url.html#url_class_url

But I agree with you that this is confusing. In the case of URL, it fits the url docs. In the case of TextDecoder, it doesn't intrinsically fit the util docs.

So I'm gonna change this here, and also follow your suggestion of moving the TextDecoder and TextEncoder docs from util to globals (see: #20662 (comment)).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mscdex Actually, I'm not quite sure about this. All the globals in globals.md link to other docs, so globals is, in effect, some kind of meta documentation. If I'd move the encoding docs to globals, 90% of the globals documentation would be about encoding, which might be confusing, too. So I don't think is a clear-cut issue.

In fact, I think there are 3 possibilities here:

[1.] Keep the encoding documentation in util and link to it from globals.

  • pro: Keeps the old documentation structure so people that know the docs already won't be surprised.
  • con: When searching for "encoding", "text encoding" or similar terms, people are less likely to find the documentation (since the words "globals" and "utilities" are not semantically related to "encoding").

[2.] Move the encoding documentation to globals and link to it from util.

  • con: The globals docs are currently "meta documentation" in that they only link to other, more detailed documentation. Moving the encoding documentation into this section would break with that.
  • con: As explained in [1.], when searching for "encoding", less experienced people might not look in the "globals" documentation, making it less likely for them to find the correct documentation.
  • con (maybe): This could possibly make navigating the globals docs harder in the future, for example, if new globals are introduced that would occur below the lengthy encoding documentation.

[3.] Move the encoding documentation to a new documentation section, e.g. encoding / "Encoding" or text-encoding / "Text Encoding", and link to it from util and globals.

  • pro: This would perhaps make finding the correct documentation easier for less experienced people.
  • con (maybe): Documentation-table-of-contents-bloat (if such a thing exists). 😄

In any case, I'm not sure what's a good way to proceed with this. So I'd greatly appreciate more feedback regarding this issue.

PS: When I go to https://nodejs.org/dist/latest-v10.x/docs/api/, I sorely miss a tiny search-box in the top-right corner - I think that would help a lot.

Copy link
Contributor

Choose a reason for hiding this comment

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

For overall doc search, you can use "View on single page" variant, there is a link at the top of each doc.

Copy link
Contributor Author

@MarkTiedemann MarkTiedemann May 13, 2018

Choose a reason for hiding this comment

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

@vsemozhetbyt True, but I don't think that's a friendly UX/DX. (Especially on mobile, loading the whole documentation on a single page might not be the best option. But then again, I think this is off-topic here.)


<!-- type=global -->

The WHATWG `TextEncoder` class. See the [`TextEncoder`][] section.
Copy link
Contributor

Choose a reason for hiding this comment

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

If what we're doing is migrating from util to a global, I think it'd be better to have the reverse: document here and have util.TextEncoder link to the definition here.

@addaleax addaleax added the semver-minor PRs that contain new features and should be released in the next minor version. label May 11, 2018
Copy link
Contributor

@cjihrig cjihrig left a comment

Choose a reason for hiding this comment

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

LGTM once all of the comments are addressed.

doc/api/util.md Outdated
<!-- YAML
added: v8.3.0
changes:
- version: v11.0.0
Copy link
Contributor

Choose a reason for hiding this comment

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

Same for the other v11.0.0 uses in this file and globals.md.

@Trott
Copy link
Member

Trott commented May 12, 2018

Is adding globals semver-major?

@vsemozhetbyt I think it is. In my experience, new globals cause failures in some test suites (particularly the one associated with hapijs...not sure if it's code or lab that breaks but one of them, and not sure it actually breaks anymore when a global is added, but it sure used to).

Maybe the thing to do is run CITGM and see if anything breaks.

I'm going to label this semver-major based on the onboarding addendum which says:

if a change has the remote chance of breaking something, go for semver-major

@Trott Trott added semver-major PRs that contain breaking changes and should be released in the next major version. and removed semver-minor PRs that contain new features and should be released in the next minor version. labels May 12, 2018
@Trott
Copy link
Member

Trott commented May 12, 2018

@nodejs/tsc Take note. This adds to the global object.

@cjihrig
Copy link
Contributor

cjihrig commented May 12, 2018

not sure if it's code or lab that breaks but one of them, and not sure it actually breaks anymore when a global is added

It's lab. lab detects leaked global variables by checking a list of known globals. So, when Node adds a new global, it also requires an update to lab.

@Trott Trott added the notable-change PRs with changes that should be highlighted in changelogs. label May 12, 2018
@Trott
Copy link
Member

Trott commented May 12, 2018

It's lab. lab detects leaked global variables by checking a list of known globals. So, when Node adds a new global, it also requires an update to lab.

Given that once this changes lands, it will break a whole lot of test suites until the owners update, I think it's definitely semver-major. I'm also adding a notable change label.

@jasnell
Copy link
Member

jasnell commented May 12, 2018

Adding a new global is always semver-major

@MarkTiedemann
Copy link
Contributor Author

It's lab. lab detects leaked global variables by checking a list of known globals. So, when Node adds a new global, it also requires an update to lab.

@cjihrig I'm kind of confused about this. Would you mind sending me a link to the lab that you are referring to or giving me a short explanation of what the lab is?

Also, does this have any implications for this PR? Should I make changes to the lab, too? And if so, could you guide me to where these changes are required?

@cjihrig
Copy link
Contributor

cjihrig commented May 13, 2018

@cjihrig I'm kind of confused about this. Would you mind sending me a link to the lab that you are referring to or giving me a short explanation of what the lab is?

lab refers to https://www.npmjs.com/package/lab. It's a test runner used by the hapi.js ecosystem. The addition of a new global variable will cause it's global leak detection to fail, which is one reason why new globals have to come in a semver major release.

@MarkTiedemann
Copy link
Contributor Author

@cjihrig Thank you for the explanation!

I created a tiny heads-up PR in lab: hapijs/lab#833 🙂

@targos targos mentioned this pull request May 13, 2018
2 tasks

if (global.TextDecoder) {
knownGlobals.push(TextDecoder)
}
Copy link
Member

Choose a reason for hiding this comment

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

If these values are added to the global, they should not be checked for. Instead, they should be added to let knownGlobals = [ ... on top. And I guess common/index.js has to be changed as well?

Copy link
Contributor Author

@MarkTiedemann MarkTiedemann May 13, 2018

Choose a reason for hiding this comment

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

I agree, they should not be checked for conditionally. So I'm gonna add TextEncoder and TextDecoder to knownGlobals in both test/common/index.mjs and test/common/index.js.

Thanks for the feedback, @BridgeAR!

On another note, I think the recently added URL global should be added to both arrays, too (but I guess in another PR).

BTW, the globals are only added in the following case:

const browserGlobals = !process._noBrowserGlobals;
if (browserGlobals) {
  // ...
}

https://github.com/MarkTiedemann/node/blob/5820e161214ba315ab70a1239063bf90f090d6e7/lib/internal/bootstrap/node.js#L73-L74

I could not find any documentation regarding this, except that there was once a --no-browser-globals flag, which doesn't seem to work anymore.

λ node --no-browser-globals
node: bad option: --no-browser-globals

So I assume I could remove these 2 lines, too?

EDIT: I found out I can't remove these 2 lines. The no-browser-globals mode can be turned on with configure --no-browser-globals and (...) is not officially supported for regular applications, but still supported after all.

@TimothyGu
Copy link
Member

setTimeout
setTimeout,
TextDecoder,
TextEncoder
Copy link
Member

Choose a reason for hiding this comment

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

I made a mistake in my review earlier. By adding these non-enumerable values we actually do exactly the opposite of what is required in this test. Please remove them and just keep the common files as they were therefore. See #20717 for further details.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@BridgeAR Thanks, will do!

@TimothyGu
Copy link
Member

@MarkTiedemann
Copy link
Contributor Author

The tests are failing because the globals are not set, as they should be. But I haven't figured out why yet. I'd appreciate any help for fixing this.

- value: undefined,
+ value: [Function: TextEncoder]

@MarkTiedemann
Copy link
Contributor Author

Superseded by #22281.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
i18n-api Issues and PRs related to the i18n implementation. notable-change PRs with changes that should be highlighted in changelogs. semver-major PRs that contain breaking changes and should be released in the next major version. wip Issues and PRs that are still a work in progress.
Projects
None yet
Development

Successfully merging this pull request may close these issues.