summaryrefslogtreecommitdiff
path: root/cli/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/build.rs')
-rw-r--r--cli/build.rs169
1 files changed, 138 insertions, 31 deletions
diff --git a/cli/build.rs b/cli/build.rs
index 4819988e9..657041132 100644
--- a/cli/build.rs
+++ b/cli/build.rs
@@ -1,9 +1,13 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-mod op_fetch_asset;
-
+use deno_core::error::custom_error;
+use deno_core::json_op_sync;
+use deno_core::serde_json;
+use deno_core::serde_json::json;
use deno_core::JsRuntime;
use deno_core::RuntimeOptions;
+use regex::Regex;
+use serde::Deserialize;
use std::collections::HashMap;
use std::env;
use std::path::Path;
@@ -46,46 +50,149 @@ fn create_runtime_snapshot(snapshot_path: &Path, files: Vec<PathBuf>) {
create_snapshot(js_runtime, snapshot_path, files);
}
+#[derive(Debug, Deserialize)]
+struct LoadArgs {
+ /// The fully qualified specifier that should be loaded.
+ specifier: String,
+}
+
fn create_compiler_snapshot(
snapshot_path: &Path,
files: Vec<PathBuf>,
cwd: &Path,
) {
- let mut custom_libs: HashMap<String, PathBuf> = HashMap::new();
- custom_libs
- .insert("lib.deno.web.d.ts".to_string(), deno_web::get_declaration());
- custom_libs.insert(
- "lib.deno.fetch.d.ts".to_string(),
- deno_fetch::get_declaration(),
- );
- custom_libs.insert(
- "lib.deno.window.d.ts".to_string(),
- cwd.join("dts/lib.deno.window.d.ts"),
- );
- custom_libs.insert(
- "lib.deno.worker.d.ts".to_string(),
- cwd.join("dts/lib.deno.worker.d.ts"),
- );
- custom_libs.insert(
- "lib.deno.shared_globals.d.ts".to_string(),
- cwd.join("dts/lib.deno.shared_globals.d.ts"),
- );
- custom_libs.insert(
- "lib.deno.ns.d.ts".to_string(),
- cwd.join("dts/lib.deno.ns.d.ts"),
- );
- custom_libs.insert(
- "lib.deno.unstable.d.ts".to_string(),
- cwd.join("dts/lib.deno.unstable.d.ts"),
- );
+ // libs that are being provided by op crates.
+ let mut op_crate_libs = HashMap::new();
+ op_crate_libs.insert("deno.web", deno_web::get_declaration());
+ op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration());
+
+ // ensure we invalidate the build properly.
+ for (_, path) in op_crate_libs.iter() {
+ println!("cargo:rerun-if-changed={}", path.display());
+ }
+
+ // libs that should be loaded into the isolate before snapshotting.
+ let libs = vec![
+ // Deno custom type libraries
+ "deno.window",
+ "deno.worker",
+ "deno.shared_globals",
+ "deno.ns",
+ "deno.unstable",
+ // Deno built-in type libraries
+ "es5",
+ "es2015.collection",
+ "es2015.core",
+ "es2015",
+ "es2015.generator",
+ "es2015.iterable",
+ "es2015.promise",
+ "es2015.proxy",
+ "es2015.reflect",
+ "es2015.symbol",
+ "es2015.symbol.wellknown",
+ "es2016.array.include",
+ "es2016",
+ "es2017",
+ "es2017.intl",
+ "es2017.object",
+ "es2017.sharedmemory",
+ "es2017.string",
+ "es2017.typedarrays",
+ "es2018.asyncgenerator",
+ "es2018.asynciterable",
+ "es2018",
+ "es2018.intl",
+ "es2018.promise",
+ "es2018.regexp",
+ "es2019.array",
+ "es2019",
+ "es2019.object",
+ "es2019.string",
+ "es2019.symbol",
+ "es2020.bigint",
+ "es2020",
+ "es2020.intl",
+ "es2020.promise",
+ "es2020.string",
+ "es2020.symbol.wellknown",
+ "esnext",
+ "esnext.intl",
+ "esnext.promise",
+ "esnext.string",
+ "esnext.weakref",
+ ];
+
+ // create a copy of the vector that includes any op crate libs to be passed
+ // to the JavaScript compiler to build into the snapshot
+ let mut build_libs = libs.clone();
+ for (op_lib, _) in op_crate_libs.iter() {
+ build_libs.push(op_lib.to_owned());
+ }
+
+ let re_asset = Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex");
+ let path_dts = cwd.join("dts");
+ let build_specifier = "asset:///bootstrap.ts";
let mut js_runtime = JsRuntime::new(RuntimeOptions {
will_snapshot: true,
..Default::default()
});
js_runtime.register_op(
- "op_fetch_asset",
- op_fetch_asset::op_fetch_asset(custom_libs),
+ "op_build_info",
+ json_op_sync(move |_state, _args, _bufs| {
+ Ok(json!({
+ "buildSpecifier": build_specifier,
+ "libs": build_libs,
+ }))
+ }),
+ );
+ // using the same op that is used in `tsc.rs` for loading modules and reading
+ // files, but a slightly different implementation at build time.
+ js_runtime.register_op(
+ "op_load",
+ json_op_sync(move |_state, args, _bufs| {
+ let v: LoadArgs = serde_json::from_value(args)?;
+ // we need a basic file to send to tsc to warm it up.
+ if v.specifier == build_specifier {
+ Ok(json!({
+ "data": r#"console.log("hello deno!");"#,
+ "hash": "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(&v.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) {
+ op_crate_lib.clone()
+ // otherwise we are will generate the path ourself
+ } else {
+ path_dts.join(format!("lib.{}.d.ts", lib))
+ };
+ let data = std::fs::read_to_string(path)?;
+ Ok(json!({
+ "data": data,
+ "hash": "1",
+ // this corresponds to `ts.ScriptKind.TypeScript`
+ "scriptKind": 3
+ }))
+ } else {
+ Err(custom_error(
+ "InvalidSpecifier",
+ format!("An invalid specifier was requested: {}", v.specifier),
+ ))
+ }
+ } else {
+ Err(custom_error(
+ "InvalidSpecifier",
+ format!("An invalid specifier was requested: {}", v.specifier),
+ ))
+ }
+ }),
);
create_snapshot(js_runtime, snapshot_path, files);
}