mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
perf(node): ensure cjs wrapper module has deterministic output (#24248)
This commit is contained in:
parent
bc7db0f703
commit
37128321ae
2 changed files with 72 additions and 62 deletions
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashSet;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
@ -106,7 +107,8 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
|
|||
.to_string(),
|
||||
];
|
||||
|
||||
let mut all_exports = analysis.exports.into_iter().collect::<HashSet<_>>();
|
||||
// use a BTreeSet to make the output deterministic for v8's code cache
|
||||
let mut all_exports = analysis.exports.into_iter().collect::<BTreeSet<_>>();
|
||||
|
||||
if !analysis.reexports.is_empty() {
|
||||
let mut errors = Vec::new();
|
||||
|
@ -159,7 +161,7 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
|
|||
&'a self,
|
||||
entry_specifier: &url::Url,
|
||||
reexports: Vec<String>,
|
||||
all_exports: &mut HashSet<String>,
|
||||
all_exports: &mut BTreeSet<String>,
|
||||
// this goes through the modules concurrently, so collect
|
||||
// the errors in order to be deterministic
|
||||
errors: &mut Vec<anyhow::Error>,
|
||||
|
|
|
@ -5043,8 +5043,8 @@ fn run_etag_delete_source_cache() {
|
|||
|
||||
#[test]
|
||||
fn code_cache_test() {
|
||||
let deno_dir = TempDir::new();
|
||||
let test_context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let deno_dir = test_context.deno_dir();
|
||||
let temp_dir = test_context.temp_dir();
|
||||
temp_dir.write("main.js", "console.log('Hello World - A');");
|
||||
|
||||
|
@ -5052,17 +5052,14 @@ fn code_cache_test() {
|
|||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.arg("run")
|
||||
.arg("-Ldebug")
|
||||
.arg("main.js")
|
||||
.args("run -Ldebug main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
|
||||
output
|
||||
.assert_stdout_matches_text("Hello World - A[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/main.js[WILDCARD]");
|
||||
assert!(!output.stderr().contains("V8 code cache hit"));
|
||||
assert_not_contains!(output.stderr(), "V8 code cache hit");
|
||||
|
||||
// Check that the code cache database exists.
|
||||
let code_cache_path = deno_dir.path().join(CODE_CACHE_DB_FILE_NAME);
|
||||
|
@ -5073,35 +5070,28 @@ fn code_cache_test() {
|
|||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.arg("run")
|
||||
.arg("-Ldebug")
|
||||
.arg("main.js")
|
||||
.args("run -Ldebug main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
|
||||
output
|
||||
.assert_stdout_matches_text("Hello World - A[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]V8 code cache hit for ES module: file:///[WILDCARD]/main.js[WILDCARD]");
|
||||
assert!(!output.stderr().contains("Updating V8 code cache"));
|
||||
assert_not_contains!(output.stderr(), "Updating V8 code cache");
|
||||
}
|
||||
|
||||
// Rerun with --no-code-cache.
|
||||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.arg("run")
|
||||
.arg("-Ldebug")
|
||||
.arg("--no-code-cache")
|
||||
.arg("main.js")
|
||||
.args("run -Ldebug --no-code-cache main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
|
||||
output
|
||||
.assert_stdout_matches_text("Hello World - A[WILDCARD]")
|
||||
.skip_stderr_check();
|
||||
assert!(!output.stderr().contains("V8 code cache"));
|
||||
assert_not_contains!(output.stderr(), "V8 code cache");
|
||||
}
|
||||
|
||||
// Modify the script, and make sure that the cache is rejected.
|
||||
|
@ -5109,27 +5099,21 @@ fn code_cache_test() {
|
|||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.arg("run")
|
||||
.arg("-Ldebug")
|
||||
.arg("main.js")
|
||||
.args("run -Ldebug main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
|
||||
output
|
||||
.assert_stdout_matches_text("Hello World - B[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/main.js[WILDCARD]");
|
||||
assert!(!output.stderr().contains("V8 code cache hit"));
|
||||
assert_not_contains!(output.stderr(), "V8 code cache hit");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn code_cache_npm_test() {
|
||||
let deno_dir = TempDir::new();
|
||||
let test_context = TestContextBuilder::new()
|
||||
.use_temp_cwd()
|
||||
.use_http_server()
|
||||
.build();
|
||||
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
||||
let deno_dir = test_context.deno_dir();
|
||||
let temp_dir = test_context.temp_dir();
|
||||
temp_dir.write(
|
||||
"main.js",
|
||||
|
@ -5140,12 +5124,7 @@ fn code_cache_npm_test() {
|
|||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.envs(env_vars_for_npm_tests())
|
||||
.arg("run")
|
||||
.arg("-Ldebug")
|
||||
.arg("-A")
|
||||
.arg("main.js")
|
||||
.args("run -Ldebug -A main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
|
||||
|
@ -5153,7 +5132,7 @@ fn code_cache_npm_test() {
|
|||
.assert_stdout_matches_text("Hello World[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/main.js[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/chalk/5.[WILDCARD]/source/index.js[WILDCARD]");
|
||||
assert!(!output.stderr().contains("V8 code cache hit"));
|
||||
assert_not_contains!(output.stderr(), "V8 code cache hit");
|
||||
|
||||
// Check that the code cache database exists.
|
||||
let code_cache_path = deno_dir.path().join(CODE_CACHE_DB_FILE_NAME);
|
||||
|
@ -5164,12 +5143,7 @@ fn code_cache_npm_test() {
|
|||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.envs(env_vars_for_npm_tests())
|
||||
.arg("run")
|
||||
.arg("-Ldebug")
|
||||
.arg("-A")
|
||||
.arg("main.js")
|
||||
.args("run -Ldebug -A main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
|
||||
|
@ -5177,17 +5151,14 @@ fn code_cache_npm_test() {
|
|||
.assert_stdout_matches_text("Hello World[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]V8 code cache hit for ES module: file:///[WILDCARD]/main.js[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]V8 code cache hit for ES module: file:///[WILDCARD]/chalk/5.[WILDCARD]/source/index.js[WILDCARD]");
|
||||
assert!(!output.stderr().contains("Updating V8 code cache"));
|
||||
assert_not_contains!(output.stderr(), "Updating V8 code cache");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn code_cache_npm_with_require_test() {
|
||||
let deno_dir = TempDir::new();
|
||||
let test_context = TestContextBuilder::new()
|
||||
.use_temp_cwd()
|
||||
.use_http_server()
|
||||
.build();
|
||||
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
||||
let deno_dir = test_context.deno_dir();
|
||||
let temp_dir = test_context.temp_dir();
|
||||
temp_dir.write(
|
||||
"main.js",
|
||||
|
@ -5198,12 +5169,7 @@ fn code_cache_npm_with_require_test() {
|
|||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.envs(env_vars_for_npm_tests())
|
||||
.arg("run")
|
||||
.arg("-Ldebug")
|
||||
.arg("-A")
|
||||
.arg("main.js")
|
||||
.args("run -Ldebug -A main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
|
||||
|
@ -5213,7 +5179,7 @@ fn code_cache_npm_with_require_test() {
|
|||
.assert_stderr_matches_text("[WILDCARD]Updating V8 code cache for ES module: file:///[WILDCARD]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]Updating V8 code cache for script: file:///[WILDCARD]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]Updating V8 code cache for script: file:///[WILDCARD]/browserslist/[WILDCARD]/index.js[WILDCARD]");
|
||||
assert!(!output.stderr().contains("V8 code cache hit"));
|
||||
assert_not_contains!(output.stderr(), "V8 code cache hit");
|
||||
|
||||
// Check that the code cache database exists.
|
||||
let code_cache_path = deno_dir.path().join(CODE_CACHE_DB_FILE_NAME);
|
||||
|
@ -5224,12 +5190,7 @@ fn code_cache_npm_with_require_test() {
|
|||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.env("DENO_DIR", deno_dir.path())
|
||||
.envs(env_vars_for_npm_tests())
|
||||
.arg("run")
|
||||
.arg("-Ldebug")
|
||||
.arg("-A")
|
||||
.arg("main.js")
|
||||
.args("run -Ldebug -A main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
|
||||
|
@ -5239,7 +5200,54 @@ fn code_cache_npm_with_require_test() {
|
|||
.assert_stderr_matches_text("[WILDCARD]V8 code cache hit for ES module: file:///[WILDCARD]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]V8 code cache hit for script: file:///[WILDCARD]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD]")
|
||||
.assert_stderr_matches_text("[WILDCARD]V8 code cache hit for script: file:///[WILDCARD]/browserslist/[WILDCARD]/index.js[WILDCARD]");
|
||||
assert!(!output.stderr().contains("Updating V8 code cache"));
|
||||
assert_not_contains!(output.stderr(), "Updating V8 code cache");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn code_cache_npm_cjs_wrapper_module_many_exports() {
|
||||
// The code cache was being invalidated because the CJS wrapper module
|
||||
// had indeterministic output.
|
||||
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
||||
let temp_dir = test_context.temp_dir();
|
||||
temp_dir.write(
|
||||
"main.js",
|
||||
// this package has a few exports
|
||||
"import { hello } from \"npm:@denotest/cjs-reexport-collision\";hello.sayHello();",
|
||||
);
|
||||
|
||||
// First run with no prior cache.
|
||||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.args("run -Ldebug -A main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
|
||||
assert_not_contains!(output.stderr(), "V8 code cache hit");
|
||||
assert_contains!(output.stderr(), "Updating V8 code cache");
|
||||
output.skip_stdout_check();
|
||||
}
|
||||
|
||||
// 2nd run with cache.
|
||||
{
|
||||
let output = test_context
|
||||
.new_command()
|
||||
.args("run -Ldebug -A main.js")
|
||||
.split_output()
|
||||
.run();
|
||||
assert_contains!(output.stderr(), "V8 code cache hit");
|
||||
assert_not_contains!(output.stderr(), "Updating V8 code cache");
|
||||
output.skip_stdout_check();
|
||||
|
||||
// should have two occurrences of this (one for entrypoint and one for wrapper module)
|
||||
assert_eq!(
|
||||
output
|
||||
.stderr()
|
||||
.split("V8 code cache hit for ES module")
|
||||
.count(),
|
||||
3
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue