Skip to content

Commit a37080a

Browse files
build: add ts support in core modules
1 parent d080801 commit a37080a

File tree

6 files changed

+550
-27
lines changed

6 files changed

+550
-27
lines changed

configure.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1765,7 +1765,8 @@ def gcc_version_ge(version_checked):
17651765
return True
17661766

17671767
def configure_node_lib_files(o):
1768-
o['variables']['node_library_files'] = SearchFiles('lib', 'js')
1768+
o['variables']['node_library_files'] = SearchFiles('lib', 'js') + \
1769+
SearchFiles('lib', 'ts')
17691770

17701771
def configure_node_cctest_sources(o):
17711772
o['variables']['node_cctest_sources'] = [ 'src/node_snapshot_stub.cc' ] + \

node.gyp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,12 +1557,27 @@
15571557
'target_name': 'node_js2c',
15581558
'type': 'executable',
15591559
'toolsets': ['host'],
1560+
'dependencies': [
1561+
'tools/v8_gypfiles/v8.gyp:v8_base_without_compiler',
1562+
'tools/v8_gypfiles/v8.gyp:v8_compiler_for_mksnapshot',
1563+
'tools/v8_gypfiles/v8.gyp:v8_init',
1564+
'tools/v8_gypfiles/v8.gyp:v8_libbase',
1565+
'tools/v8_gypfiles/v8.gyp:v8_libplatform',
1566+
'tools/v8_gypfiles/v8.gyp:v8_maybe_icu',
1567+
'tools/v8_gypfiles/v8.gyp:v8_pch',
1568+
'tools/v8_gypfiles/v8.gyp:fp16',
1569+
'tools/v8_gypfiles/abseil.gyp:abseil',
1570+
],
15601571
'include_dirs': [
1572+
'deps/v8',
1573+
'deps/v8/include',
15611574
'tools',
15621575
'src',
15631576
],
15641577
'sources': [
15651578
'tools/js2c.cc',
1579+
'tools/typescript_transpiler.cc',
1580+
'tools/typescript_transpiler.h',
15661581
'tools/executable_wrapper.h',
15671582
'src/embedded_data.h',
15681583
'src/embedded_data.cc',

src/node_builtins.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,15 @@ static std::string OnDiskFileName(const char* id) {
192192
// V8 tools scripts are .mjs files.
193193
filename += ".mjs";
194194
} else {
195-
filename += ".js";
195+
std::string ts_filename = filename + ".ts";
196+
uv_fs_t req;
197+
int err = uv_fs_access(nullptr, &req, ts_filename.c_str(), 0, nullptr);
198+
uv_fs_req_cleanup(&req);
199+
if (err == 0) {
200+
filename = std::move(ts_filename);
201+
} else {
202+
filename += ".js";
203+
}
196204
}
197205

198206
return filename;

tools/js2c.cc

Lines changed: 78 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "embedded_data.h"
1414
#include "executable_wrapper.h"
1515
#include "simdutf.h"
16+
#include "typescript_transpiler.h"
1617
#include "uv.h"
1718

1819
#if defined(_WIN32)
@@ -131,13 +132,14 @@ bool SearchFiles(const std::string& dir,
131132

132133
constexpr std::string_view kMjsSuffix = ".mjs";
133134
constexpr std::string_view kJsSuffix = ".js";
135+
constexpr std::string_view kTsSuffix = ".ts";
134136
constexpr std::string_view kGypiSuffix = ".gypi";
135137
constexpr std::string_view depsPrefix = "deps/";
136138
constexpr std::string_view libPrefix = "lib/";
137139

138140
constexpr std::string_view HasAllowedExtensions(
139141
const std::string_view filename) {
140-
for (const auto& ext : {kGypiSuffix, kJsSuffix, kMjsSuffix}) {
142+
for (const auto& ext : {kGypiSuffix, kJsSuffix, kMjsSuffix, kTsSuffix}) {
141143
if (filename.ends_with(ext)) {
142144
return ext;
143145
}
@@ -329,11 +331,13 @@ std::string GetFileId(const std::string& filename) {
329331
size_t end = filename.size();
330332
size_t start = 0;
331333
std::string prefix;
332-
// Strip .mjs and .js suffix
334+
// Strip .mjs, .js and .ts suffix
333335
if (filename.ends_with(kMjsSuffix)) {
334336
end -= kMjsSuffix.size();
335337
} else if (filename.ends_with(kJsSuffix)) {
336338
end -= kJsSuffix.size();
339+
} else if (filename.ends_with(kTsSuffix)) {
340+
end -= kTsSuffix.size();
337341
}
338342

339343
// deps/acorn/acorn/dist/acorn.js -> internal/deps/acorn/acorn/dist/acorn
@@ -670,6 +674,7 @@ Fragment GetDefinition(const std::string& var, const std::vector<char>& code) {
670674
}
671675

672676
int AddModule(const std::string& filename,
677+
TypeScriptTranspiler* transpiler,
673678
Fragments* definitions,
674679
Fragments* initializers,
675680
Fragments* registrations) {
@@ -684,6 +689,21 @@ int AddModule(const std::string& filename,
684689
if (error != 0) {
685690
return error;
686691
}
692+
693+
if (filename.ends_with(kTsSuffix)) {
694+
std::vector<char> transpiled;
695+
if (transpiler->Strip(std::string_view(code.data(), code.size()),
696+
filename,
697+
&transpiled) != 0) {
698+
fprintf(stderr,
699+
"Failed to transpile TypeScript file %s: %s\n",
700+
filename.c_str(),
701+
std::string(transpiler->LastError()).c_str());
702+
return 1;
703+
}
704+
code = std::move(transpiled);
705+
}
706+
687707
std::string file_id = GetFileId(filename);
688708
std::string var = GetVariableName(file_id);
689709

@@ -826,23 +846,39 @@ int AddGypi(const std::string& var,
826846

827847
int JS2C(const FileList& js_files,
828848
const FileList& mjs_files,
849+
const FileList& ts_files,
829850
const std::string& config,
851+
const char* argv0,
830852
const std::string& dest) {
853+
TypeScriptTranspiler transpiler;
831854
Fragments definitions;
832-
definitions.reserve(js_files.size() + mjs_files.size() + 1);
855+
definitions.reserve(js_files.size() + mjs_files.size() + ts_files.size() + 1);
833856
Fragments initializers;
834-
initializers.reserve(js_files.size() + mjs_files.size());
857+
initializers.reserve(js_files.size() + mjs_files.size() + ts_files.size());
835858
Fragments registrations;
836-
registrations.reserve(js_files.size() + mjs_files.size() + 1);
859+
registrations.reserve(js_files.size() + mjs_files.size() + ts_files.size() +
860+
1);
837861

838-
for (const auto& filename : js_files) {
839-
int r = AddModule(filename, &definitions, &initializers, &registrations);
840-
if (r != 0) {
841-
return r;
842-
}
862+
if (!ts_files.empty() && transpiler.Initialize(argv0) != 0) {
863+
fprintf(stderr,
864+
"Failed to initialize TypeScript transpiler: %s\n",
865+
std::string(transpiler.LastError()).c_str());
866+
return 1;
843867
}
844-
for (const auto& filename : mjs_files) {
845-
int r = AddModule(filename, &definitions, &initializers, &registrations);
868+
869+
auto add_modules = [&](const FileList& files) {
870+
for (const auto& filename : files) {
871+
int r = AddModule(
872+
filename, &transpiler, &definitions, &initializers, &registrations);
873+
if (r != 0) {
874+
return r;
875+
}
876+
}
877+
return 0;
878+
};
879+
880+
for (const auto* files : {&js_files, &mjs_files, &ts_files}) {
881+
int r = add_modules(*files);
846882
if (r != 0) {
847883
return r;
848884
}
@@ -910,7 +946,8 @@ int Main(int argc, char* argv[]) {
910946
const std::string& file = args[i];
911947
if (IsDirectory(file, &error)) {
912948
if (!SearchFiles(file, &file_map, kJsSuffix) ||
913-
!SearchFiles(file, &file_map, kMjsSuffix)) {
949+
!SearchFiles(file, &file_map, kMjsSuffix) ||
950+
!SearchFiles(file, &file_map, kTsSuffix)) {
914951
return 1;
915952
}
916953
} else if (error != 0) {
@@ -927,8 +964,6 @@ int Main(int argc, char* argv[]) {
927964
}
928965
}
929966

930-
// Should have exactly 3 types: `.js`, `.mjs` and `.gypi`.
931-
assert(file_map.size() == 3);
932967
auto gypi_it = file_map.find(".gypi");
933968
// Currently config.gypi is the only `.gypi` file allowed
934969
if (gypi_it == file_map.end() || gypi_it->second.size() != 1 ||
@@ -940,19 +975,37 @@ int Main(int argc, char* argv[]) {
940975
}
941976
auto js_it = file_map.find(".js");
942977
auto mjs_it = file_map.find(".mjs");
943-
assert(js_it != file_map.end() && mjs_it != file_map.end());
944-
945-
auto it = std::find(mjs_it->second.begin(),
946-
mjs_it->second.end(),
947-
"lib/eslint.config_partial.mjs");
948-
if (it != mjs_it->second.end()) {
949-
mjs_it->second.erase(it);
978+
auto ts_it = file_map.find(".ts");
979+
if (mjs_it != file_map.end()) {
980+
auto it = std::find(mjs_it->second.begin(),
981+
mjs_it->second.end(),
982+
"lib/eslint.config_partial.mjs");
983+
if (it != mjs_it->second.end()) {
984+
mjs_it->second.erase(it);
985+
}
950986
}
951987

952-
std::sort(js_it->second.begin(), js_it->second.end());
953-
std::sort(mjs_it->second.begin(), mjs_it->second.end());
988+
if (js_it != file_map.end()) {
989+
std::sort(js_it->second.begin(), js_it->second.end());
990+
}
991+
if (mjs_it != file_map.end()) {
992+
std::sort(mjs_it->second.begin(), mjs_it->second.end());
993+
}
994+
if (ts_it != file_map.end()) {
995+
std::sort(ts_it->second.begin(), ts_it->second.end());
996+
}
954997

955-
return JS2C(js_it->second, mjs_it->second, gypi_it->second[0], output);
998+
static const FileList empty_list;
999+
const FileList& js_files =
1000+
js_it == file_map.end() ? empty_list : js_it->second;
1001+
const FileList& mjs_files =
1002+
mjs_it == file_map.end() ? empty_list : mjs_it->second;
1003+
return JS2C(js_files,
1004+
mjs_files,
1005+
ts_it == file_map.end() ? empty_list : ts_it->second,
1006+
gypi_it->second[0],
1007+
argv[0],
1008+
output);
9561009
}
9571010
} // namespace js2c
9581011
} // namespace node

0 commit comments

Comments
 (0)