mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
module: integrate TypeScript into compile cache
This integrates TypeScript into the compile cache by caching the transpilation (either type-stripping or transforming) output in addition to the V8 code cache that's generated from the transpilation output. Locally this speeds up loading with type stripping of `benchmark/fixtures/strip-types-benchmark.ts` by ~65% and loading with type transforms of `fixtures/transform-types-benchmark.ts` by ~128%. When comparing loading .ts and loading pre-transpiled .js on-disk with the compile cache enabled, previously .ts loaded 46% slower with type-stripping and 66% slower with transforms compared to loading .js files directly. After this patch, .ts loads 12% slower with type-stripping and 22% slower with transforms compared to .js. (Note that the numbers are based on microbenchmark fixtures and do not necessarily represent real-world workloads, though with bigger real-world files, the speed up should be more significant). PR-URL: https://github.com/nodejs/node/pull/56629 Fixes: https://github.com/nodejs/node/issues/54741 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
@@ -22,6 +22,11 @@ const {
|
||||
const { getOptionValue } = require('internal/options');
|
||||
const assert = require('internal/assert');
|
||||
const { Buffer } = require('buffer');
|
||||
const {
|
||||
getCompileCacheEntry,
|
||||
saveCompileCacheEntry,
|
||||
cachedCodeTypes: { kStrippedTypeScript, kTransformedTypeScript, kTransformedTypeScriptWithSourceMaps },
|
||||
} = internalBinding('modules');
|
||||
|
||||
/**
|
||||
* The TypeScript parsing mode, either 'strip-only' or 'transform'.
|
||||
@@ -105,11 +110,19 @@ function stripTypeScriptTypes(code, options = kEmptyObject) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {'strip-only' | 'transform'} TypeScriptMode
|
||||
* @typedef {object} TypeScriptOptions
|
||||
* @property {TypeScriptMode} mode Mode.
|
||||
* @property {boolean} sourceMap Whether to generate source maps.
|
||||
* @property {string|undefined} filename Filename.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Processes TypeScript code by stripping types or transforming.
|
||||
* Handles source maps if needed.
|
||||
* @param {string} code TypeScript code to process.
|
||||
* @param {object} options The configuration object.
|
||||
* @param {TypeScriptOptions} options The configuration object.
|
||||
* @returns {string} The processed code.
|
||||
*/
|
||||
function processTypeScriptCode(code, options) {
|
||||
@@ -126,6 +139,20 @@ function processTypeScriptCode(code, options) {
|
||||
return transformedCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type enum used for compile cache.
|
||||
* @param {TypeScriptMode} mode Mode of transpilation.
|
||||
* @param {boolean} sourceMap Whether source maps are enabled.
|
||||
* @returns {number}
|
||||
*/
|
||||
function getCachedCodeType(mode, sourceMap) {
|
||||
if (mode === 'transform') {
|
||||
if (sourceMap) { return kTransformedTypeScriptWithSourceMaps; }
|
||||
return kTransformedTypeScript;
|
||||
}
|
||||
return kStrippedTypeScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs type-stripping to TypeScript source code internally.
|
||||
* It is used by internal loaders.
|
||||
@@ -142,12 +169,40 @@ function stripTypeScriptModuleTypes(source, filename, emitWarning = true) {
|
||||
if (isUnderNodeModules(filename)) {
|
||||
throw new ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING(filename);
|
||||
}
|
||||
const sourceMap = getOptionValue('--enable-source-maps');
|
||||
|
||||
const mode = getTypeScriptParsingMode();
|
||||
|
||||
// Instead of caching the compile cache status, just go into C++ to fetch it,
|
||||
// as checking process.env equally involves calling into C++ anyway, and
|
||||
// the compile cache can be enabled dynamically.
|
||||
const type = getCachedCodeType(mode, sourceMap);
|
||||
// Get a compile cache entry into the native compile cache store,
|
||||
// keyed by the filename. If the cache can already be loaded on disk,
|
||||
// cached.transpiled contains the cached string. Otherwise we should do
|
||||
// the transpilation and save it in the native store later using
|
||||
// saveCompileCacheEntry().
|
||||
const cached = (filename ? getCompileCacheEntry(source, filename, type) : undefined);
|
||||
if (cached?.transpiled) { // TODO(joyeecheung): return Buffer here.
|
||||
return cached.transpiled;
|
||||
}
|
||||
|
||||
const options = {
|
||||
mode: getTypeScriptParsingMode(),
|
||||
sourceMap: getOptionValue('--enable-source-maps'),
|
||||
mode,
|
||||
sourceMap,
|
||||
filename,
|
||||
};
|
||||
return processTypeScriptCode(source, options);
|
||||
|
||||
const transpiled = processTypeScriptCode(source, options);
|
||||
if (cached) {
|
||||
// cached.external contains a pointer to the native cache entry.
|
||||
// The cached object would be unreachable once it's out of scope,
|
||||
// but the pointer inside cached.external would stay around for reuse until
|
||||
// environment shutdown or when the cache is manually flushed
|
||||
// to disk. Unwrap it in JS before passing into C++ since it's faster.
|
||||
saveCompileCacheEntry(cached.external, transpiled);
|
||||
}
|
||||
return transpiled;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -77,10 +77,27 @@ v8::ScriptCompiler::CachedData* CompileCacheEntry::CopyCache() const {
|
||||
// See comments in CompileCacheHandler::Persist().
|
||||
constexpr uint32_t kCacheMagicNumber = 0x8adfdbb2;
|
||||
|
||||
const char* CompileCacheEntry::type_name() const {
|
||||
switch (type) {
|
||||
case CachedCodeType::kCommonJS:
|
||||
return "CommonJS";
|
||||
case CachedCodeType::kESM:
|
||||
return "ESM";
|
||||
case CachedCodeType::kStrippedTypeScript:
|
||||
return "StrippedTypeScript";
|
||||
case CachedCodeType::kTransformedTypeScript:
|
||||
return "TransformedTypeScript";
|
||||
case CachedCodeType::kTransformedTypeScriptWithSourceMaps:
|
||||
return "TransformedTypeScriptWithSourceMaps";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void CompileCacheHandler::ReadCacheFile(CompileCacheEntry* entry) {
|
||||
Debug("[compile cache] reading cache from %s for %s %s...",
|
||||
entry->cache_filename,
|
||||
entry->type == CachedCodeType::kCommonJS ? "CommonJS" : "ESM",
|
||||
entry->type_name(),
|
||||
entry->source_filename);
|
||||
|
||||
uv_fs_t req;
|
||||
@@ -256,7 +273,8 @@ void CompileCacheHandler::MaybeSaveImpl(CompileCacheEntry* entry,
|
||||
v8::Local<T> func_or_mod,
|
||||
bool rejected) {
|
||||
DCHECK_NOT_NULL(entry);
|
||||
Debug("[compile cache] cache for %s was %s, ",
|
||||
Debug("[compile cache] V8 code cache for %s %s was %s, ",
|
||||
entry->type_name(),
|
||||
entry->source_filename,
|
||||
rejected ? "rejected"
|
||||
: (entry->cache == nullptr) ? "not initialized"
|
||||
@@ -287,6 +305,25 @@ void CompileCacheHandler::MaybeSave(CompileCacheEntry* entry,
|
||||
MaybeSaveImpl(entry, func, rejected);
|
||||
}
|
||||
|
||||
void CompileCacheHandler::MaybeSave(CompileCacheEntry* entry,
|
||||
std::string_view transpiled) {
|
||||
CHECK(entry->type == CachedCodeType::kStrippedTypeScript ||
|
||||
entry->type == CachedCodeType::kTransformedTypeScript ||
|
||||
entry->type == CachedCodeType::kTransformedTypeScriptWithSourceMaps);
|
||||
Debug("[compile cache] saving transpilation cache for %s %s\n",
|
||||
entry->type_name(),
|
||||
entry->source_filename);
|
||||
|
||||
// TODO(joyeecheung): it's weird to copy it again here. Convert the v8::String
|
||||
// directly into buffer held by v8::ScriptCompiler::CachedData here.
|
||||
int cache_size = static_cast<int>(transpiled.size());
|
||||
uint8_t* data = new uint8_t[cache_size];
|
||||
memcpy(data, transpiled.data(), cache_size);
|
||||
entry->cache.reset(new v8::ScriptCompiler::CachedData(
|
||||
data, cache_size, v8::ScriptCompiler::CachedData::BufferOwned));
|
||||
entry->refreshed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist the compile cache accumulated in memory to disk.
|
||||
*
|
||||
@@ -316,18 +353,25 @@ void CompileCacheHandler::Persist() {
|
||||
// incur a negligible overhead from thread synchronization.
|
||||
for (auto& pair : compiler_cache_store_) {
|
||||
auto* entry = pair.second.get();
|
||||
const char* type_name = entry->type_name();
|
||||
if (entry->cache == nullptr) {
|
||||
Debug("[compile cache] skip %s because the cache was not initialized\n",
|
||||
Debug("[compile cache] skip persisting %s %s because the cache was not "
|
||||
"initialized\n",
|
||||
type_name,
|
||||
entry->source_filename);
|
||||
continue;
|
||||
}
|
||||
if (entry->refreshed == false) {
|
||||
Debug("[compile cache] skip %s because cache was the same\n",
|
||||
entry->source_filename);
|
||||
Debug(
|
||||
"[compile cache] skip persisting %s %s because cache was the same\n",
|
||||
type_name,
|
||||
entry->source_filename);
|
||||
continue;
|
||||
}
|
||||
if (entry->persisted == true) {
|
||||
Debug("[compile cache] skip %s because cache was already persisted\n",
|
||||
Debug("[compile cache] skip persisting %s %s because cache was already "
|
||||
"persisted\n",
|
||||
type_name,
|
||||
entry->source_filename);
|
||||
continue;
|
||||
}
|
||||
@@ -363,8 +407,9 @@ void CompileCacheHandler::Persist() {
|
||||
auto cleanup_mkstemp =
|
||||
OnScopeLeave([&mkstemp_req]() { uv_fs_req_cleanup(&mkstemp_req); });
|
||||
std::string cache_filename_tmp = entry->cache_filename + ".XXXXXX";
|
||||
Debug("[compile cache] Creating temporary file for cache of %s...",
|
||||
entry->source_filename);
|
||||
Debug("[compile cache] Creating temporary file for cache of %s (%s)...",
|
||||
entry->source_filename,
|
||||
type_name);
|
||||
int err = uv_fs_mkstemp(
|
||||
nullptr, &mkstemp_req, cache_filename_tmp.c_str(), nullptr);
|
||||
if (err < 0) {
|
||||
@@ -372,8 +417,10 @@ void CompileCacheHandler::Persist() {
|
||||
continue;
|
||||
}
|
||||
Debug(" -> %s\n", mkstemp_req.path);
|
||||
Debug("[compile cache] writing cache for %s to temporary file %s [%d %d %d "
|
||||
Debug("[compile cache] writing cache for %s %s to temporary file %s [%d "
|
||||
"%d %d "
|
||||
"%d %d]...",
|
||||
type_name,
|
||||
entry->source_filename,
|
||||
mkstemp_req.path,
|
||||
headers[kMagicNumberOffset],
|
||||
|
||||
@@ -13,10 +13,17 @@
|
||||
namespace node {
|
||||
class Environment;
|
||||
|
||||
// TODO(joyeecheung): move it into a CacheHandler class.
|
||||
#define CACHED_CODE_TYPES(V) \
|
||||
V(kCommonJS, 0) \
|
||||
V(kESM, 1) \
|
||||
V(kStrippedTypeScript, 2) \
|
||||
V(kTransformedTypeScript, 3) \
|
||||
V(kTransformedTypeScriptWithSourceMaps, 4)
|
||||
|
||||
enum class CachedCodeType : uint8_t {
|
||||
kCommonJS = 0,
|
||||
kESM,
|
||||
#define V(type, value) type = value,
|
||||
CACHED_CODE_TYPES(V)
|
||||
#undef V
|
||||
};
|
||||
|
||||
struct CompileCacheEntry {
|
||||
@@ -34,6 +41,7 @@ struct CompileCacheEntry {
|
||||
// Copy the cache into a new store for V8 to consume. Caller takes
|
||||
// ownership.
|
||||
v8::ScriptCompiler::CachedData* CopyCache() const;
|
||||
const char* type_name() const;
|
||||
};
|
||||
|
||||
#define COMPILE_CACHE_STATUS(V) \
|
||||
@@ -70,6 +78,7 @@ class CompileCacheHandler {
|
||||
void MaybeSave(CompileCacheEntry* entry,
|
||||
v8::Local<v8::Module> mod,
|
||||
bool rejected);
|
||||
void MaybeSave(CompileCacheEntry* entry, std::string_view transpiled);
|
||||
std::string_view cache_dir() { return compile_cache_dir_; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "node_modules.h"
|
||||
#include <cstdio>
|
||||
#include "base_object-inl.h"
|
||||
#include "compile_cache.h"
|
||||
#include "node_errors.h"
|
||||
#include "node_external_reference.h"
|
||||
#include "node_url.h"
|
||||
@@ -21,12 +22,16 @@ namespace modules {
|
||||
|
||||
using v8::Array;
|
||||
using v8::Context;
|
||||
using v8::External;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::HandleScope;
|
||||
using v8::Integer;
|
||||
using v8::Isolate;
|
||||
using v8::Local;
|
||||
using v8::LocalVector;
|
||||
using v8::Name;
|
||||
using v8::NewStringType;
|
||||
using v8::Null;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
using v8::Primitive;
|
||||
@@ -498,6 +503,74 @@ void GetCompileCacheDir(const FunctionCallbackInfo<Value>& args) {
|
||||
.ToLocalChecked());
|
||||
}
|
||||
|
||||
void GetCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
CHECK(args[0]->IsString()); // TODO(joyeecheung): accept buffer.
|
||||
CHECK(args[1]->IsString());
|
||||
CHECK(args[2]->IsUint32());
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
Environment* env = Environment::GetCurrent(context);
|
||||
if (!env->use_compile_cache()) {
|
||||
return;
|
||||
}
|
||||
Local<String> source = args[0].As<String>();
|
||||
Local<String> filename = args[1].As<String>();
|
||||
CachedCodeType type =
|
||||
static_cast<CachedCodeType>(args[2].As<v8::Uint32>()->Value());
|
||||
auto* cache_entry =
|
||||
env->compile_cache_handler()->GetOrInsert(source, filename, type);
|
||||
if (cache_entry == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
v8::LocalVector<v8::Name> names(isolate,
|
||||
{FIXED_ONE_BYTE_STRING(isolate, "external")});
|
||||
v8::LocalVector<v8::Value> values(isolate,
|
||||
{v8::External::New(isolate, cache_entry)});
|
||||
if (cache_entry->cache != nullptr) {
|
||||
Debug(env,
|
||||
DebugCategory::COMPILE_CACHE,
|
||||
"[compile cache] retrieving transpile cache for %s %s...",
|
||||
cache_entry->type_name(),
|
||||
cache_entry->source_filename);
|
||||
|
||||
std::string_view cache(
|
||||
reinterpret_cast<const char*>(cache_entry->cache->data),
|
||||
cache_entry->cache->length);
|
||||
Local<Value> transpiled;
|
||||
// TODO(joyeecheung): convert with simdutf and into external strings
|
||||
if (!ToV8Value(context, cache).ToLocal(&transpiled)) {
|
||||
Debug(env, DebugCategory::COMPILE_CACHE, "failed\n");
|
||||
return;
|
||||
} else {
|
||||
Debug(env, DebugCategory::COMPILE_CACHE, "success\n");
|
||||
}
|
||||
names.push_back(FIXED_ONE_BYTE_STRING(isolate, "transpiled"));
|
||||
values.push_back(transpiled);
|
||||
} else {
|
||||
Debug(env,
|
||||
DebugCategory::COMPILE_CACHE,
|
||||
"[compile cache] no transpile cache for %s %s\n",
|
||||
cache_entry->type_name(),
|
||||
cache_entry->source_filename);
|
||||
}
|
||||
args.GetReturnValue().Set(Object::New(
|
||||
isolate, v8::Null(isolate), names.data(), values.data(), names.size()));
|
||||
}
|
||||
|
||||
void SaveCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
Environment* env = Environment::GetCurrent(context);
|
||||
DCHECK(env->use_compile_cache());
|
||||
CHECK(args[0]->IsExternal());
|
||||
CHECK(args[1]->IsString()); // TODO(joyeecheung): accept buffer.
|
||||
auto* cache_entry =
|
||||
static_cast<CompileCacheEntry*>(args[0].As<External>()->Value());
|
||||
Utf8Value utf8(isolate, args[1].As<String>());
|
||||
env->compile_cache_handler()->MaybeSave(cache_entry, utf8.ToStringView());
|
||||
}
|
||||
|
||||
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
|
||||
Local<ObjectTemplate> target) {
|
||||
Isolate* isolate = isolate_data->isolate();
|
||||
@@ -514,6 +587,8 @@ void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
|
||||
SetMethod(isolate, target, "enableCompileCache", EnableCompileCache);
|
||||
SetMethod(isolate, target, "getCompileCacheDir", GetCompileCacheDir);
|
||||
SetMethod(isolate, target, "flushCompileCache", FlushCompileCache);
|
||||
SetMethod(isolate, target, "getCompileCacheEntry", GetCompileCacheEntry);
|
||||
SetMethod(isolate, target, "saveCompileCacheEntry", SaveCompileCacheEntry);
|
||||
}
|
||||
|
||||
void BindingData::CreatePerContextProperties(Local<Object> target,
|
||||
@@ -530,12 +605,31 @@ void BindingData::CreatePerContextProperties(Local<Object> target,
|
||||
compile_cache_status_values.push_back( \
|
||||
FIXED_ONE_BYTE_STRING(isolate, #status));
|
||||
COMPILE_CACHE_STATUS(V)
|
||||
#undef V
|
||||
|
||||
USE(target->Set(context,
|
||||
FIXED_ONE_BYTE_STRING(isolate, "compileCacheStatus"),
|
||||
Array::New(isolate,
|
||||
compile_cache_status_values.data(),
|
||||
compile_cache_status_values.size())));
|
||||
|
||||
LocalVector<Name> cached_code_type_keys(isolate);
|
||||
LocalVector<Value> cached_code_type_values(isolate);
|
||||
|
||||
#define V(type, value) \
|
||||
cached_code_type_keys.push_back(FIXED_ONE_BYTE_STRING(isolate, #type)); \
|
||||
cached_code_type_values.push_back(Integer::New(isolate, value)); \
|
||||
DCHECK_EQ(value, cached_code_type_values.size() - 1);
|
||||
CACHED_CODE_TYPES(V)
|
||||
#undef V
|
||||
|
||||
USE(target->Set(context,
|
||||
FIXED_ONE_BYTE_STRING(isolate, "cachedCodeTypes"),
|
||||
Object::New(isolate,
|
||||
Null(isolate),
|
||||
cached_code_type_keys.data(),
|
||||
cached_code_type_values.data(),
|
||||
cached_code_type_keys.size())));
|
||||
}
|
||||
|
||||
void BindingData::RegisterExternalReferences(
|
||||
@@ -547,6 +641,8 @@ void BindingData::RegisterExternalReferences(
|
||||
registry->Register(EnableCompileCache);
|
||||
registry->Register(GetCompileCacheDir);
|
||||
registry->Register(FlushCompileCache);
|
||||
registry->Register(GetCompileCacheEntry);
|
||||
registry->Register(SaveCompileCacheEntry);
|
||||
}
|
||||
|
||||
} // namespace modules
|
||||
|
||||
166
test/parallel/test-compile-cache-typescript-commonjs.js
Normal file
166
test/parallel/test-compile-cache-typescript-commonjs.js
Normal file
@@ -0,0 +1,166 @@
|
||||
'use strict';
|
||||
|
||||
// This tests NODE_COMPILE_CACHE works for CommonJS with types.
|
||||
|
||||
require('../common');
|
||||
const { spawnSyncAndAssert } = require('../common/child_process');
|
||||
const assert = require('assert');
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
// Check cache for .ts files that would be run as CommonJS.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = tmpdir.resolve('.compile_cache_dir');
|
||||
const script = fixtures.path('typescript', 'ts', 'test-commonjs-parsing.ts');
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /saving transpilation cache for StrippedTypeScript .*test-commonjs-parsing\.ts/);
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-commonjs-parsing\.ts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-commonjs-parsing\.ts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-commonjs-parsing\.ts.*success/);
|
||||
assert.match(output, /reading cache from .* for CommonJS .*test-commonjs-parsing\.ts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-commonjs-parsing\.ts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for CommonJS .*test-commonjs-parsing\.ts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting CommonJS .*test-commonjs-parsing\.ts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check cache for .cts files that require .cts files.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = tmpdir.resolve('.compile_cache_dir');
|
||||
const script = fixtures.path('typescript', 'cts', 'test-require-commonjs.cts');
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-require-commonjs\.cts.*success/);
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-cts-export-foo\.cts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-require-commonjs\.cts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-cts-export-foo\.cts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-require-commonjs\.cts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-require-commonjs\.cts because cache was the same/);
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-cts-export-foo\.cts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-cts-export-foo\.cts because cache was the same/);
|
||||
|
||||
assert.match(output, /V8 code cache for CommonJS .*test-require-commonjs\.cts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting CommonJS .*test-require-commonjs\.cts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for CommonJS .*test-cts-export-foo\.cts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting CommonJS .*test-cts-export-foo\.cts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check cache for .cts files that require .mts files.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = tmpdir.resolve('.compile_cache_dir');
|
||||
const script = fixtures.path('typescript', 'cts', 'test-require-mts-module.cts');
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-require-mts-module\.cts.*success/);
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-mts-export-foo\.mts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-require-mts-module\.cts.*success/);
|
||||
assert.match(output, /writing cache for ESM .*test-mts-export-foo\.mts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-require-mts-module\.cts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-require-mts-module\.cts because cache was the same/);
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-mts-export-foo\.mts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-mts-export-foo\.mts because cache was the same/);
|
||||
|
||||
assert.match(output, /V8 code cache for CommonJS .*test-require-mts-module\.cts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting CommonJS .*test-require-mts-module\.cts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for ESM .*test-mts-export-foo\.mts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting ESM .*test-mts-export-foo\.mts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
167
test/parallel/test-compile-cache-typescript-esm.js
Normal file
167
test/parallel/test-compile-cache-typescript-esm.js
Normal file
@@ -0,0 +1,167 @@
|
||||
'use strict';
|
||||
|
||||
// This tests NODE_COMPILE_CACHE works for ESM with types.
|
||||
|
||||
require('../common');
|
||||
const { spawnSyncAndAssert } = require('../common/child_process');
|
||||
const assert = require('assert');
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
// Check cache for .ts files that would be run as ESM.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = tmpdir.resolve('.compile_cache_dir');
|
||||
const script = fixtures.path('typescript', 'ts', 'test-module-typescript.ts');
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /saving transpilation cache for StrippedTypeScript .*test-module-typescript\.ts/);
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-module-typescript\.ts.*success/);
|
||||
assert.match(output, /writing cache for ESM .*test-module-typescript\.ts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-module-typescript\.ts.*success/);
|
||||
assert.match(output, /reading cache from .* for ESM .*test-module-typescript\.ts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-module-typescript\.ts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for ESM .*test-module-typescript\.ts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting ESM .*test-module-typescript\.ts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check cache for .mts files that import .mts files.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = tmpdir.resolve('.compile_cache_dir');
|
||||
const script = fixtures.path('typescript', 'mts', 'test-import-module.mts');
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-import-module\.mts.*success/);
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-mts-export-foo\.mts.*success/);
|
||||
assert.match(output, /writing cache for ESM .*test-import-module\.mts.*success/);
|
||||
assert.match(output, /writing cache for ESM .*test-mts-export-foo\.mts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-import-module\.mts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-import-module\.mts because cache was the same/);
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-mts-export-foo\.mts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-mts-export-foo\.mts because cache was the same/);
|
||||
|
||||
assert.match(output, /V8 code cache for ESM .*test-import-module\.mts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting ESM .*test-import-module\.mts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for ESM .*test-mts-export-foo\.mts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting ESM .*test-mts-export-foo\.mts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Check cache for .mts files that import .cts files.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = tmpdir.resolve('.compile_cache_dir');
|
||||
const script = fixtures.path('typescript', 'mts', 'test-import-commonjs.mts');
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-import-commonjs\.mts.*success/);
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-cts-export-foo\.cts.*success/);
|
||||
assert.match(output, /writing cache for ESM .*test-import-commonjs\.mts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-cts-export-foo\.cts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-import-commonjs\.mts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-import-commonjs\.mts because cache was the same/);
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-cts-export-foo\.cts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-cts-export-foo\.cts because cache was the same/);
|
||||
|
||||
assert.match(output, /V8 code cache for ESM .*test-import-commonjs\.mts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting ESM .*test-import-commonjs\.mts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for CommonJS .*test-cts-export-foo\.cts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting CommonJS .*test-cts-export-foo\.cts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
104
test/parallel/test-compile-cache-typescript-strip-miss.js
Normal file
104
test/parallel/test-compile-cache-typescript-strip-miss.js
Normal file
@@ -0,0 +1,104 @@
|
||||
'use strict';
|
||||
|
||||
// This tests NODE_COMPILE_CACHE can handle cache invalidation
|
||||
// between strip-only TypeScript and transformed TypeScript.
|
||||
|
||||
require('../common');
|
||||
const { spawnSyncAndAssert } = require('../common/child_process');
|
||||
const assert = require('assert');
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
tmpdir.refresh();
|
||||
const dir = tmpdir.resolve('.compile_cache_dir');
|
||||
const script = fixtures.path('typescript', 'ts', 'test-typescript.ts');
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /saving transpilation cache for StrippedTypeScript .*test-typescript\.ts/);
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-typescript\.ts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-typescript\.ts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Reloading with transform should miss the cache generated without transform.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
['--experimental-transform-types', script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
// Both the transpile cache and the code cache should be missed.
|
||||
assert.match(output, /no transpile cache for TransformedTypeScriptWithSourceMaps .*test-typescript\.ts/);
|
||||
assert.match(output, /reading cache from .* for CommonJS .*test-typescript\.ts.*mismatch/);
|
||||
// New cache with source map should be generated.
|
||||
assert.match(output, /writing cache for TransformedTypeScriptWithSourceMaps .*test-typescript\.ts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-typescript\.ts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Reloading with transform should hit the cache generated with transform.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
['--experimental-transform-types', script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for TransformedTypeScriptWithSourceMaps .*test-typescript\.ts.*success/);
|
||||
assert.match(output, /reading cache from .* for CommonJS .*test-typescript\.ts.*success/);
|
||||
assert.match(output, /skip persisting TransformedTypeScriptWithSourceMaps .*test-typescript\.ts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for CommonJS .*test-typescript\.ts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting CommonJS .*test-typescript\.ts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Reloading without transform should hit the co-existing transpile cache generated without transform,
|
||||
// but miss the code cache generated with transform.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-typescript\.ts.*success/);
|
||||
assert.match(output, /reading cache from .* for CommonJS .*test-typescript\.ts.*mismatch/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-typescript\.ts because cache was the same/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-typescript\.ts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
// This tests NODE_COMPILE_CACHE can be used for type stripping and ignores
|
||||
// --enable-source-maps as there's no difference in the code generated.
|
||||
|
||||
require('../common');
|
||||
const { spawnSyncAndAssert } = require('../common/child_process');
|
||||
const assert = require('assert');
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
tmpdir.refresh();
|
||||
const dir = tmpdir.resolve('.compile_cache_dir');
|
||||
const script = fixtures.path('typescript', 'ts', 'test-typescript.ts');
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /saving transpilation cache for StrippedTypeScript .*test-typescript\.ts/);
|
||||
assert.match(output, /writing cache for StrippedTypeScript .*test-typescript\.ts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-typescript\.ts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Reloading with source maps should hit the cache generated without source maps, because for
|
||||
// type stripping, only sourceURL is added regardless of whether source map is enabled.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
['--enable-source-maps', script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
// Both the transpile cache and the code cache should be missed.
|
||||
assert.match(output, /retrieving transpile cache for StrippedTypeScript .*test-typescript\.ts.*success/);
|
||||
assert.match(output, /reading cache from .* for CommonJS .*test-typescript\.ts.*success/);
|
||||
assert.match(output, /skip persisting StrippedTypeScript .*test-typescript\.ts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for CommonJS .*test-typescript\.ts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting CommonJS .*test-typescript\.ts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
127
test/parallel/test-compile-cache-typescript-transform.js
Normal file
127
test/parallel/test-compile-cache-typescript-transform.js
Normal file
@@ -0,0 +1,127 @@
|
||||
'use strict';
|
||||
|
||||
// This tests NODE_COMPILE_CACHE works with --experimental-transform-types.
|
||||
|
||||
require('../common');
|
||||
const { spawnSyncAndAssert } = require('../common/child_process');
|
||||
const assert = require('assert');
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
|
||||
tmpdir.refresh();
|
||||
const dir = tmpdir.resolve('.compile_cache_dir');
|
||||
const script = fixtures.path('typescript', 'ts', 'transformation', 'test-enum.ts');
|
||||
|
||||
// Check --experimental-transform-types which enables source maps by default.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
['--experimental-transform-types', script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /saving transpilation cache for TransformedTypeScriptWithSourceMaps .*test-enum\.ts/);
|
||||
assert.match(output, /writing cache for TransformedTypeScriptWithSourceMaps .*test-enum\.ts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-enum\.ts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
['--experimental-transform-types', script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for TransformedTypeScriptWithSourceMaps .*test-enum\.ts.*success/);
|
||||
assert.match(output, /reading cache from .* for CommonJS .*test-enum\.ts.*success/);
|
||||
assert.match(output, /skip persisting TransformedTypeScriptWithSourceMaps .*test-enum\.ts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for CommonJS .*test-enum\.ts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting CommonJS .*test-enum\.ts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Reloading without source maps should miss the cache generated with source maps.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
['--experimental-transform-types', '--no-enable-source-maps', script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
// Both the transpile cache and the code cache should be missed.
|
||||
assert.match(output, /no transpile cache for TransformedTypeScript .*test-enum\.ts/);
|
||||
assert.match(output, /reading cache from .* for CommonJS .*test-enum\.ts.*mismatch/);
|
||||
// New cache without source map should be generated.
|
||||
assert.match(output, /writing cache for TransformedTypeScript .*test-enum\.ts.*success/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-enum\.ts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Reloading without source maps again should hit the cache generated without source maps.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
['--experimental-transform-types', '--no-enable-source-maps', script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for TransformedTypeScript .*test-enum\.ts.*success/);
|
||||
assert.match(output, /reading cache from .* for CommonJS .*test-enum\.ts.*success/);
|
||||
assert.match(output, /skip persisting TransformedTypeScript .*test-enum\.ts because cache was the same/);
|
||||
assert.match(output, /V8 code cache for CommonJS .*test-enum\.ts was accepted, keeping the in-memory entry/);
|
||||
assert.match(output, /skip persisting CommonJS .*test-enum\.ts because cache was the same/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Reloading with source maps again should hit the co-existing transpile cache with source
|
||||
// maps, but miss the code cache generated without source maps.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
['--experimental-transform-types', script],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
|
||||
NODE_COMPILE_CACHE: dir
|
||||
},
|
||||
cwd: tmpdir.path
|
||||
},
|
||||
{
|
||||
stderr(output) {
|
||||
assert.match(output, /retrieving transpile cache for TransformedTypeScriptWithSourceMaps .*test-enum\.ts.*success/);
|
||||
assert.match(output, /reading cache from .* for CommonJS .*test-enum\.ts.*mismatch/);
|
||||
assert.match(output, /skip persisting TransformedTypeScriptWithSourceMaps .*test-enum\.ts because cache was the same/);
|
||||
assert.match(output, /writing cache for CommonJS .*test-enum\.ts.*success/);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user