summaryrefslogtreecommitdiff
path: root/cli/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/build.rs')
-rw-r--r--cli/build.rs295
1 files changed, 153 insertions, 142 deletions
diff --git a/cli/build.rs b/cli/build.rs
index 216969e39..e4df856f7 100644
--- a/cli/build.rs
+++ b/cli/build.rs
@@ -1,11 +1,13 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use std::cell::RefCell;
use std::env;
use std::path::PathBuf;
+use std::rc::Rc;
-use deno_core::include_js_files;
use deno_core::snapshot_util::*;
use deno_core::Extension;
+use deno_core::ExtensionBuilder;
use deno_core::ExtensionFileSource;
use deno_core::ExtensionFileSourceCode;
use deno_runtime::deno_cache::SqliteBackedCache;
@@ -33,6 +35,105 @@ mod ts {
specifier: String,
}
+ #[op]
+ fn op_build_info(state: &mut OpState) -> Value {
+ let build_specifier = "asset:///bootstrap.ts";
+
+ let node_built_in_module_names = SUPPORTED_BUILTIN_NODE_MODULES
+ .iter()
+ .map(|s| s.name)
+ .collect::<Vec<&str>>();
+ let build_libs = state.borrow::<Vec<&str>>();
+ json!({
+ "buildSpecifier": build_specifier,
+ "libs": build_libs,
+ "nodeBuiltInModuleNames": node_built_in_module_names,
+ })
+ }
+
+ #[op]
+ fn op_is_node_file() -> bool {
+ false
+ }
+
+ #[op]
+ fn op_script_version(
+ _state: &mut OpState,
+ _args: Value,
+ ) -> Result<Option<String>, AnyError> {
+ Ok(Some("1".to_string()))
+ }
+
+ #[op]
+ // using the same op that is used in `tsc.rs` for loading modules and reading
+ // files, but a slightly different implementation at build time.
+ fn op_load(state: &mut OpState, args: LoadArgs) -> Result<Value, AnyError> {
+ let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
+ let path_dts = state.borrow::<PathBuf>();
+ let re_asset =
+ Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex");
+ let build_specifier = "asset:///bootstrap.ts";
+
+ // we need a basic file to send to tsc to warm it up.
+ if args.specifier == build_specifier {
+ Ok(json!({
+ "data": r#"Deno.writeTextFile("hello.txt", "hello deno!");"#,
+ "version": "1",
+ // this corresponds to `ts.ScriptKind.TypeScript`
+ "scriptKind": 3
+ }))
+ // specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to
+ // parse out just the name so we can lookup the asset.
+ } else if let Some(caps) = re_asset.captures(&args.specifier) {
+ if let Some(lib) = caps.get(1).map(|m| m.as_str()) {
+ // if it comes from an op crate, we were supplied with the path to the
+ // file.
+ let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
+ PathBuf::from(op_crate_lib).canonicalize()?
+ // otherwise we will generate the path ourself
+ } else {
+ path_dts.join(format!("lib.{lib}.d.ts"))
+ };
+ let data = std::fs::read_to_string(path)?;
+ Ok(json!({
+ "data": data,
+ "version": "1",
+ // this corresponds to `ts.ScriptKind.TypeScript`
+ "scriptKind": 3
+ }))
+ } else {
+ Err(custom_error(
+ "InvalidSpecifier",
+ format!("An invalid specifier was requested: {}", args.specifier),
+ ))
+ }
+ } else {
+ Err(custom_error(
+ "InvalidSpecifier",
+ format!("An invalid specifier was requested: {}", args.specifier),
+ ))
+ }
+ }
+
+ deno_core::extension!(deno_tsc,
+ ops = [op_build_info, op_is_node_file, op_load, op_script_version],
+ js = [
+ dir "tsc",
+ "00_typescript.js",
+ "99_main_compiler.js",
+ ],
+ config = {
+ op_crate_libs: HashMap<&'static str, PathBuf>,
+ build_libs: Vec<&'static str>,
+ path_dts: PathBuf,
+ },
+ state = |state, op_crate_libs, build_libs, path_dts| {
+ state.put(op_crate_libs);
+ state.put(build_libs);
+ state.put(path_dts);
+ },
+ );
+
pub fn create_compiler_snapshot(snapshot_path: PathBuf, cwd: &Path) {
// libs that are being provided by op crates.
let mut op_crate_libs = HashMap::new();
@@ -158,110 +259,15 @@ mod ts {
)
.unwrap();
- #[op]
- fn op_build_info(state: &mut OpState) -> Value {
- let build_specifier = "asset:///bootstrap.ts";
-
- let node_built_in_module_names = SUPPORTED_BUILTIN_NODE_MODULES
- .iter()
- .map(|s| s.name)
- .collect::<Vec<&str>>();
- let build_libs = state.borrow::<Vec<&str>>();
- json!({
- "buildSpecifier": build_specifier,
- "libs": build_libs,
- "nodeBuiltInModuleNames": node_built_in_module_names,
- })
- }
-
- #[op]
- fn op_is_node_file() -> bool {
- false
- }
-
- #[op]
- fn op_script_version(
- _state: &mut OpState,
- _args: Value,
- ) -> Result<Option<String>, AnyError> {
- Ok(Some("1".to_string()))
- }
-
- #[op]
- // using the same op that is used in `tsc.rs` for loading modules and reading
- // files, but a slightly different implementation at build time.
- fn op_load(state: &mut OpState, args: LoadArgs) -> Result<Value, AnyError> {
- let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
- let path_dts = state.borrow::<PathBuf>();
- let re_asset =
- Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex");
- let build_specifier = "asset:///bootstrap.ts";
-
- // we need a basic file to send to tsc to warm it up.
- if args.specifier == build_specifier {
- Ok(json!({
- "data": r#"Deno.writeTextFile("hello.txt", "hello deno!");"#,
- "version": "1",
- // this corresponds to `ts.ScriptKind.TypeScript`
- "scriptKind": 3
- }))
- // specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to
- // parse out just the name so we can lookup the asset.
- } else if let Some(caps) = re_asset.captures(&args.specifier) {
- if let Some(lib) = caps.get(1).map(|m| m.as_str()) {
- // if it comes from an op crate, we were supplied with the path to the
- // file.
- let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
- PathBuf::from(op_crate_lib).canonicalize()?
- // otherwise we are will generate the path ourself
- } else {
- path_dts.join(format!("lib.{lib}.d.ts"))
- };
- let data = std::fs::read_to_string(path)?;
- Ok(json!({
- "data": data,
- "version": "1",
- // this corresponds to `ts.ScriptKind.TypeScript`
- "scriptKind": 3
- }))
- } else {
- Err(custom_error(
- "InvalidSpecifier",
- format!("An invalid specifier was requested: {}", args.specifier),
- ))
- }
- } else {
- Err(custom_error(
- "InvalidSpecifier",
- format!("An invalid specifier was requested: {}", args.specifier),
- ))
- }
- }
-
- let tsc_extension = Extension::builder("deno_tsc")
- .ops(vec![
- op_build_info::decl(),
- op_is_node_file::decl(),
- op_load::decl(),
- op_script_version::decl(),
- ])
- .js(include_js_files! {
- dir "tsc",
- "00_typescript.js",
- "99_main_compiler.js",
- })
- .state(move |state| {
- state.put(op_crate_libs.clone());
- state.put(build_libs.clone());
- state.put(path_dts.clone());
- })
- .build();
-
create_snapshot(CreateSnapshotOptions {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
snapshot_path,
startup_snapshot: None,
- extensions: vec![tsc_extension],
+ extensions: vec![deno_tsc::init_ops_and_esm(
+ op_crate_libs,
+ build_libs,
+ path_dts,
+ )],
// NOTE(bartlomieju): Compressing the TSC snapshot in debug build took
// ~45s on M1 MacBook Pro; without compression it took ~1s.
@@ -304,61 +310,66 @@ mod ts {
}
}
+// FIXME(bartlomieju): information about which extensions were
+// already snapshotted is not preserved in the snapshot. This should be
+// fixed, so we can reliably depend on that information.
+// deps = [runtime]
+deno_core::extension!(
+ cli,
+ esm = [
+ dir "js",
+ "40_testing.js"
+ ],
+ customizer = |ext: &mut ExtensionBuilder| {
+ ext.esm(vec![ExtensionFileSource {
+ specifier: "runtime/js/99_main.js".to_string(),
+ code: ExtensionFileSourceCode::LoadedFromFsDuringSnapshot(
+ std::path::PathBuf::from(deno_runtime::js::PATH_FOR_99_MAIN_JS),
+ ),
+ }]);
+ }
+);
+
fn create_cli_snapshot(snapshot_path: PathBuf) {
// NOTE(bartlomieju): ordering is important here, keep it in sync with
// `runtime/worker.rs`, `runtime/web_worker.rs` and `runtime/build.rs`!
- let mut extensions: Vec<Extension> = vec![
- deno_webidl::init(),
- deno_console::init(),
- deno_url::init_ops(),
- deno_web::init_ops::<PermissionsContainer>(
+ let extensions: Vec<Extension> = vec![
+ deno_webidl::deno_webidl::init_ops(),
+ deno_console::deno_console::init_ops(),
+ deno_url::deno_url::init_ops(),
+ deno_web::deno_web::init_ops::<PermissionsContainer>(
deno_web::BlobStore::default(),
Default::default(),
),
- deno_fetch::init_ops::<PermissionsContainer>(Default::default()),
- deno_cache::init_ops::<SqliteBackedCache>(None),
- deno_websocket::init_ops::<PermissionsContainer>("".to_owned(), None, None),
- deno_webstorage::init_ops(None),
- deno_crypto::init_ops(None),
- deno_broadcast_channel::init_ops(
+ deno_fetch::deno_fetch::init_ops::<PermissionsContainer>(Default::default()),
+ deno_cache::deno_cache::init_ops::<SqliteBackedCache>(None),
+ deno_websocket::deno_websocket::init_ops::<PermissionsContainer>(
+ "".to_owned(),
+ None,
+ None,
+ ),
+ deno_webstorage::deno_webstorage::init_ops(None),
+ deno_crypto::deno_crypto::init_ops(None),
+ deno_broadcast_channel::deno_broadcast_channel::init_ops(
deno_broadcast_channel::InMemoryBroadcastChannel::default(),
false, // No --unstable.
),
- deno_ffi::init_ops::<PermissionsContainer>(false),
- deno_net::init_ops::<PermissionsContainer>(
+ deno_ffi::deno_ffi::init_ops::<PermissionsContainer>(false),
+ deno_net::deno_net::init_ops::<PermissionsContainer>(
None, false, // No --unstable.
None,
),
- deno_tls::init_ops(),
- deno_napi::init_ops::<PermissionsContainer>(),
- deno_http::init_ops(),
- deno_io::init_ops(Default::default()),
- deno_fs::init_ops::<PermissionsContainer>(false),
- deno_flash::init_ops::<PermissionsContainer>(false), // No --unstable
- deno_node::init_ops::<PermissionsContainer>(None), // No --unstable.
- deno_node::init_polyfill_ops(),
+ deno_tls::deno_tls::init_ops(),
+ deno_napi::deno_napi::init_ops::<PermissionsContainer>(),
+ deno_http::deno_http::init_ops(),
+ deno_io::deno_io::init_ops(Rc::new(RefCell::new(Some(Default::default())))),
+ deno_fs::deno_fs::init_ops::<PermissionsContainer>(false),
+ deno_flash::deno_flash::init_ops::<PermissionsContainer>(false), // No --unstable
+ deno_node::deno_node_loading::init_ops::<PermissionsContainer>(None), // No --unstable.
+ deno_node::deno_node::init_ops(),
+ cli::init_ops_and_esm(), // NOTE: This needs to be init_ops_and_esm!
];
- let mut esm_files = include_js_files!(
- dir "js",
- "40_testing.js",
- );
- esm_files.push(ExtensionFileSource {
- specifier: "runtime/js/99_main.js".to_string(),
- code: ExtensionFileSourceCode::LoadedFromFsDuringSnapshot(
- std::path::PathBuf::from(deno_runtime::js::PATH_FOR_99_MAIN_JS),
- ),
- });
- extensions.push(
- Extension::builder("cli")
- // FIXME(bartlomieju): information about which extensions were
- // already snapshotted is not preserved in the snapshot. This should be
- // fixed, so we can reliably depend on that information.
- // .dependencies(vec!["runtime"])
- .esm(esm_files)
- .build(),
- );
-
create_snapshot(CreateSnapshotOptions {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
snapshot_path,