summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/js/compiler/host.ts10
-rw-r--r--cli/js/compiler/sourcefile.ts5
-rw-r--r--cli/js/compiler/util.ts6
-rw-r--r--cli/ops/compiler.rs12
-rw-r--r--cli/tests/integration_tests.rs34
5 files changed, 60 insertions, 7 deletions
diff --git a/cli/js/compiler/host.ts b/cli/js/compiler/host.ts
index 627c52970..457388bd9 100644
--- a/cli/js/compiler/host.ts
+++ b/cli/js/compiler/host.ts
@@ -242,8 +242,16 @@ export class Host implements ts.CompilerHost {
assert(sourceFile != null);
if (!sourceFile.tsSourceFile) {
assert(sourceFile.sourceCode != null);
+ // even though we assert the extension for JSON modules to the compiler
+ // is TypeScript, TypeScript internally analyses the filename for its
+ // extension and tries to parse it as JSON instead of TS. We have to
+ // change the filename to the TypeScript file.
sourceFile.tsSourceFile = ts.createSourceFile(
- fileName.startsWith(ASSETS) ? sourceFile.filename : fileName,
+ fileName.startsWith(ASSETS)
+ ? sourceFile.filename
+ : fileName.toLowerCase().endsWith(".json")
+ ? `${fileName}.ts`
+ : fileName,
sourceFile.sourceCode,
languageVersion
);
diff --git a/cli/js/compiler/sourcefile.ts b/cli/js/compiler/sourcefile.ts
index 159ccda85..e400acbf5 100644
--- a/cli/js/compiler/sourcefile.ts
+++ b/cli/js/compiler/sourcefile.ts
@@ -35,7 +35,10 @@ function getExtension(fileName: string, mediaType: MediaType): ts.Extension {
case MediaType.TSX:
return ts.Extension.Tsx;
case MediaType.Json:
- return ts.Extension.Json;
+ // we internally compile JSON, so what gets provided to the TypeScript
+ // compiler is an ES module, but in order to get TypeScript to handle it
+ // properly we have to pretend it is TS.
+ return ts.Extension.Ts;
case MediaType.Wasm:
// Custom marker for Wasm type.
return ts.Extension.Js;
diff --git a/cli/js/compiler/util.ts b/cli/js/compiler/util.ts
index 09725fc22..8acc83a2d 100644
--- a/cli/js/compiler/util.ts
+++ b/cli/js/compiler/util.ts
@@ -4,7 +4,7 @@ import { bold, cyan, yellow } from "../colors.ts";
import { CompilerOptions } from "./api.ts";
import { buildBundle } from "./bundler.ts";
import { ConfigureResponse, Host } from "./host.ts";
-import { SourceFile } from "./sourcefile.ts";
+import { MediaType, SourceFile } from "./sourcefile.ts";
import { atob, TextEncoder } from "../web/text_encoding.ts";
import * as compilerOps from "../ops/compiler.ts";
import * as util from "../util.ts";
@@ -51,13 +51,13 @@ function cache(
// NOTE: If it's a `.json` file we don't want to write it to disk.
// JSON files are loaded and used by TS compiler to check types, but we don't want
// to emit them to disk because output file is the same as input file.
- if (sf.extension === ts.Extension.Json) {
+ if (sf.mediaType === MediaType.Json) {
return;
}
// NOTE: JavaScript files are only cached to disk if `checkJs`
// option in on
- if (sf.extension === ts.Extension.Js && !checkJs) {
+ if (sf.mediaType === MediaType.JavaScript && !checkJs) {
return;
}
}
diff --git a/cli/ops/compiler.rs b/cli/ops/compiler.rs
index e6ed364da..baa7b4c1c 100644
--- a/cli/ops/compiler.rs
+++ b/cli/ops/compiler.rs
@@ -136,9 +136,9 @@ fn op_fetch_source_files(
}
_ => f,
};
- // Special handling of Wasm files:
+ // Special handling of WASM and JSON files:
// compile them into JS first!
- // This allows TS to do correct export types.
+ // This allows TS to do correct export types as well as bundles.
let source_code = match file.media_type {
msg::MediaType::Wasm => {
global_state
@@ -148,6 +148,14 @@ fn op_fetch_source_files(
.map_err(|e| OpError::other(e.to_string()))?
.code
}
+ msg::MediaType::Json => {
+ global_state
+ .json_compiler
+ .compile(&file)
+ .await
+ .map_err(|e| OpError::other(e.to_string()))?
+ .code
+ }
_ => String::from_utf8(file.source_code).unwrap(),
};
Ok::<_, OpError>(json!({
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index 9cdf0af56..29203d411 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -399,6 +399,40 @@ fn bundle_single_module() {
}
#[test]
+fn bundle_json() {
+ use tempfile::TempDir;
+
+ let json_modules = util::root_path().join("cli/tests/020_json_modules.ts");
+ assert!(json_modules.is_file());
+ let t = TempDir::new().expect("tempdir fail");
+ let bundle = t.path().join("020_json_modules.bundle.js");
+ let mut deno = util::deno_cmd()
+ .current_dir(util::root_path())
+ .arg("bundle")
+ .arg(json_modules)
+ .arg(&bundle)
+ .spawn()
+ .expect("failed to spawn script");
+ let status = deno.wait().expect("failed to wait for the child process");
+ assert!(status.success());
+ assert!(bundle.is_file());
+
+ let output = util::deno_cmd()
+ .current_dir(util::root_path())
+ .arg("run")
+ .arg("--reload")
+ .arg(&bundle)
+ .output()
+ .expect("failed to spawn script");
+ // check the output of the the bundle program.
+ assert!(std::str::from_utf8(&output.stdout)
+ .unwrap()
+ .trim()
+ .ends_with("{\"foo\":{\"bar\":true,\"baz\":[\"qat\",1]}}"));
+ assert_eq!(output.stderr, b"");
+}
+
+#[test]
fn bundle_tla() {
// First we have to generate a bundle of some module that has exports.
let tla_import = util::root_path().join("cli/tests/subdir/tla.ts");