+
Skip to content

Conversation

fireairforce
Copy link
Member

Summary

closes: #4215

Typescript 5.9 Beta support import defer, which is a stage-3 proposal: https://devblogs.microsoft.com/typescript/announcing-typescript-5-9-beta/#support-for-import-defer

The implement we can refer to: https://github.com/microsoft/TypeScript/pull/60757/files

This PR support import defer, the syntax looks like:

import defer * as foo from "<specifier>";

And the syntax import defer foo from "<specifier>" or import defer { foo } from "<specifier>" is invalid.

In this pr, I use defer as a keyword just like what TypeScript do.

Test Plan

I add test case for biome_js_parser and biome_js_formatter.

Docs

Copy link

changeset-bot bot commented Jul 20, 2025

🦋 Changeset detected

Latest commit: 0c74466

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools L-JavaScript Language: JavaScript and super languages labels Jul 20, 2025
Copy link
Contributor

github-actions bot commented Jul 20, 2025

Parser conformance results on

js/262

Test result main count This PR count Difference
Total 50627 50627 0
Passed 49303 49357 ✅ ⏫ +54
Failed 1324 1270 ✅ ⏬ -54
Panics 0 0 0
Coverage 97.38% 97.49% +0.11%
🎉 Fixed (54):
test/language/import/import-defer/deferred-namespace-object/exotic-object-behavior.js
test/language/import/import-defer/deferred-namespace-object/to-string-tag.js
test/language/import/import-defer/errors/get-self-while-defer-evaluating/main.js
test/language/import/import-defer/errors/get-self-while-evaluating-async/main.js
test/language/import/import-defer/errors/get-self-while-evaluating.js
test/language/import/import-defer/errors/module-throws/third-party-evaluation-after-defer-import.js
test/language/import/import-defer/errors/module-throws/trigger-evaluation.js
test/language/import/import-defer/evaluation-sync/import-defer-does-not-evaluate.js
test/language/import/import-defer/evaluation-sync/module-imported-defer-and-eager.js
test/language/import/import-defer/evaluation-top-level-await/flattening-order/main.js
test/language/import/import-defer/evaluation-top-level-await/import-defer-async-module/main.js
test/language/import/import-defer/evaluation-top-level-await/import-defer-transitive-async-module/main.js
test/language/import/import-defer/evaluation-top-level-await/sync-dependency-of-deferred-async-module/main.js
test/language/import/import-defer/evaluation-triggers/ignore-exported-then-defineOwnProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-exported-then-delete.js
test/language/import/import-defer/evaluation-triggers/ignore-exported-then-get.js
test/language/import/import-defer/evaluation-triggers/ignore-exported-then-getOwnProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-exported-then-hasProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-getPrototypeOf.js
test/language/import/import-defer/evaluation-triggers/ignore-isExtensible.js
test/language/import/import-defer/evaluation-triggers/ignore-not-exported-then-defineOwnProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-not-exported-then-delete.js
test/language/import/import-defer/evaluation-triggers/ignore-not-exported-then-get.js
test/language/import/import-defer/evaluation-triggers/ignore-not-exported-then-getOwnProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-not-exported-then-hasProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-preventExtensions.js
test/language/import/import-defer/evaluation-triggers/ignore-set-string-exported.js
test/language/import/import-defer/evaluation-triggers/ignore-set-string-not-exported.js
test/language/import/import-defer/evaluation-triggers/ignore-setPrototypeOf.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-other-defineOwnProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-other-delete.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-other-get.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-other-getOwnProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-other-hasProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-toStringTag-defineOwnProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-toStringTag-delete.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-toStringTag-get.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-toStringTag-getOwnProperty.js
test/language/import/import-defer/evaluation-triggers/ignore-symbol-toStringTag-hasProperty.js
test/language/import/import-defer/evaluation-triggers/trigger-exported-string-defineOwnProperty.js
test/language/import/import-defer/evaluation-triggers/trigger-exported-string-delete.js
test/language/import/import-defer/evaluation-triggers/trigger-exported-string-get.js
test/language/import/import-defer/evaluation-triggers/trigger-exported-string-getOwnProperty.js
test/language/import/import-defer/evaluation-triggers/trigger-exported-string-hasProperty.js
test/language/import/import-defer/evaluation-triggers/trigger-not-exported-string-defineOwnProperty.js
test/language/import/import-defer/evaluation-triggers/trigger-not-exported-string-delete.js
test/language/import/import-defer/evaluation-triggers/trigger-not-exported-string-get.js
test/language/import/import-defer/evaluation-triggers/trigger-not-exported-string-getOwnProperty.js
test/language/import/import-defer/evaluation-triggers/trigger-not-exported-string-hasProperty.js
test/language/import/import-defer/evaluation-triggers/trigger-ownPropertyKey-names.js
test/language/import/import-defer/evaluation-triggers/trigger-ownPropertyKeys-symbols.js
test/language/import/import-defer/evaluation-triggers/trigger-ownPropertyKeys.js
test/language/import/import-defer/syntax/import-attributes.js
test/language/import/import-defer/syntax/valid-defer-namespace.js

