Repository navigation
Conversation
Contributor
Tests PassedCommit: 3857cd0 |
This was referenced Nov 5, 2026
sokra
commented
Nov 9, 2026
β¦eads-export snapshot test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦ test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦t test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦ snapshot test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦snapshot test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦exports snapshot test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦est to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦t test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦t to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦est to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦st to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦ test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦apshot test, covered by the require-binding execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦shot test to the require-narrow execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦test to the require-narrow execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦st to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
β¦erty snapshot test to an execution test Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
sokra
force-pushed
the
fleet/turbopack-exec-tests-3-cjs-tree-shaking
branch
from
November 9, 2026 13:35
17235c0 to
3857cd0
Compare
sokra
commented
Nov 9, 2026
Comment on lines
-3
to
-5
| + v-----------------------------v | ||
| 1 + import { used } from './lib.js' | ||
| + ^-----------------------------^ |
Member
Author
There was a problem hiding this comment.
Follow-up: This is a bug. used exists in the module. this.used should also be detected similar to exports.used.
sokra
marked this pull request as ready for review
November 9, 2026 16:25
sokra
added a commit
that referenced
this pull request
Nov 9, 2026
β¦tests (#101211) **Stack** (migrating Turbopack snapshot tests to execution tests), part 1 of 7: 1. #101211: imports, `import.meta`, TypeScript config, Node β this PR 2. #101227: comptime 3. #101228: CommonJS tree shaking 4. #101229: ESM export optimizations 5. #101230: tree shaking and scope hoisting 6. #101231: basic/chunking 7. #101232: CSS ### What? Migrates the `imports/*`, `import-meta/*`, `typescript/*` and `node/*` Turbopack snapshot tests (`turbopack/crates/turbopack-tests/tests/snapshot/**`) to execution tests (`tests/execution/turbopack/**`), and removes the stale `imports/import-meta-glob` snapshot output (it had no `input/`). Test-only change. The one harness change is small: `tests/execution.rs` now puts static assets inside the output root, so they are written to disk with the chunks. No compiler or runtime code changes. This is the first PR of a stack that moves 104 of the 128 snapshot tests to execution tests, one category group per PR. ### Why? Snapshot tests store the whole emitted bundle. Any unrelated codegen or runtime change touches many output files, and the snapshot doesn't say which property the test is meant to check. Execution tests run the bundled code and assert that property directly. ### How? For each snapshot test I worked out its intent and asserted it, preferring in this order: 1. **Runtime behavior**: values, module identity, evaluation order, thrown errors. 2. **`fn.toString()` / module factory source** via `__turbopack_modules__`, for optimizations not observable at runtime. 3. **Emitted output files**, as a last resort. A new shared helper, `tests/execution/turbopack/__helpers__/module-factories.js`, finds a module's factories in `__turbopack_modules__` by its path under `input/` and returns their source. Tests across the stack use it instead of copies of the same lookup. Fixture discovery doesn't pick it up as a test. In this PR: - **Imports:** - dynamic imports and modules shared between static and dynamic imports. A dynamic import of a module that is already available resolves within one microtask, so no chunk is loaded (`productionChunking`) - static asset URLs, and that the asset file is emitted with the right content - JSON imports (including huge and invalid JSON), and that huge JSON is parsed with `JSON.parse` - extension resolution order - duplicate bindings - ignore comments, which keep ignored `import()`/`require()` in the output - optional-import comments - unresolvable CJS/ESM requests, which throw when evaluated Reported issues stay as the execution tests' `issues/` snapshots. - **`import.meta`:** `import.meta.url` in ESM and CommonJS, multiple usages, the exact properties of the object (`url` and the `env` object), mutation, using the object as a value, and `new URL(..., import.meta.url)` assets. - **TypeScript config:** `paths`/`baseUrl` from `jsconfig.json`/`tsconfig.json` and every `extends` variant, asserted through the modules they resolve to. - **Node:** `node:` and Bun builtins are externals, and `child_process` spawns with a dynamic program or an inline `node -e` script. - Snapshot tests default to all optimizations off and execution tests to most of them on. Each migrated test sets the options its intent depends on. - The Web Worker cases of `imports/ignore-comments` stay as a snapshot test, because the execution harness only runs Node.js. - The stale `imports/import-meta-glob` output only had the source in its source map. That case (lazy matches split into async chunks, eager ones kept in the entry chunk) is already covered by the existing `resolving/import-meta-glob-code-splitting` execution test. Verified with `cargo test -p turbopack-tests --test execution --test snapshot` on this layer: 360 execution and 116 snapshot tests pass. Prettier is clean. <!-- NEXT_JS_LLM --> <!-- fleet a144b357-ef78-451c-8231-ec24b8a59cec --> --------- Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
sokra
added a commit
that referenced
this pull request
Nov 9, 2026
**Stack** (migrating Turbopack snapshot tests to execution tests), part 2 of 7: 1. #101211: imports, `import.meta`, TypeScript config, Node 2. #101227: comptime β this PR 3. #101228: CommonJS tree shaking 4. #101229: ESM export optimizations 5. #101230: tree shaking and scope hoisting 6. #101231: basic/chunking 7. #101232: CSS ### What? Migrates the `comptime/*` Turbopack snapshot tests to execution tests. Test-only change. ### Why? Same motivation as the rest of the stack: the snapshots store whole bundles, but these tests are about compile-time evaluation. An execution test can assert that directly. ### How? - Each test checks its runtime result. It then inspects the module factory source (`fn.toString()` via `__turbopack_modules__`) to confirm the constant was inlined or the dead code removed. Covered cases: - cross-module constant inlining, including constants computed from other constants and constants reexported through side-effect-free barrels - `turbopackConstants: true/false` import attributes, and the issue for non-constant exports. The branches that must stay require modules that don't exist, so the `issues/` snapshot proves they were kept at compile time - long literals, which aren't inlined - constant/dynamic export cycles not hanging - code after an early `return` being removed (top level, if/else, class members, nested functions) - `typeof` on a CommonJS module - Tests that inspect per-module factories disable scope hoisting, so modules stay separate. - For each test I flipped the relevant option and confirmed the test fails. - `comptime/define` stays a snapshot test. It needs custom compile-time defines that the execution harness doesn't configure. - Two missed optimizations are tracked as expected-failure tests in `comptime/__skipped__/`. The harness requires them to fail until they are implemented: - `cross-module-imported-reexports`: values a module imports and (re)exports are constants too, but aren't inlined. - `cross-module-long-literal-conditions`: long literals, `NaN` and `Infinity` aren't inlined, but could still be used to evaluate conditions at compile time. Known gap, not addressed here: `comptime/cross-module-strict` needs `scopeHoisting: false`. With module merging on, `other.js`'s module factory goes missing at runtime. Verified on this layer: 372 execution and 106 snapshot tests pass. Prettier is clean. <!-- NEXT_JS_LLM --> <!-- fleet a144b357-ef78-451c-8231-ec24b8a59cec --> --------- Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
sokra
added a commit
that referenced
this pull request
Nov 9, 2026
β¦n tests (#101229) **Stack** (migrating Turbopack snapshot tests to execution tests), part 4 of 7: 1. #101211: imports, `import.meta`, TypeScript config, Node 2. #101227: comptime 3. #101228: CommonJS tree shaking 4. #101229: ESM export optimizations β this PR 5. #101230: tree shaking and scope hoisting 6. #101231: basic/chunking 7. #101232: CSS ### What? Migrates the ESM export optimization snapshot tests to execution tests: `export-alls/*`, `ns-value-reexport/*`, `reexport-drop/*`, `remove-unused-imports/*`, `mangle-exports/*` and `reexport-registration/*`. Test-only change. ### Why? These tests cover export-level optimizations: dropping unused re-exports, export mangling, and how re-exports are registered. A snapshot of the whole bundle doesn't show which of these each test checks. Execution tests assert it directly. ### How? - **Runtime assertions** cover: - `export *` of CommonJS through a chain, and from a module with side effects - namespaces reexported as values - reexports registered from several sources, with names with and without commas, in separate statements, or from a module scope-hoisted into the importer. `facade-scope-hoisted-shared` also asserts the current hoisting shape: the facade of `x.js` is merged into `index.js`, and `x.js <locals>` and the dynamically imported `reexports.js` keep their own factories - namespace key order: `plain-reexports` checks it without sorting - **Module factory inspection** confirms that unused static, dynamic and renamed reexports are dropped, and that imports used only by unused exports are removed, transitively. A namespace import accessed with a string-literal key is narrowed. - **Options:** the tests set `followReexports`/`removeUnusedExports` explicitly where their intent depends on them. - **Export mangling** is on by default in execution tests. `exports/mangle-single-export` checks the value and the fixed single-export key, not the original export name. - Removed as duplicates: - `reexport-drop/basic` is identical to `reexport-drop/dynamic`. - `mangle-exports/escaping-namespace` and `mangle-exports/named-and-preserved` are covered by the `exports/mangle-*` execution tests. - `reexport-registration/{comma-name,facade-all-reexports,two-sources}` are covered by existing `reexport-registration` execution tests. - For the optimization tests I flipped the relevant option and confirmed the test fails. Known gap, not addressed here: a namespace that re-exports names from several modules lists them module by module, not in the code unit order ESM requires. `mixed-encoding` gives `b, has,comma, c`. That test still sorts the keys. The correct order is checked by the expected-failure test `reexport-registration/__skipped__/mixed-encoding-namespace-key-order`. Verified on this layer: 398 execution and 70 snapshot tests pass. Prettier is clean. <!-- NEXT_JS_LLM --> <!-- fleet a144b357-ef78-451c-8231-ec24b8a59cec --> --------- Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
sokra
added a commit
that referenced
this pull request
Nov 9, 2026
β¦execution tests (#101230) **Stack** (migrating Turbopack snapshot tests to execution tests), part 5 of 7: 1. #101211: imports, `import.meta`, TypeScript config, Node 2. #101227: comptime 3. #101228: CommonJS tree shaking 4. #101229: ESM export optimizations 5. #101230: tree shaking and scope hoisting β this PR 6. #101231: basic/chunking 7. #101232: CSS ### What? Migrates the tree-shaking and scope-hoisting snapshot tests to execution tests: `basic-tree-shake/*`, `intermediate-tree-shake/*`, `tree-shaking/dce`, `scope-hoisting/*` and `minification/paren-remover`. Test-only change. ### Why? These tests are about which code survives tree shaking and how modules are merged. The snapshots store the whole bundle without stating that property. Execution tests run the code and inspect the relevant module factories. ### How? - **Tree shaking:** `basic-tree-shake` and `intermediate-tree-shake` enable `moduleFragmentsEnabled`. They assert side effects and imported values, and check that unused exports are removed, for named, renamed, namespace, side-effect, `require` and dynamic imports. `intermediate-tree-shake` also checks importing locals of a module that has reexports, skipping a side-effect-free facade, and exporting only the used function. - **DCE:** `tree-shaking/dce` asserts a module only used in dead code is removed. - **Scope hoisting:** `scope-hoisting/*` check that merged modules importing the same module evaluate it once and in order, and that a merged module is shared between async chunks and merged only within one chunk. - `scope-hoisting/direct-eval` moves into the existing `direct-eval` execution test, which now also checks that indirect eval is still hoisted. - `minification/paren-remover` is removed: the existing `paren-remover` execution test now runs minified and covers it. - For each optimization test I flipped the relevant option and confirmed the test fails. Known bug, not fixed here: with module fragments, a mutated variable's side effects all see its final value, so `dog!!!` is logged three times instead of `dog!`, `dog!!`, `dog!!!`. The old snapshot output already showed this. The migrated tests assert that the side effects happen. The correct order is in `basic-tree-shake/__skipped__/side-effect-order`, which the harness requires to fail until the bug is fixed. Verified on this layer: 414 execution and 53 snapshot tests pass. Prettier is clean. <!-- NEXT_JS_LLM --> <!-- fleet a144b357-ef78-451c-8231-ec24b8a59cec --> --------- Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
sokra
added a commit
that referenced
this pull request
Nov 9, 2026
**Stack** (migrating Turbopack snapshot tests to execution tests), part 6 of 7: 1. #101211: imports, `import.meta`, TypeScript config, Node 2. #101227: comptime 3. #101228: CommonJS tree shaking 4. #101229: ESM export optimizations 5. #101230: tree shaking and scope hoisting 6. #101231: basic/chunking β this PR 7. #101232: CSS ### What? Migrates the `basic/*` Turbopack snapshot tests to execution tests. Test-only change. ### Why? These tests cover chunking and basic code generation: async chunks, minification, `export default`, shebangs, top-level await and parse errors. Execution tests assert the behavior directly, instead of storing the whole emitted bundle. ### How? - **Chunking:** `async-chunk`, `async-chunk-build` and `nested-async-availability` load (nested) async chunks that share modules with their parent chunk. `chunked` imports from `node_modules`. - **Minification:** the `ecmascript-minify*` tests enable minification. They check that behavior is kept and that the module factory source is compressed or minified per module, and that CommonJS modules minified before chunking stay in sloppy mode while ES modules stay strict. That is checked at runtime, not by looking for a `"use strict"` directive. - **Codegen:** - `export-default` imports a default-exported expression. - `shebang` handles shebangs in the entry and in `node_modules`. - `top-level-await` waits for a module using top-level await. - **Errors:** `ts-parse-error` throws when the broken module is required, and keeps its parse error as an `issues/` snapshot. Its `.prettierignore` entry moves with the fixture. - **Removed:** `basic/use-strict`, which the `minification/strict-mode-layouts` execution tests cover. - **Still snapshots**, because the browser chunk format is what they test: `basic/chunk_loading_global` and `basic/single-chunk-entry`. Verified on this layer: 425 execution and 41 snapshot tests pass. Prettier is clean. <!-- NEXT_JS_LLM --> <!-- fleet a144b357-ef78-451c-8231-ec24b8a59cec --> --------- Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
sokra
added a commit
that referenced
this pull request
Nov 9, 2026
**Stack** (migrating Turbopack snapshot tests to execution tests), part 7 of 7: 1. #101211: imports, `import.meta`, TypeScript config, Node 2. #101227: comptime 3. #101228: CommonJS tree shaking 4. #101229: ESM export optimizations 5. #101230: tree shaking and scope hoisting 6. #101231: basic/chunking 7. #101232: CSS β this PR ### What? Migrates the `css/*` and `cssmodules/*` Turbopack snapshot tests to execution tests. This is the last PR of the stack. Test-only change. ### Why? The CSS snapshots store whole emitted chunks, but each test checks one property, such as import order or `url()` rewriting. These execution tests assert that property directly. ### How? - **CSS modules:** `composes` (also from another CSS module or a package), static and dynamic imports, and deduplication are asserted at runtime through the exported class names. - **Emitted CSS:** the other tests read the emitted CSS chunks from `output/` (which the harness cleans before every run) and check one property each, not the whole file. A new shared helper, `__helpers__/css.js`, reads the chunks and parses their source comments, so the tests don't each copy that code: - absolute-URL `@import`s are hoisted without duplicates, and relative ones inlined in order - protocol-relative imports stay external - bare `@import`s resolve relative to the importing file - `layer()`, media and supports attributes of nested imports are chained - `url()` is rewritten to the emitted asset; unresolvable `url()`s and `url()` in `@supports` are kept unchanged - legacy nesting is flattened - output is minified - `@import` cycles and modules shared between chunks keep their order (most fixtures already encode the expected position in `content: 'N'`) - **Errors:** after an invalid rule, the valid rules around it are kept. Issues stay as `issues/` snapshots, and `css-parse-error`'s `.prettierignore` entry moves with the fixture. **Kept as snapshot tests across the stack** (24), because the output itself is under test or the Node.js-only execution harness can't express them: - browser runtime/chunk format: `runtime/*`, `workers/*`, `basic/chunk_loading_global`, `basic/single-chunk-entry`, `example`, `evaluated_entrry` - source maps and debug IDs: `source_maps/*`, `debug-ids/*` - transforms the execution harness doesn't configure: `swc_transforms/*`, `emotion`, `styled_components` - harness-specific setup: `comptime/define`, `env/env`, `dynamic-request/very-dynamic`, and the Web Worker cases of `imports/ignore-comments` Known gap, not addressed here: the snapshot harness doesn't discover `swc_transforms/mono_transforms`. It uses a custom entry and has no `input/index.*`. This predates the stack. Verified on this layer, the top of the stack: 442 execution and 24 snapshot tests pass. Prettier is clean. <!-- NEXT_JS_LLM --> <!-- fleet a144b357-ef78-451c-8231-ec24b8a59cec --> --------- Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack (migrating Turbopack snapshot tests to execution tests), part 3 of 7:
import.meta, TypeScript config, NodeWhat?
Migrates the
cjs-remove-unused-exports/*andcjs-remove-unused-imports/*Turbopack snapshot tests to execution tests. Test-only change.Why?
These tests check CommonJS tree shaking: which
exports.*assignments are dropped and which are kept. In a snapshot, that property is buried in the whole bundle. Execution tests can assert it directly and still check the runtime values.How?
cjsTreeShaking. Each one asserts the values the consumer reads, then inspects the CommonJS module factory source to confirm unused exports were dropped and used ones kept. Cases covered:Object.definePropertyexports, including getters that read another exportthisexports, andthisread from an arrow functionmodule.exportsobject literals: plain, with getters and methods, with__esModuleinterop, and with later assignmentsrequireconsumers: aliased requires, require bindings that escape or are narrowed to members, destructuring, and wholesale requires keeping all exportscjs-remove-unused-imports: discardedrequire()s of side-effect-free modules are removed. A module that defines properties on a foreign object is kept.require-destructureandrequire-memberare merged into onerequire-narrowexecution test.require-binding-escapeis removed: therequire-bindingexecution test covers it.cjsTreeShakingand confirmed the test fails.Verified on this layer: 385 execution and 88 snapshot tests pass. Prettier is clean.