-
Notifications
You must be signed in to change notification settings - Fork 1.4k
chore(types): migrate module resolution and module types #2012
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
chore(types): migrate module resolution and module types #2012
Conversation
…resolution and module types.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2012 +/- ##
==========================================
- Coverage 81.68% 81.57% -0.11%
==========================================
Files 25 25
Lines 1583 1585 +2
Branches 368 368
==========================================
Hits 1293 1293
- Misses 199 201 +2
Partials 91 91
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a smaller version of my previous PR to migrate to a stricter TypeScript configuration. I added comments to help with the review as always.
@robertsLando could you let me know if there is a way to recognise the browser code and the Node.js code aside from looking at imported dependencies? It would probably make my life a lot easier.
if (reader.result instanceof ArrayBuffer) { | ||
proxy.push(Buffer.from(reader.result)) | ||
|
||
if (data instanceof ArrayBuffer) data = Buffer.from(data) | ||
else data = Buffer.from(data, 'utf8') | ||
proxy.push(data) | ||
return | ||
} | ||
|
||
proxy.push(Buffer.from(reader.result, 'utf-8')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there was a typing issue here, I made a minor refactoring to make the code lighter.
src/lib/connect/tls.ts
Outdated
// @ts-expect-error - There is a type overlap between readable-stream and stream which are used for browsers and node respectively. | ||
// We would need to make it clearer what is aimed at browsers and what is aimed at Node.js to resolve this type issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be very beneficial to make it clear which files are aimed at browsers and which files are aimed at Node.js within the project architecture. As it is today I find it too risky to change any interface since there are so many overlaps.
@@ -9,7 +10,7 @@ export type GenericCallback<T> = (error?: Error, result?: T) => void | |||
|
|||
export type VoidCallback = () => void | |||
|
|||
export type IStream = Duplex & { | |||
export type IStream = (Duplex | NativeDuplex) & { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change actually represents the reality of how IStream
is used. Since this is just a type, it won't affect runtime.
I added @ts-expect-error
directives in other places so we don't break existing code.
tsconfig.json
Outdated
"compilerOptions": { | ||
"module": "commonjs", | ||
"skipLibCheck": true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not added, simply moved up as it will be simpler for me to find which rule is still missing if I preserve the order from my reference.
@@ -1,17 +1,19 @@ | |||
{ | |||
"$schema": "https://json.schemastore.org/tsconfig", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No other effect than adding autocomplete and error highlighting in the IDE.
src/lib/connect/ws.ts
Outdated
// @ts-expect-error - This is a type confusion because of the overlap between browser oriented code and Node.js oriented code. | ||
// Here we are in a Node.js code since the Ws library explictly says it does not work in the browser. | ||
const webSocketStream = Ws.createWebSocketStream(socket, options.wsOptions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SmashingQuasar there is no real overlap here, there is a browserStreamBuilder for browsers and this one is for nodejs so I don't understand what you mean here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the TypeScript error is as follows:
If you look at the signature of Ws.createWebSocketStream()
, you will see that it accepts: internal.DuplexOptions
as second parameter, which is the DuplexOptions
type from node:stream
.
On the other hand, we are passing a IClientOptions
, which has a wsOptions
property with the following typing: ClientOptions | ClientRequestArgs | DuplexOptions
.
The problem here is that the DuplexOptions
from IClientOptions
comes from readable-stream
, while the DuplexOptions
of Ws.createWebSocketStream()
comes from node:stream
. So there is a naming overlap between node:stream:DuplexOptions
and readable-stream:DuplexOptions
.
ClientOptions.wsOptions
can be of three different types, we would need to create type guards to narrow down the type and ensure it is indeed a readable-stream:DuplexOptions
. I can absolutely implement this, but this will affect runtime and reject any wrongly typed option, which will have possible effects on users. Since we want to have a cautious approach, I elected to use the safest course of action and not touch the code at runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a small addition to my explanation: From my understanding, the entire point of using readable-stream
is to work with browsers, as it is otherwise entirely superseded by the node:stream
native library, hence why I am so confused about the mix between node:stream
and readable-stream
within the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok now I understad what you mean
tsconfig.json
Outdated
"module": "NodeNext", | ||
"moduleResolution": "NodeNext", | ||
"target": "ESNext", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For setting og module/moduleResolution and target I think the best is to use @tsconfig/node packages. Maybe in our case https://www.npmjs.com/package/@tsconfig/node20 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I noted that you wanted to extend the configuration, however you also want to introduce as few rules as possible, and the configuration you want to extend introduces "strict": true
which will create more errors, and thus more changes.
strict
is an alias for many strict rules so it would devolve this PR in a large number of changes. Let me know how you want to proceed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SmashingQuasar I would use that and set each strict rule explicit to false and put it true one by one on next PRs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robertsLando I just did that, the problem is that @tsconfig/node20
is designed to work with Node.js 20, not with a mix of Node.js 20 and browsers API. For example the FileReader
class whihc is used in the ali.ts
file (which I assume is browser exclusive) can never be resolved.
I'll try to re-extend the correct libraries to avoid breaking more things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a lib: ["DOM"]
extension in the tsconfig
but honestly, to me this is a really bad idea.
I think you can't reliably extends @tsconfig/node20
until there is a separation between what is for browsers and what is for Node.js or you are taking the risk to use symbols (such as FileReader) that do not exist in one of the environments.
src/lib/connect/ws.ts
Outdated
options.wsOptions as DuplexOptions, | ||
) | ||
// @ts-expect-error - This is a type confusion because of the overlap between browser oriented code and Node.js oriented code. | ||
// Here we are in a Node.js code since the Ws library explictly says it does not work in the browser. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove this comment (and keep only the ts expect error) as it's obvious we are in nodejs env here considering there is also the browser stream builder method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can remove it for sure.
I just don't find it obvious at all that we are in a Node.js context only within this file, especially since we import isBrowser
and have a condition on this on another section of the same file.
I removed the comment in question. |
@SmashingQuasar We already have tests for socks with a mocked socks server here: https://github.com/mqttjs/MQTT.js/blob/main/test/node/socks.ts Maybe there is just no test that inits a client with a sock proxy and I think that if that line isn't covered by test it was not even before. Would you like to add a simple test for that? |
Hey @robertsLando , sorry for not answering earlier, the end of the week was quite busy. |
It's ok for me 👍🏼 |
Description
This PR slightly changes the TypeScript configuration as a first step to migrate towards a stricter TypeScript configuration.