jsx/babel

Test result main count This PR count Difference
Total 40 40 0
Passed 37 37 0
Failed 3 3 0
Panics 0 0 0
Coverage 92.50% 92.50% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 6706 6706 0
Passed 2244 2245 ✅ ⏫ +1
Failed 4462 4461 ✅ ⏬ -1
Panics 0 0 0
Coverage 33.46% 33.48% +0.01%
🎉 Fixed (1):
importDeferComments.symbols

ts/babel

Test result main count This PR count Difference
Total 822 822 0
Passed 731 731 0
Failed 91 91 0
Panics 0 0 0
Coverage 88.93% 88.93% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 18784 18784 0
Passed 14412 14412 0
Failed 4372 4372 0
Panics 0 0 0
Coverage 76.72% 76.72% 0.00%
🔥 Regression (2):
conformance/importDefer/importDeferNamespace.ts
conformance/importDefer/importDeferTypeConflict1.ts
🎉 Fixed (2):
conformance/importDefer/importDeferComments.ts
conformance/importDefer/importDeferDeclaration.ts

Copy link

codspeed-hq bot commented Jul 20, 2025

CodSpeed Performance Report

Merging #6949 will not alter performance

Comparing feat-4215 (0c74466) with main (249306d)

Summary

✅ 115 untouched benchmarks

@ematipico
Copy link
Member

Out of curiosity, is the following syntax allowed?

import defer type * as foo from "bar"

@fireairforce
Copy link
Member Author

Out of curiosity, is the following syntax allowed?

import defer type * as foo from "bar"

No, only allow import defer * as foo from "bar", the behaviour is align with https://www.typescriptlang.org/play/?ts=5.9.0-beta#code/JYWwDg9gTgLgBAEwKYDMlTjAnmJcBUcAhgM5woQTlQQhwBEARkVPUA

Co-authored-by: Denis Bezrukov <6227442+denbezrukov@users.noreply.github.com>
@fireairforce
Copy link
Member Author

The next step i will support import source: https://github.com/tc39/proposal-source-phase-imports

Syntax like: import.defer() will support in next pr.

@fireairforce
Copy link
Member Author

fireairforce commented Jul 20, 2025

Out of curiosity, is the following syntax allowed?

import defer type * as foo from "bar"

also add test case for this example

// import defer * as foo from "mod";
JsImportNamespaceClause =
'type'?
'type'? | 'defer'?
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 wondering if we can reuse the logic from Babel:
https://github.com/babel/babel/blob/ab6de823b3353b2af6d8e163b55fdc763aa840a6/packages/babel-parser/src/types.ts#L751
They have a separate token for it: phase.

What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

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

you are right here,before i make this pr,i also refer swc and oxc's parser imeplement of the import defer,they do the same things as babel does. I will change here too

// import defer * as foo from "mod";
JsImportNamespaceClause =
'type'?
phase: 'defer'?
Copy link
Member Author

@fireairforce fireairforce Jul 20, 2025

Choose a reason for hiding this comment

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

@denbezrukov i add a phase field here, i will expand this filed in the next pr when i support phase: 'source', that case will be different from import defer here.

import defer need to support syntax like:

import defer * as x from 'mod';

import source syntax is:

import source x from 'mod';

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mean that a 'source' phase doesn't make any sense for a namespace syntax?
I think you're right!

To be honest I have the same feeling for a 'type' token.
It might be also a 'phase' modifier.
But I'm not sure how many changes it might require.

Copy link
Member Author

Choose a reason for hiding this comment

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

It’s not a big problem. I’ll observe it again when I implement the import source. We will keep the phase here now.

@fireairforce fireairforce merged commit 48462f8 into main Jul 21, 2025
30 checks passed
@fireairforce fireairforce deleted the feat-4215 branch July 21, 2025 07:50
@github-actions github-actions bot mentioned this pull request Jul 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Formatter Area: formatter A-Parser Area: parser A-Tooling Area: internal tools L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

📎 Add support for the defer attribute in import statements

3 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载