mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
perf(node): ensure cjs wrapper module has deterministic output (#24248)
This commit is contained in:
parent
7b5c514763
commit
cba212b9c6
2 changed files with 72 additions and 62 deletions
|
@ -1,5 +1,6 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use std::collections::BTreeSet;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -106,7 +107,8 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
|
||||||
.to_string(),
|
.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() {
|
if !analysis.reexports.is_empty() {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
@ -159,7 +161,7 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
|
||||||
&'a self,
|
&'a self,
|
||||||
entry_specifier: &url::Url,
|
entry_specifier: &url::Url,
|
||||||
reexports: Vec<String>,
|
reexports: Vec<String>,
|
||||||
all_exports: &mut HashSet<String>,
|
all_exports: &mut BTreeSet<String>,
|
||||||
// this goes through the modules concurrently, so collect
|
// this goes through the modules concurrently, so collect
|
||||||
// the errors in order to be deterministic
|
// the errors in order to be deterministic
|
||||||
errors: &mut Vec<anyhow::Error>,
|
errors: &mut Vec<anyhow::Error>,
|
||||||
|
|
|
@ -5043,8 +5043,8 @@ fn run_etag_delete_source_cache() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn code_cache_test() {
|
fn code_cache_test() {
|
||||||
let deno_dir = TempDir::new();
|
|
||||||
let test_context = TestContextBuilder::new().use_temp_cwd().build();
|
let test_context = TestContextBuilder::new().use_temp_cwd().build();
|
||||||
|
let deno_dir = test_context.deno_dir();
|
||||||
let temp_dir = test_context.temp_dir();
|
let temp_dir = test_context.temp_dir();
|
||||||
temp_dir.write("main.js", "console.log('Hello World - A');");
|
temp_dir.write("main.js", "console.log('Hello World - A');");
|
||||||
|
|
||||||
|
@ -5052,17 +5052,14 @@ fn code_cache_test() {
|
||||||
{
|
{
|
||||||
let output = test_context
|
let output = test_context
|
||||||
.new_command()
|
.new_command()
|
||||||
.env("DENO_DIR", deno_dir.path())
|
.args("run -Ldebug main.js")
|
||||||
.arg("run")
|
|
||||||
.arg("-Ldebug")
|
|
||||||
.arg("main.js")
|
|
||||||
.split_output()
|
.split_output()
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
output
|
output
|
||||||
.assert_stdout_matches_text("Hello World - A[WILDCARD]")
|
.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_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.
|
// Check that the code cache database exists.
|
||||||
let code_cache_path = deno_dir.path().join(CODE_CACHE_DB_FILE_NAME);
|
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
|
let output = test_context
|
||||||
.new_command()
|
.new_command()
|
||||||
.env("DENO_DIR", deno_dir.path())
|
.args("run -Ldebug main.js")
|
||||||
.arg("run")
|
|
||||||
.arg("-Ldebug")
|
|
||||||
.arg("main.js")
|
|
||||||
.split_output()
|
.split_output()
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
output
|
output
|
||||||
.assert_stdout_matches_text("Hello World - A[WILDCARD]")
|
.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_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.
|
// Rerun with --no-code-cache.
|
||||||
{
|
{
|
||||||
let output = test_context
|
let output = test_context
|
||||||
.new_command()
|
.new_command()
|
||||||
.env("DENO_DIR", deno_dir.path())
|
.args("run -Ldebug --no-code-cache main.js")
|
||||||
.arg("run")
|
|
||||||
.arg("-Ldebug")
|
|
||||||
.arg("--no-code-cache")
|
|
||||||
.arg("main.js")
|
|
||||||
.split_output()
|
.split_output()
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
output
|
output
|
||||||
.assert_stdout_matches_text("Hello World - A[WILDCARD]")
|
.assert_stdout_matches_text("Hello World - A[WILDCARD]")
|
||||||
.skip_stderr_check();
|
.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.
|
// Modify the script, and make sure that the cache is rejected.
|
||||||
|
@ -5109,27 +5099,21 @@ fn code_cache_test() {
|
||||||
{
|
{
|
||||||
let output = test_context
|
let output = test_context
|
||||||
.new_command()
|
.new_command()
|
||||||
.env("DENO_DIR", deno_dir.path())
|
.args("run -Ldebug main.js")
|
||||||
.arg("run")
|
|
||||||
.arg("-Ldebug")
|
|
||||||
.arg("main.js")
|
|
||||||
.split_output()
|
.split_output()
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
output
|
output
|
||||||
.assert_stdout_matches_text("Hello World - B[WILDCARD]")
|
.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_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]
|
#[test]
|
||||||
fn code_cache_npm_test() {
|
fn code_cache_npm_test() {
|
||||||
let deno_dir = TempDir::new();
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
||||||
let test_context = TestContextBuilder::new()
|
let deno_dir = test_context.deno_dir();
|
||||||
.use_temp_cwd()
|
|
||||||
.use_http_server()
|
|
||||||
.build();
|
|
||||||
let temp_dir = test_context.temp_dir();
|
let temp_dir = test_context.temp_dir();
|
||||||
temp_dir.write(
|
temp_dir.write(
|
||||||
"main.js",
|
"main.js",
|
||||||
|
@ -5140,12 +5124,7 @@ fn code_cache_npm_test() {
|
||||||
{
|
{
|
||||||
let output = test_context
|
let output = test_context
|
||||||
.new_command()
|
.new_command()
|
||||||
.env("DENO_DIR", deno_dir.path())
|
.args("run -Ldebug -A main.js")
|
||||||
.envs(env_vars_for_npm_tests())
|
|
||||||
.arg("run")
|
|
||||||
.arg("-Ldebug")
|
|
||||||
.arg("-A")
|
|
||||||
.arg("main.js")
|
|
||||||
.split_output()
|
.split_output()
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
|
@ -5153,7 +5132,7 @@ fn code_cache_npm_test() {
|
||||||
.assert_stdout_matches_text("Hello World[WILDCARD]")
|
.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]/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_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.
|
// Check that the code cache database exists.
|
||||||
let code_cache_path = deno_dir.path().join(CODE_CACHE_DB_FILE_NAME);
|
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
|
let output = test_context
|
||||||
.new_command()
|
.new_command()
|
||||||
.env("DENO_DIR", deno_dir.path())
|
.args("run -Ldebug -A main.js")
|
||||||
.envs(env_vars_for_npm_tests())
|
|
||||||
.arg("run")
|
|
||||||
.arg("-Ldebug")
|
|
||||||
.arg("-A")
|
|
||||||
.arg("main.js")
|
|
||||||
.split_output()
|
.split_output()
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
|
@ -5177,17 +5151,14 @@ fn code_cache_npm_test() {
|
||||||
.assert_stdout_matches_text("Hello World[WILDCARD]")
|
.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]/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_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]
|
#[test]
|
||||||
fn code_cache_npm_with_require_test() {
|
fn code_cache_npm_with_require_test() {
|
||||||
let deno_dir = TempDir::new();
|
let test_context = TestContextBuilder::for_npm().use_temp_cwd().build();
|
||||||
let test_context = TestContextBuilder::new()
|
let deno_dir = test_context.deno_dir();
|
||||||
.use_temp_cwd()
|
|
||||||
.use_http_server()
|
|
||||||
.build();
|
|
||||||
let temp_dir = test_context.temp_dir();
|
let temp_dir = test_context.temp_dir();
|
||||||
temp_dir.write(
|
temp_dir.write(
|
||||||
"main.js",
|
"main.js",
|
||||||
|
@ -5198,12 +5169,7 @@ fn code_cache_npm_with_require_test() {
|
||||||
{
|
{
|
||||||
let output = test_context
|
let output = test_context
|
||||||
.new_command()
|
.new_command()
|
||||||
.env("DENO_DIR", deno_dir.path())
|
.args("run -Ldebug -A main.js")
|
||||||
.envs(env_vars_for_npm_tests())
|
|
||||||
.arg("run")
|
|
||||||
.arg("-Ldebug")
|
|
||||||
.arg("-A")
|
|
||||||
.arg("main.js")
|
|
||||||
.split_output()
|
.split_output()
|
||||||
.run();
|
.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 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]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD]")
|
||||||
.assert_stderr_matches_text("[WILDCARD]Updating V8 code cache for script: file:///[WILDCARD]/browserslist/[WILDCARD]/index.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.
|
// Check that the code cache database exists.
|
||||||
let code_cache_path = deno_dir.path().join(CODE_CACHE_DB_FILE_NAME);
|
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
|
let output = test_context
|
||||||
.new_command()
|
.new_command()
|
||||||
.env("DENO_DIR", deno_dir.path())
|
.args("run -Ldebug -A main.js")
|
||||||
.envs(env_vars_for_npm_tests())
|
|
||||||
.arg("run")
|
|
||||||
.arg("-Ldebug")
|
|
||||||
.arg("-A")
|
|
||||||
.arg("main.js")
|
|
||||||
.split_output()
|
.split_output()
|
||||||
.run();
|
.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 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]/autoprefixer/[WILDCARD]/autoprefixer.js[WILDCARD]")
|
||||||
.assert_stderr_matches_text("[WILDCARD]V8 code cache hit for script: file:///[WILDCARD]/browserslist/[WILDCARD]/index.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