mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
parent
034ab48086
commit
57e95032c8
59 changed files with 886 additions and 67 deletions
70
Cargo.lock
generated
70
Cargo.lock
generated
|
@ -212,6 +212,12 @@ dependencies = [
|
||||||
"safemem",
|
"safemem",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "build_const"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.4.0"
|
version = "3.4.0"
|
||||||
|
@ -315,6 +321,15 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
||||||
|
dependencies = [
|
||||||
|
"build_const",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -430,6 +445,7 @@ dependencies = [
|
||||||
"semver-parser 0.9.0",
|
"semver-parser 0.9.0",
|
||||||
"serde",
|
"serde",
|
||||||
"sourcemap",
|
"sourcemap",
|
||||||
|
"swc_bundler",
|
||||||
"swc_common",
|
"swc_common",
|
||||||
"swc_ecmascript",
|
"swc_ecmascript",
|
||||||
"sys-info",
|
"sys-info",
|
||||||
|
@ -661,6 +677,12 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fixedbitset"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.17"
|
version = "1.0.17"
|
||||||
|
@ -1475,6 +1497,16 @@ version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "petgraph"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
|
||||||
|
dependencies = [
|
||||||
|
"fixedbitset",
|
||||||
|
"indexmap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf"
|
name = "phf"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
@ -1638,6 +1670,12 @@ dependencies = [
|
||||||
"proc-macro2 1.0.21",
|
"proc-macro2 1.0.21",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radix_fmt"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
|
@ -1828,6 +1866,12 @@ version = "0.6.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "relative-path"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65aff7c83039e88c1c0b4bedf8dfa93d6ec84d5fc2945b37c1fa4186f46c5f94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "remove_dir_all"
|
name = "remove_dir_all"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
@ -2225,6 +2269,32 @@ dependencies = [
|
||||||
"string_cache_codegen",
|
"string_cache_codegen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "swc_bundler"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5dabc79c5bf47498e16a01134846fbb677dd9c7233c591710587d76bd30cbe02"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"crc",
|
||||||
|
"indexmap",
|
||||||
|
"is-macro",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"petgraph",
|
||||||
|
"radix_fmt",
|
||||||
|
"relative-path",
|
||||||
|
"retain_mut",
|
||||||
|
"swc_atoms",
|
||||||
|
"swc_common",
|
||||||
|
"swc_ecma_ast",
|
||||||
|
"swc_ecma_codegen",
|
||||||
|
"swc_ecma_parser",
|
||||||
|
"swc_ecma_transforms",
|
||||||
|
"swc_ecma_utils",
|
||||||
|
"swc_ecma_visit",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_common"
|
name = "swc_common"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
|
|
|
@ -61,6 +61,7 @@ rustyline-derive = "0.3.1"
|
||||||
serde = { version = "1.0.116", features = ["derive"] }
|
serde = { version = "1.0.116", features = ["derive"] }
|
||||||
sys-info = "0.7.0"
|
sys-info = "0.7.0"
|
||||||
sourcemap = "6.0.1"
|
sourcemap = "6.0.1"
|
||||||
|
swc_bundler = "=0.11.3"
|
||||||
swc_common = { version = "=0.10.4", features = ["sourcemap"] }
|
swc_common = { version = "=0.10.4", features = ["sourcemap"] }
|
||||||
swc_ecmascript = { version = "=0.10.1", features = ["codegen", "dep_graph", "parser", "react", "transforms", "visit"] }
|
swc_ecmascript = { version = "=0.10.1", features = ["codegen", "dep_graph", "parser", "react", "transforms", "visit"] }
|
||||||
tempfile = "3.1.0"
|
tempfile = "3.1.0"
|
||||||
|
|
136
cli/ast.rs
136
cli/ast.rs
|
@ -1,13 +1,14 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use crate::media_type::MediaType;
|
use crate::media_type::MediaType;
|
||||||
|
use crate::tsc_config;
|
||||||
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::serde_json;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::result;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
use swc_common::chain;
|
use swc_common::chain;
|
||||||
|
@ -21,6 +22,7 @@ use swc_common::errors::HandlerFlags;
|
||||||
use swc_common::FileName;
|
use swc_common::FileName;
|
||||||
use swc_common::Globals;
|
use swc_common::Globals;
|
||||||
use swc_common::Loc;
|
use swc_common::Loc;
|
||||||
|
use swc_common::SourceFile;
|
||||||
use swc_common::SourceMap;
|
use swc_common::SourceMap;
|
||||||
use swc_common::Span;
|
use swc_common::Span;
|
||||||
use swc_ecmascript::ast::Module;
|
use swc_ecmascript::ast::Module;
|
||||||
|
@ -38,13 +40,11 @@ use swc_ecmascript::parser::TsConfig;
|
||||||
use swc_ecmascript::transforms::fixer;
|
use swc_ecmascript::transforms::fixer;
|
||||||
use swc_ecmascript::transforms::helpers;
|
use swc_ecmascript::transforms::helpers;
|
||||||
use swc_ecmascript::transforms::pass::Optional;
|
use swc_ecmascript::transforms::pass::Optional;
|
||||||
use swc_ecmascript::transforms::proposals::decorators;
|
use swc_ecmascript::transforms::proposals;
|
||||||
use swc_ecmascript::transforms::react;
|
use swc_ecmascript::transforms::react;
|
||||||
use swc_ecmascript::transforms::typescript;
|
use swc_ecmascript::transforms::typescript;
|
||||||
use swc_ecmascript::visit::FoldWith;
|
use swc_ecmascript::visit::FoldWith;
|
||||||
|
|
||||||
type Result<V> = result::Result<V, AnyError>;
|
|
||||||
|
|
||||||
static TARGET: JscTarget = JscTarget::Es2020;
|
static TARGET: JscTarget = JscTarget::Es2020;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
@ -173,7 +173,10 @@ pub fn get_syntax(media_type: &MediaType) -> Syntax {
|
||||||
|
|
||||||
/// Options which can be adjusted when transpiling a module.
|
/// Options which can be adjusted when transpiling a module.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TranspileOptions {
|
pub struct EmitOptions {
|
||||||
|
/// Indicate if JavaScript is being checked/transformed as well, or if it is
|
||||||
|
/// only TypeScript.
|
||||||
|
pub check_js: bool,
|
||||||
/// When emitting a legacy decorator, also emit experimental decorator meta
|
/// When emitting a legacy decorator, also emit experimental decorator meta
|
||||||
/// data. Defaults to `false`.
|
/// data. Defaults to `false`.
|
||||||
pub emit_metadata: bool,
|
pub emit_metadata: bool,
|
||||||
|
@ -190,9 +193,10 @@ pub struct TranspileOptions {
|
||||||
pub transform_jsx: bool,
|
pub transform_jsx: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TranspileOptions {
|
impl Default for EmitOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
TranspileOptions {
|
EmitOptions {
|
||||||
|
check_js: false,
|
||||||
emit_metadata: false,
|
emit_metadata: false,
|
||||||
inline_source_map: true,
|
inline_source_map: true,
|
||||||
jsx_factory: "React.createElement".into(),
|
jsx_factory: "React.createElement".into(),
|
||||||
|
@ -202,6 +206,21 @@ impl Default for TranspileOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<tsc_config::TsConfig> for EmitOptions {
|
||||||
|
fn from(config: tsc_config::TsConfig) -> Self {
|
||||||
|
let options: tsc_config::EmitConfigOptions =
|
||||||
|
serde_json::from_value(config.0).unwrap();
|
||||||
|
EmitOptions {
|
||||||
|
check_js: options.check_js,
|
||||||
|
emit_metadata: options.emit_decorator_metadata,
|
||||||
|
inline_source_map: true,
|
||||||
|
jsx_factory: options.jsx_factory,
|
||||||
|
jsx_fragment_factory: options.jsx_fragment_factory,
|
||||||
|
transform_jsx: options.jsx == "react",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A logical structure to hold the value of a parsed module for further
|
/// A logical structure to hold the value of a parsed module for further
|
||||||
/// processing.
|
/// processing.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -245,8 +264,8 @@ impl ParsedModule {
|
||||||
/// The result is a tuple of the code and optional source map as strings.
|
/// The result is a tuple of the code and optional source map as strings.
|
||||||
pub fn transpile(
|
pub fn transpile(
|
||||||
self,
|
self,
|
||||||
options: &TranspileOptions,
|
options: &EmitOptions,
|
||||||
) -> Result<(String, Option<String>)> {
|
) -> Result<(String, Option<String>), AnyError> {
|
||||||
let program = Program::Module(self.module);
|
let program = Program::Module(self.module);
|
||||||
|
|
||||||
let jsx_pass = react::react(
|
let jsx_pass = react::react(
|
||||||
|
@ -263,7 +282,7 @@ impl ParsedModule {
|
||||||
);
|
);
|
||||||
let mut passes = chain!(
|
let mut passes = chain!(
|
||||||
Optional::new(jsx_pass, options.transform_jsx),
|
Optional::new(jsx_pass, options.transform_jsx),
|
||||||
decorators::decorators(decorators::Config {
|
proposals::decorators::decorators(proposals::decorators::Config {
|
||||||
legacy: true,
|
legacy: true,
|
||||||
emit_metadata: options.emit_metadata
|
emit_metadata: options.emit_metadata
|
||||||
}),
|
}),
|
||||||
|
@ -329,7 +348,7 @@ pub fn parse(
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
source: &str,
|
source: &str,
|
||||||
media_type: &MediaType,
|
media_type: &MediaType,
|
||||||
) -> Result<ParsedModule> {
|
) -> Result<ParsedModule, AnyError> {
|
||||||
let source_map = SourceMap::default();
|
let source_map = SourceMap::default();
|
||||||
let source_file = source_map.new_source_file(
|
let source_file = source_map.new_source_file(
|
||||||
FileName::Custom(specifier.to_string()),
|
FileName::Custom(specifier.to_string()),
|
||||||
|
@ -372,6 +391,95 @@ pub fn parse(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A low level function which transpiles a source module into an swc
|
||||||
|
/// SourceFile.
|
||||||
|
pub fn transpile_module(
|
||||||
|
filename: &str,
|
||||||
|
src: &str,
|
||||||
|
media_type: &MediaType,
|
||||||
|
emit_options: &EmitOptions,
|
||||||
|
cm: Rc<SourceMap>,
|
||||||
|
) -> Result<(Rc<SourceFile>, Module), AnyError> {
|
||||||
|
// TODO(@kitsonk) DRY-up with ::parse()
|
||||||
|
let error_buffer = ErrorBuffer::new();
|
||||||
|
let handler = Handler::with_emitter_and_flags(
|
||||||
|
Box::new(error_buffer.clone()),
|
||||||
|
HandlerFlags {
|
||||||
|
can_emit_warnings: true,
|
||||||
|
dont_buffer_diagnostics: true,
|
||||||
|
..HandlerFlags::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let comments = SingleThreadedComments::default();
|
||||||
|
let syntax = get_syntax(media_type);
|
||||||
|
let source_file =
|
||||||
|
cm.new_source_file(FileName::Custom(filename.to_string()), src.to_string());
|
||||||
|
let lexer = Lexer::new(
|
||||||
|
syntax,
|
||||||
|
TARGET,
|
||||||
|
StringInput::from(&*source_file),
|
||||||
|
Some(&comments),
|
||||||
|
);
|
||||||
|
let mut parser = swc_ecmascript::parser::Parser::new_from(lexer);
|
||||||
|
let sm = cm.clone();
|
||||||
|
let module = parser.parse_module().map_err(move |err| {
|
||||||
|
let mut diagnostic = err.into_diagnostic(&handler);
|
||||||
|
diagnostic.emit();
|
||||||
|
|
||||||
|
DiagnosticBuffer::from_error_buffer(error_buffer, |span| {
|
||||||
|
sm.lookup_char_pos(span.lo)
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
// TODO(@kitsonk) DRY-up with ::transpile()
|
||||||
|
let jsx_pass = react::react(
|
||||||
|
cm,
|
||||||
|
Some(&comments),
|
||||||
|
react::Options {
|
||||||
|
pragma: emit_options.jsx_factory.clone(),
|
||||||
|
pragma_frag: emit_options.jsx_fragment_factory.clone(),
|
||||||
|
// this will use `Object.assign()` instead of the `_extends` helper
|
||||||
|
// when spreading props.
|
||||||
|
use_builtins: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let mut passes = chain!(
|
||||||
|
Optional::new(jsx_pass, emit_options.transform_jsx),
|
||||||
|
proposals::decorators::decorators(proposals::decorators::Config {
|
||||||
|
legacy: true,
|
||||||
|
emit_metadata: emit_options.emit_metadata
|
||||||
|
}),
|
||||||
|
typescript::strip(),
|
||||||
|
fixer(Some(&comments)),
|
||||||
|
);
|
||||||
|
let module = module.fold_with(&mut passes);
|
||||||
|
|
||||||
|
Ok((source_file, module))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BundleHook;
|
||||||
|
|
||||||
|
impl swc_bundler::Hook for BundleHook {
|
||||||
|
fn get_import_meta_url(
|
||||||
|
&self,
|
||||||
|
span: swc_common::Span,
|
||||||
|
file: &swc_common::FileName,
|
||||||
|
) -> Result<Option<swc_ecmascript::ast::Expr>, AnyError> {
|
||||||
|
// we use custom file names, and swc "wraps" these in `<` and `>` so, we
|
||||||
|
// want to strip those back out.
|
||||||
|
let mut value = file.to_string();
|
||||||
|
value.pop();
|
||||||
|
value.remove(0);
|
||||||
|
Ok(Some(swc_ecmascript::ast::Expr::Lit(
|
||||||
|
swc_ecmascript::ast::Lit::Str(swc_ecmascript::ast::Str {
|
||||||
|
span,
|
||||||
|
value: value.into(),
|
||||||
|
has_escape: false,
|
||||||
|
}),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -436,7 +544,7 @@ mod tests {
|
||||||
let module = parse(&specifier, source, &MediaType::TypeScript)
|
let module = parse(&specifier, source, &MediaType::TypeScript)
|
||||||
.expect("could not parse module");
|
.expect("could not parse module");
|
||||||
let (code, maybe_map) = module
|
let (code, maybe_map) = module
|
||||||
.transpile(&TranspileOptions::default())
|
.transpile(&EmitOptions::default())
|
||||||
.expect("could not strip types");
|
.expect("could not strip types");
|
||||||
assert!(code.starts_with("var D;\n(function(D) {\n"));
|
assert!(code.starts_with("var D;\n(function(D) {\n"));
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -460,7 +568,7 @@ mod tests {
|
||||||
let module = parse(&specifier, source, &MediaType::TSX)
|
let module = parse(&specifier, source, &MediaType::TSX)
|
||||||
.expect("could not parse module");
|
.expect("could not parse module");
|
||||||
let (code, _) = module
|
let (code, _) = module
|
||||||
.transpile(&TranspileOptions::default())
|
.transpile(&EmitOptions::default())
|
||||||
.expect("could not strip types");
|
.expect("could not strip types");
|
||||||
assert!(code.contains("React.createElement(\"div\", null"));
|
assert!(code.contains("React.createElement(\"div\", null"));
|
||||||
}
|
}
|
||||||
|
@ -491,7 +599,7 @@ mod tests {
|
||||||
let module = parse(&specifier, source, &MediaType::TypeScript)
|
let module = parse(&specifier, source, &MediaType::TypeScript)
|
||||||
.expect("could not parse module");
|
.expect("could not parse module");
|
||||||
let (code, _) = module
|
let (code, _) = module
|
||||||
.transpile(&TranspileOptions::default())
|
.transpile(&EmitOptions::default())
|
||||||
.expect("could not strip types");
|
.expect("could not strip types");
|
||||||
assert!(code.contains("_applyDecoratedDescriptor("));
|
assert!(code.contains("_applyDecoratedDescriptor("));
|
||||||
}
|
}
|
||||||
|
|
38
cli/flags.rs
38
cli/flags.rs
|
@ -402,14 +402,7 @@ fn install_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bundle_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
fn bundle_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||||
// TODO(nayeemrmn): Replace the next couple lines with `compile_args_parse()`
|
compile_args_parse(flags, matches);
|
||||||
// once `deno bundle --no-check` is supported.
|
|
||||||
importmap_arg_parse(flags, matches);
|
|
||||||
no_remote_arg_parse(flags, matches);
|
|
||||||
config_arg_parse(flags, matches);
|
|
||||||
reload_arg_parse(flags, matches);
|
|
||||||
lock_args_parse(flags, matches);
|
|
||||||
ca_file_arg_parse(flags, matches);
|
|
||||||
|
|
||||||
let source_file = matches.value_of("source_file").unwrap().to_string();
|
let source_file = matches.value_of("source_file").unwrap().to_string();
|
||||||
|
|
||||||
|
@ -776,16 +769,7 @@ These must be added to the path manually if required.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bundle_subcommand<'a, 'b>() -> App<'a, 'b> {
|
fn bundle_subcommand<'a, 'b>() -> App<'a, 'b> {
|
||||||
SubCommand::with_name("bundle")
|
compile_args(SubCommand::with_name("bundle"))
|
||||||
// TODO(nayeemrmn): Replace the next couple lines with `compile_args()` once
|
|
||||||
// `deno bundle --no-check` is supported.
|
|
||||||
.arg(importmap_arg())
|
|
||||||
.arg(no_remote_arg())
|
|
||||||
.arg(config_arg())
|
|
||||||
.arg(reload_arg())
|
|
||||||
.arg(lock_arg())
|
|
||||||
.arg(lock_write_arg())
|
|
||||||
.arg(ca_file_arg())
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("source_file")
|
Arg::with_name("source_file")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
|
@ -2353,6 +2337,24 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bundle_nocheck() {
|
||||||
|
let r =
|
||||||
|
flags_from_vec_safe(svec!["deno", "bundle", "--no-check", "script.ts"])
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
r,
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Bundle {
|
||||||
|
source_file: "script.ts".to_string(),
|
||||||
|
out_file: None,
|
||||||
|
},
|
||||||
|
no_check: true,
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn run_importmap() {
|
fn run_importmap() {
|
||||||
let r = flags_from_vec_safe(svec![
|
let r = flags_from_vec_safe(svec![
|
||||||
|
|
37
cli/main.rs
37
cli/main.rs
|
@ -65,6 +65,7 @@ use crate::fs as deno_fs;
|
||||||
use crate::media_type::MediaType;
|
use crate::media_type::MediaType;
|
||||||
use crate::permissions::Permissions;
|
use crate::permissions::Permissions;
|
||||||
use crate::program_state::ProgramState;
|
use crate::program_state::ProgramState;
|
||||||
|
use crate::specifier_handler::FetchHandler;
|
||||||
use crate::worker::MainWorker;
|
use crate::worker::MainWorker;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::future::FutureExt;
|
use deno_core::futures::future::FutureExt;
|
||||||
|
@ -304,7 +305,7 @@ async fn bundle_command(
|
||||||
let module_specifier = ModuleSpecifier::resolve_url_or_path(&source_file)?;
|
let module_specifier = ModuleSpecifier::resolve_url_or_path(&source_file)?;
|
||||||
|
|
||||||
debug!(">>>>> bundle START");
|
debug!(">>>>> bundle START");
|
||||||
let program_state = ProgramState::new(flags)?;
|
let program_state = ProgramState::new(flags.clone())?;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
|
@ -312,10 +313,36 @@ async fn bundle_command(
|
||||||
module_specifier.to_string()
|
module_specifier.to_string()
|
||||||
);
|
);
|
||||||
|
|
||||||
let output = program_state
|
let output = if flags.no_check {
|
||||||
.ts_compiler
|
let handler = Rc::new(RefCell::new(FetchHandler::new(
|
||||||
.bundle(&program_state, module_specifier)
|
&program_state,
|
||||||
.await?;
|
Permissions::allow_all(),
|
||||||
|
)?));
|
||||||
|
let mut builder = module_graph2::GraphBuilder2::new(
|
||||||
|
handler,
|
||||||
|
program_state.maybe_import_map.clone(),
|
||||||
|
);
|
||||||
|
builder.insert(&module_specifier).await?;
|
||||||
|
let graph = builder.get_graph(&program_state.lockfile)?;
|
||||||
|
|
||||||
|
let (s, stats, maybe_ignored_options) =
|
||||||
|
graph.bundle(module_graph2::BundleOptions {
|
||||||
|
debug: flags.log_level == Some(Level::Debug),
|
||||||
|
maybe_config_path: flags.config_path,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if let Some(ignored_options) = maybe_ignored_options {
|
||||||
|
eprintln!("{}", ignored_options);
|
||||||
|
}
|
||||||
|
debug!("{}", stats);
|
||||||
|
|
||||||
|
s
|
||||||
|
} else {
|
||||||
|
program_state
|
||||||
|
.ts_compiler
|
||||||
|
.bundle(&program_state, module_specifier)
|
||||||
|
.await?
|
||||||
|
};
|
||||||
|
|
||||||
debug!(">>>>> bundle END");
|
debug!(">>>>> bundle END");
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use crate::ast;
|
|
||||||
use crate::ast::parse;
|
use crate::ast::parse;
|
||||||
|
use crate::ast::transpile_module;
|
||||||
|
use crate::ast::BundleHook;
|
||||||
|
use crate::ast::EmitOptions;
|
||||||
use crate::ast::Location;
|
use crate::ast::Location;
|
||||||
use crate::ast::ParsedModule;
|
use crate::ast::ParsedModule;
|
||||||
use crate::import_map::ImportMap;
|
use crate::import_map::ImportMap;
|
||||||
|
@ -21,6 +23,7 @@ use crate::tsc_config::TsConfig;
|
||||||
use crate::version;
|
use crate::version;
|
||||||
use crate::AnyError;
|
use crate::AnyError;
|
||||||
|
|
||||||
|
use deno_core::error::Context;
|
||||||
use deno_core::futures::stream::FuturesUnordered;
|
use deno_core::futures::stream::FuturesUnordered;
|
||||||
use deno_core::futures::stream::StreamExt;
|
use deno_core::futures::stream::StreamExt;
|
||||||
use deno_core::serde_json::json;
|
use deno_core::serde_json::json;
|
||||||
|
@ -38,7 +41,6 @@ use std::rc::Rc;
|
||||||
use std::result;
|
use std::result;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use swc_ecmascript::dep_graph::DependencyKind;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Matched the `@deno-types` pragma.
|
/// Matched the `@deno-types` pragma.
|
||||||
|
@ -108,6 +110,59 @@ impl fmt::Display for GraphError {
|
||||||
|
|
||||||
impl Error for GraphError {}
|
impl Error for GraphError {}
|
||||||
|
|
||||||
|
/// A structure for handling bundle loading, which is implemented here, to
|
||||||
|
/// avoid a circular dependency with `ast`.
|
||||||
|
struct BundleLoader<'a> {
|
||||||
|
cm: Rc<swc_common::SourceMap>,
|
||||||
|
graph: &'a Graph2,
|
||||||
|
emit_options: &'a EmitOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> BundleLoader<'a> {
|
||||||
|
pub fn new(
|
||||||
|
graph: &'a Graph2,
|
||||||
|
emit_options: &'a EmitOptions,
|
||||||
|
cm: Rc<swc_common::SourceMap>,
|
||||||
|
) -> Self {
|
||||||
|
BundleLoader {
|
||||||
|
cm,
|
||||||
|
graph,
|
||||||
|
emit_options,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl swc_bundler::Load for BundleLoader<'_> {
|
||||||
|
fn load(
|
||||||
|
&self,
|
||||||
|
file: &swc_common::FileName,
|
||||||
|
) -> Result<(Rc<swc_common::SourceFile>, swc_ecmascript::ast::Module), AnyError>
|
||||||
|
{
|
||||||
|
match file {
|
||||||
|
swc_common::FileName::Custom(filename) => {
|
||||||
|
let specifier = ModuleSpecifier::resolve_url_or_path(filename)
|
||||||
|
.context("Failed to convert swc FileName to ModuleSpecifier.")?;
|
||||||
|
if let Some(src) = self.graph.get_source(&specifier) {
|
||||||
|
let media_type = self
|
||||||
|
.graph
|
||||||
|
.get_media_type(&specifier)
|
||||||
|
.context("Looking up media type during bundling.")?;
|
||||||
|
transpile_module(
|
||||||
|
filename,
|
||||||
|
&src,
|
||||||
|
&media_type,
|
||||||
|
self.emit_options,
|
||||||
|
self.cm.clone(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Err(MissingDependency(specifier, "<bundle>".to_string()).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!("Received request for unsupported filename {:?}", file),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An enum which represents the parsed out values of references in source code.
|
/// An enum which represents the parsed out values of references in source code.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
enum TypeScriptReference {
|
enum TypeScriptReference {
|
||||||
|
@ -273,10 +328,9 @@ impl Module {
|
||||||
|
|
||||||
// Parse out all the syntactical dependencies for a module
|
// Parse out all the syntactical dependencies for a module
|
||||||
let dependencies = parsed_module.analyze_dependencies();
|
let dependencies = parsed_module.analyze_dependencies();
|
||||||
for desc in dependencies
|
for desc in dependencies.iter().filter(|desc| {
|
||||||
.iter()
|
desc.kind != swc_ecmascript::dep_graph::DependencyKind::Require
|
||||||
.filter(|desc| desc.kind != DependencyKind::Require)
|
}) {
|
||||||
{
|
|
||||||
let location = Location {
|
let location = Location {
|
||||||
filename: self.specifier.to_string(),
|
filename: self.specifier.to_string(),
|
||||||
col: desc.col,
|
col: desc.col,
|
||||||
|
@ -301,8 +355,8 @@ impl Module {
|
||||||
.dependencies
|
.dependencies
|
||||||
.entry(desc.specifier.to_string())
|
.entry(desc.specifier.to_string())
|
||||||
.or_default();
|
.or_default();
|
||||||
if desc.kind == DependencyKind::ExportType
|
if desc.kind == swc_ecmascript::dep_graph::DependencyKind::ExportType
|
||||||
|| desc.kind == DependencyKind::ImportType
|
|| desc.kind == swc_ecmascript::dep_graph::DependencyKind::ImportType
|
||||||
{
|
{
|
||||||
dep.maybe_type = Some(specifier);
|
dep.maybe_type = Some(specifier);
|
||||||
} else {
|
} else {
|
||||||
|
@ -392,6 +446,12 @@ impl fmt::Display for Stats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct BundleOptions {
|
||||||
|
pub debug: bool,
|
||||||
|
pub maybe_config_path: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
/// A structure which provides options when transpiling modules.
|
/// A structure which provides options when transpiling modules.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct TranspileOptions {
|
pub struct TranspileOptions {
|
||||||
|
@ -431,6 +491,76 @@ impl Graph2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transform the module graph into a single JavaScript module which is
|
||||||
|
/// returned as a `String` in the result.
|
||||||
|
pub fn bundle(
|
||||||
|
&self,
|
||||||
|
options: BundleOptions,
|
||||||
|
) -> Result<(String, Stats, Option<IgnoredCompilerOptions>), AnyError> {
|
||||||
|
if self.roots.is_empty() || self.roots.len() > 1 {
|
||||||
|
return Err(NotSupported(format!("Bundling is only supported when there is a single root module in the graph. Found: {}", self.roots.len())).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
let root_specifier = self.roots[0].clone();
|
||||||
|
let mut ts_config = TsConfig::new(json!({
|
||||||
|
"checkJs": false,
|
||||||
|
"emitDecoratorMetadata": false,
|
||||||
|
"jsx": "react",
|
||||||
|
"jsxFactory": "React.createElement",
|
||||||
|
"jsxFragmentFactory": "React.Fragment",
|
||||||
|
}));
|
||||||
|
let maybe_ignored_options =
|
||||||
|
ts_config.merge_user_config(options.maybe_config_path)?;
|
||||||
|
let emit_options: EmitOptions = ts_config.into();
|
||||||
|
let cm = Rc::new(swc_common::SourceMap::new(
|
||||||
|
swc_common::FilePathMapping::empty(),
|
||||||
|
));
|
||||||
|
let loader = BundleLoader::new(self, &emit_options, cm.clone());
|
||||||
|
let hook = Box::new(BundleHook);
|
||||||
|
let globals = swc_common::Globals::new();
|
||||||
|
let bundler = swc_bundler::Bundler::new(
|
||||||
|
&globals,
|
||||||
|
cm.clone(),
|
||||||
|
loader,
|
||||||
|
self,
|
||||||
|
swc_bundler::Config::default(),
|
||||||
|
hook,
|
||||||
|
);
|
||||||
|
let mut entries = HashMap::new();
|
||||||
|
entries.insert(
|
||||||
|
"bundle".to_string(),
|
||||||
|
swc_common::FileName::Custom(root_specifier.to_string()),
|
||||||
|
);
|
||||||
|
let output = bundler
|
||||||
|
.bundle(entries)
|
||||||
|
.context("Unable to output bundle during Graph2::bundle().")?;
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
{
|
||||||
|
let mut emitter = swc_ecmascript::codegen::Emitter {
|
||||||
|
cfg: swc_ecmascript::codegen::Config { minify: false },
|
||||||
|
cm: cm.clone(),
|
||||||
|
comments: None,
|
||||||
|
wr: Box::new(swc_ecmascript::codegen::text_writer::JsWriter::new(
|
||||||
|
cm, "\n", &mut buf, None,
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
|
||||||
|
emitter
|
||||||
|
.emit_module(&output[0].module)
|
||||||
|
.context("Unable to emit bundle during Graph2::bundle().")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let s = String::from_utf8(buf)
|
||||||
|
.context("Emitted bundle is an invalid utf-8 string.")?;
|
||||||
|
let stats = Stats(vec![
|
||||||
|
("Files".to_string(), self.modules.len() as u128),
|
||||||
|
("Total time".to_string(), start.elapsed().as_millis()),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Ok((s, stats, maybe_ignored_options))
|
||||||
|
}
|
||||||
|
|
||||||
fn contains_module(&self, specifier: &ModuleSpecifier) -> bool {
|
fn contains_module(&self, specifier: &ModuleSpecifier) -> bool {
|
||||||
let s = self.resolve_specifier(specifier);
|
let s = self.resolve_specifier(specifier);
|
||||||
self.modules.contains_key(s)
|
self.modules.contains_key(s)
|
||||||
|
@ -725,16 +855,7 @@ impl Graph2 {
|
||||||
let maybe_ignored_options =
|
let maybe_ignored_options =
|
||||||
ts_config.merge_user_config(options.maybe_config_path)?;
|
ts_config.merge_user_config(options.maybe_config_path)?;
|
||||||
|
|
||||||
let compiler_options = ts_config.as_transpile_config()?;
|
let emit_options: EmitOptions = ts_config.clone().into();
|
||||||
let check_js = compiler_options.check_js;
|
|
||||||
let transform_jsx = compiler_options.jsx == "react";
|
|
||||||
let emit_options = ast::TranspileOptions {
|
|
||||||
emit_metadata: compiler_options.emit_decorator_metadata,
|
|
||||||
inline_source_map: true,
|
|
||||||
jsx_factory: compiler_options.jsx_factory,
|
|
||||||
jsx_fragment_factory: compiler_options.jsx_fragment_factory,
|
|
||||||
transform_jsx,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut emit_count: u128 = 0;
|
let mut emit_count: u128 = 0;
|
||||||
for (_, module) in self.modules.iter_mut() {
|
for (_, module) in self.modules.iter_mut() {
|
||||||
|
@ -748,7 +869,7 @@ impl Graph2 {
|
||||||
}
|
}
|
||||||
// if we don't have check_js enabled, we won't touch non TypeScript
|
// if we don't have check_js enabled, we won't touch non TypeScript
|
||||||
// modules
|
// modules
|
||||||
if !(check_js
|
if !(emit_options.check_js
|
||||||
|| module.media_type == MediaType::TSX
|
|| module.media_type == MediaType::TSX
|
||||||
|| module.media_type == MediaType::TypeScript)
|
|| module.media_type == MediaType::TypeScript)
|
||||||
{
|
{
|
||||||
|
@ -781,6 +902,27 @@ impl Graph2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl swc_bundler::Resolve for Graph2 {
|
||||||
|
fn resolve(
|
||||||
|
&self,
|
||||||
|
referrer: &swc_common::FileName,
|
||||||
|
specifier: &str,
|
||||||
|
) -> Result<swc_common::FileName, AnyError> {
|
||||||
|
let referrer = if let swc_common::FileName::Custom(referrer) = referrer {
|
||||||
|
ModuleSpecifier::resolve_url_or_path(referrer)
|
||||||
|
.context("Cannot resolve swc FileName to a module specifier")?
|
||||||
|
} else {
|
||||||
|
unreachable!(
|
||||||
|
"An unexpected referrer was passed when bundling: {:?}",
|
||||||
|
referrer
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let specifier = self.resolve(specifier, &referrer)?;
|
||||||
|
|
||||||
|
Ok(swc_common::FileName::Custom(specifier.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A structure for building a dependency graph of modules.
|
/// A structure for building a dependency graph of modules.
|
||||||
pub struct GraphBuilder2 {
|
pub struct GraphBuilder2 {
|
||||||
fetched: HashSet<ModuleSpecifier>,
|
fetched: HashSet<ModuleSpecifier>,
|
||||||
|
@ -1094,6 +1236,50 @@ pub mod tests {
|
||||||
assert_eq!(module.maybe_version, expected);
|
assert_eq!(module.maybe_version, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_graph_bundle() {
|
||||||
|
let tests = vec![
|
||||||
|
("file:///tests/fixture01.ts", "fixture01.out"),
|
||||||
|
("file:///tests/fixture02.ts", "fixture02.out"),
|
||||||
|
("file:///tests/fixture03.ts", "fixture03.out"),
|
||||||
|
("file:///tests/fixture04.ts", "fixture04.out"),
|
||||||
|
("file:///tests/fixture05.ts", "fixture05.out"),
|
||||||
|
("file:///tests/fixture06.ts", "fixture06.out"),
|
||||||
|
("file:///tests/fixture07.ts", "fixture07.out"),
|
||||||
|
("file:///tests/fixture08.ts", "fixture08.out"),
|
||||||
|
("file:///tests/fixture09.ts", "fixture09.out"),
|
||||||
|
("file:///tests/fixture10.ts", "fixture10.out"),
|
||||||
|
("file:///tests/fixture11.ts", "fixture11.out"),
|
||||||
|
("file:///tests/fixture12.ts", "fixture12.out"),
|
||||||
|
("file:///tests/fixture13.ts", "fixture13.out"),
|
||||||
|
("file:///tests/fixture14.ts", "fixture14.out"),
|
||||||
|
];
|
||||||
|
let c = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
|
||||||
|
let fixtures = c.join("tests/bundle");
|
||||||
|
|
||||||
|
for (specifier, expected_str) in tests {
|
||||||
|
let specifier = ModuleSpecifier::resolve_url_or_path(specifier).unwrap();
|
||||||
|
let handler = Rc::new(RefCell::new(MockSpecifierHandler {
|
||||||
|
fixtures: fixtures.clone(),
|
||||||
|
..MockSpecifierHandler::default()
|
||||||
|
}));
|
||||||
|
let mut builder = GraphBuilder2::new(handler.clone(), None);
|
||||||
|
builder
|
||||||
|
.insert(&specifier)
|
||||||
|
.await
|
||||||
|
.expect("module not inserted");
|
||||||
|
let graph = builder.get_graph(&None).expect("could not get graph");
|
||||||
|
let (actual, stats, maybe_ignored_options) = graph
|
||||||
|
.bundle(BundleOptions::default())
|
||||||
|
.expect("could not bundle");
|
||||||
|
assert_eq!(stats.0.len(), 2);
|
||||||
|
assert_eq!(maybe_ignored_options, None);
|
||||||
|
let expected_path = fixtures.join(expected_str);
|
||||||
|
let expected = fs::read_to_string(expected_path).unwrap();
|
||||||
|
assert_eq!(actual, expected, "fixture: {}", specifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_graph_info() {
|
async fn test_graph_info() {
|
||||||
let c = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
|
let c = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
|
||||||
|
|
3
cli/tests/bundle/file_tests-fixture01.ts
Normal file
3
cli/tests/bundle/file_tests-fixture01.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import * as a from "./subdir/a.ts";
|
||||||
|
|
||||||
|
console.log(a);
|
4
cli/tests/bundle/file_tests-fixture02.ts
Normal file
4
cli/tests/bundle/file_tests-fixture02.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import * as b from "./subdir/b.ts";
|
||||||
|
|
||||||
|
console.log(b.b); // "b"
|
||||||
|
console.log(b.c); // { c: "c", default: class C }
|
3
cli/tests/bundle/file_tests-fixture03.ts
Normal file
3
cli/tests/bundle/file_tests-fixture03.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { d } from "./subdir/d.ts";
|
||||||
|
|
||||||
|
console.log(d);
|
3
cli/tests/bundle/file_tests-fixture04.ts
Normal file
3
cli/tests/bundle/file_tests-fixture04.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const a = await import("./subdir/a.ts");
|
||||||
|
|
||||||
|
console.log(a);
|
3
cli/tests/bundle/file_tests-fixture05.ts
Normal file
3
cli/tests/bundle/file_tests-fixture05.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { a } from "./subdir/e.ts";
|
||||||
|
|
||||||
|
console.log(a);
|
4
cli/tests/bundle/file_tests-fixture06.ts
Normal file
4
cli/tests/bundle/file_tests-fixture06.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import { isMain, modUrl } from "./subdir/f.ts";
|
||||||
|
|
||||||
|
console.log(isMain, modUrl);
|
||||||
|
console.log(import.meta.main, import.meta.url);
|
4
cli/tests/bundle/file_tests-fixture07.ts
Normal file
4
cli/tests/bundle/file_tests-fixture07.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import { G } from "./subdir/g.ts";
|
||||||
|
import { H } from "./subdir/h.ts";
|
||||||
|
|
||||||
|
console.log(new G(true), new H(true));
|
1
cli/tests/bundle/file_tests-fixture08.ts
Normal file
1
cli/tests/bundle/file_tests-fixture08.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * as a from "./subdir/a.ts";
|
1
cli/tests/bundle/file_tests-fixture09.ts
Normal file
1
cli/tests/bundle/file_tests-fixture09.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { a } from "./subdir/k.ts";
|
7
cli/tests/bundle/file_tests-fixture10.ts
Normal file
7
cli/tests/bundle/file_tests-fixture10.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { a as defaultA } from "./subdir/l.ts";
|
||||||
|
|
||||||
|
const o: { a?: string } = {};
|
||||||
|
|
||||||
|
const { a = defaultA } = o;
|
||||||
|
|
||||||
|
console.log(a);
|
32
cli/tests/bundle/file_tests-fixture11.ts
Normal file
32
cli/tests/bundle/file_tests-fixture11.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { a as defaultA, O } from "./subdir/m.ts";
|
||||||
|
export { O } from "./subdir/m.ts";
|
||||||
|
|
||||||
|
interface AOptions {
|
||||||
|
a?(): void;
|
||||||
|
c?: O;
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
#a: () => void;
|
||||||
|
#c?: O;
|
||||||
|
constructor(o: AOptions = {}) {
|
||||||
|
const {
|
||||||
|
a = defaultA,
|
||||||
|
c,
|
||||||
|
} = o;
|
||||||
|
this.#a = a;
|
||||||
|
this.#c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
a() {
|
||||||
|
this.#a();
|
||||||
|
}
|
||||||
|
|
||||||
|
c() {
|
||||||
|
console.log(this.#c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const a = new A();
|
||||||
|
a.a();
|
||||||
|
a.c();
|
7
cli/tests/bundle/file_tests-fixture12.ts
Normal file
7
cli/tests/bundle/file_tests-fixture12.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { a } from "./subdir/p.ts";
|
||||||
|
|
||||||
|
function b() {
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
|
||||||
|
b();
|
11
cli/tests/bundle/file_tests-fixture13.ts
Normal file
11
cli/tests/bundle/file_tests-fixture13.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { D, d } from "./subdir/q.ts";
|
||||||
|
|
||||||
|
class A {
|
||||||
|
private s: D = d();
|
||||||
|
|
||||||
|
a() {
|
||||||
|
this.s.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new A();
|
4
cli/tests/bundle/file_tests-fixture14.ts
Normal file
4
cli/tests/bundle/file_tests-fixture14.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
// @deno-types="https://deno.land/x/lib/mod.d.ts"
|
||||||
|
import * as lib from "https://deno.land/x/lib/mod.js";
|
||||||
|
|
||||||
|
console.log(lib);
|
1
cli/tests/bundle/file_tests-subdir-a.ts
Normal file
1
cli/tests/bundle/file_tests-subdir-a.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const a = "a";
|
3
cli/tests/bundle/file_tests-subdir-b.ts
Normal file
3
cli/tests/bundle/file_tests-subdir-b.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export * as c from "./c.ts";
|
||||||
|
|
||||||
|
export const b = "b";
|
2
cli/tests/bundle/file_tests-subdir-c.ts
Normal file
2
cli/tests/bundle/file_tests-subdir-c.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export const c = "c";
|
||||||
|
export default class C {}
|
3
cli/tests/bundle/file_tests-subdir-d.ts
Normal file
3
cli/tests/bundle/file_tests-subdir-d.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { a } from "./a.ts";
|
||||||
|
|
||||||
|
export const d = { a };
|
1
cli/tests/bundle/file_tests-subdir-e.ts
Normal file
1
cli/tests/bundle/file_tests-subdir-e.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from "./a.ts";
|
2
cli/tests/bundle/file_tests-subdir-f.ts
Normal file
2
cli/tests/bundle/file_tests-subdir-f.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export const isMain = import.meta.main;
|
||||||
|
export const modUrl = import.meta.url;
|
12
cli/tests/bundle/file_tests-subdir-g.ts
Normal file
12
cli/tests/bundle/file_tests-subdir-g.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
const g: number[] = [];
|
||||||
|
|
||||||
|
export class G {
|
||||||
|
#g!: number[];
|
||||||
|
constructor(shared: boolean) {
|
||||||
|
if (shared) {
|
||||||
|
this.#g = g;
|
||||||
|
} else {
|
||||||
|
this.#g = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
cli/tests/bundle/file_tests-subdir-h.ts
Normal file
12
cli/tests/bundle/file_tests-subdir-h.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
const g: number[] = [];
|
||||||
|
|
||||||
|
export class H {
|
||||||
|
#g!: number[];
|
||||||
|
constructor(shared: boolean) {
|
||||||
|
if (shared) {
|
||||||
|
this.#g = g;
|
||||||
|
} else {
|
||||||
|
this.#g = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
cli/tests/bundle/file_tests-subdir-i.ts
Normal file
3
cli/tests/bundle/file_tests-subdir-i.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function a(...d: string[]): string {
|
||||||
|
return d.join(" ");
|
||||||
|
}
|
3
cli/tests/bundle/file_tests-subdir-j.ts
Normal file
3
cli/tests/bundle/file_tests-subdir-j.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function a(...d: string[]): string {
|
||||||
|
return d.join("/");
|
||||||
|
}
|
11
cli/tests/bundle/file_tests-subdir-k.ts
Normal file
11
cli/tests/bundle/file_tests-subdir-k.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import * as _i from "./i.ts";
|
||||||
|
import * as _j from "./j.ts";
|
||||||
|
|
||||||
|
const k = globalThis.value ? _i : _j;
|
||||||
|
|
||||||
|
export const i = _i;
|
||||||
|
export const j = _j;
|
||||||
|
|
||||||
|
export const {
|
||||||
|
a,
|
||||||
|
} = k;
|
1
cli/tests/bundle/file_tests-subdir-l.ts
Normal file
1
cli/tests/bundle/file_tests-subdir-l.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { a } from "./a.ts";
|
2
cli/tests/bundle/file_tests-subdir-m.ts
Normal file
2
cli/tests/bundle/file_tests-subdir-m.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export { a } from "./n.ts";
|
||||||
|
export { O } from "./o.ts";
|
3
cli/tests/bundle/file_tests-subdir-n.ts
Normal file
3
cli/tests/bundle/file_tests-subdir-n.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function a() {
|
||||||
|
console.log("a");
|
||||||
|
}
|
5
cli/tests/bundle/file_tests-subdir-o.ts
Normal file
5
cli/tests/bundle/file_tests-subdir-o.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export enum O {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
}
|
1
cli/tests/bundle/file_tests-subdir-p.ts
Normal file
1
cli/tests/bundle/file_tests-subdir-p.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from "./i.ts";
|
13
cli/tests/bundle/file_tests-subdir-q.ts
Normal file
13
cli/tests/bundle/file_tests-subdir-q.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
export interface D {
|
||||||
|
resolve: any;
|
||||||
|
reject: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function d(): D {
|
||||||
|
let methods;
|
||||||
|
const promise = new Promise((resolve, reject) => {
|
||||||
|
methods = { resolve, reject };
|
||||||
|
});
|
||||||
|
return Object.assign(promise, methods);
|
||||||
|
}
|
7
cli/tests/bundle/fixture01.out
Normal file
7
cli/tests/bundle/fixture01.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
const a = function() {
|
||||||
|
const a = "a";
|
||||||
|
return {
|
||||||
|
a
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
console.log(a);
|
11
cli/tests/bundle/fixture02.out
Normal file
11
cli/tests/bundle/fixture02.out
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
const c = function() {
|
||||||
|
const c1 = "c";
|
||||||
|
class C {
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
c: c1,
|
||||||
|
default: C
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
console.log("b");
|
||||||
|
console.log(c);
|
4
cli/tests/bundle/fixture03.out
Normal file
4
cli/tests/bundle/fixture03.out
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
const d = {
|
||||||
|
a: "a"
|
||||||
|
};
|
||||||
|
console.log(d);
|
2
cli/tests/bundle/fixture04.out
Normal file
2
cli/tests/bundle/fixture04.out
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
const a = await import("./subdir/a.ts");
|
||||||
|
console.log(a);
|
1
cli/tests/bundle/fixture05.out
Normal file
1
cli/tests/bundle/fixture05.out
Normal file
|
@ -0,0 +1 @@
|
||||||
|
console.log("a");
|
2
cli/tests/bundle/fixture06.out
Normal file
2
cli/tests/bundle/fixture06.out
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
console.log(false, "file:///tests/subdir/f.ts");
|
||||||
|
console.log(import.meta.main, "file:///tests/fixture06.ts");
|
23
cli/tests/bundle/fixture07.out
Normal file
23
cli/tests/bundle/fixture07.out
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
const g = [];
|
||||||
|
class G {
|
||||||
|
#g;
|
||||||
|
constructor(shared){
|
||||||
|
if (shared) {
|
||||||
|
this.#g = g;
|
||||||
|
} else {
|
||||||
|
this.#g = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const g1 = [];
|
||||||
|
class H {
|
||||||
|
#g;
|
||||||
|
constructor(shared1){
|
||||||
|
if (shared1) {
|
||||||
|
this.#g = g1;
|
||||||
|
} else {
|
||||||
|
this.#g = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(new G(true), new H(true));
|
7
cli/tests/bundle/fixture08.out
Normal file
7
cli/tests/bundle/fixture08.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
const a = function() {
|
||||||
|
const a1 = "a";
|
||||||
|
return {
|
||||||
|
a: a1
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
export { a };
|
19
cli/tests/bundle/fixture09.out
Normal file
19
cli/tests/bundle/fixture09.out
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
const _i = function() {
|
||||||
|
function a(...d) {
|
||||||
|
return d.join(" ");
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
a
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
const _j = function() {
|
||||||
|
function a(...d) {
|
||||||
|
return d.join("/");
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
a
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
const k = globalThis.value ? _i : _j;
|
||||||
|
const { a , } = k;
|
||||||
|
export { a };
|
4
cli/tests/bundle/fixture10.out
Normal file
4
cli/tests/bundle/fixture10.out
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
const o = {
|
||||||
|
};
|
||||||
|
const { a ="a" } = o;
|
||||||
|
console.log(a);
|
31
cli/tests/bundle/fixture11.out
Normal file
31
cli/tests/bundle/fixture11.out
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
function a() {
|
||||||
|
console.log("a");
|
||||||
|
}
|
||||||
|
var O;
|
||||||
|
(function(O1) {
|
||||||
|
O1[O1["A"] = 0] = "A";
|
||||||
|
O1[O1["B"] = 1] = "B";
|
||||||
|
O1[O1["C"] = 2] = "C";
|
||||||
|
})((void 0) || (O = {
|
||||||
|
}));
|
||||||
|
const O1 = void 0;
|
||||||
|
export { O1 as O };
|
||||||
|
class A {
|
||||||
|
#a;
|
||||||
|
#c;
|
||||||
|
constructor(o = {
|
||||||
|
}){
|
||||||
|
const { a: a1 = a , c , } = o;
|
||||||
|
this.#a = a1;
|
||||||
|
this.#c = c;
|
||||||
|
}
|
||||||
|
a() {
|
||||||
|
this.#a();
|
||||||
|
}
|
||||||
|
c() {
|
||||||
|
console.log(this.#c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const a2 = new A();
|
||||||
|
a2.a();
|
||||||
|
a2.c();
|
7
cli/tests/bundle/fixture12.out
Normal file
7
cli/tests/bundle/fixture12.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
function a(...d) {
|
||||||
|
return d.join(" ");
|
||||||
|
}
|
||||||
|
function b() {
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
b();
|
17
cli/tests/bundle/fixture13.out
Normal file
17
cli/tests/bundle/fixture13.out
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
function d() {
|
||||||
|
let methods;
|
||||||
|
const promise = new Promise((resolve, reject)=>{
|
||||||
|
methods = {
|
||||||
|
resolve,
|
||||||
|
reject
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return Object.assign(promise, methods);
|
||||||
|
}
|
||||||
|
class A {
|
||||||
|
s = d();
|
||||||
|
a() {
|
||||||
|
this.s.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new A();
|
25
cli/tests/bundle/fixture14.out
Normal file
25
cli/tests/bundle/fixture14.out
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
const lib = function() {
|
||||||
|
const a = function() {
|
||||||
|
const a1 = [];
|
||||||
|
return {
|
||||||
|
a: a1
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
const b = function() {
|
||||||
|
const b1 = [];
|
||||||
|
return {
|
||||||
|
b: b1
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
const c = function() {
|
||||||
|
const c1;
|
||||||
|
return {
|
||||||
|
c: c1
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
const mod;
|
||||||
|
return {
|
||||||
|
mod
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
console.log(lib);
|
1
cli/tests/bundle/https_deno.land-x-lib-a.ts
Normal file
1
cli/tests/bundle/https_deno.land-x-lib-a.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const a: string[] = [];
|
1
cli/tests/bundle/https_deno.land-x-lib-b.js
Normal file
1
cli/tests/bundle/https_deno.land-x-lib-b.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const b = [];
|
1
cli/tests/bundle/https_deno.land-x-lib-c.d.ts
vendored
Normal file
1
cli/tests/bundle/https_deno.land-x-lib-c.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const c: string[];
|
3
cli/tests/bundle/https_deno.land-x-lib-c.js
Normal file
3
cli/tests/bundle/https_deno.land-x-lib-c.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
/// <reference types="./c.d.ts" />
|
||||||
|
|
||||||
|
export const c = [];
|
9
cli/tests/bundle/https_deno.land-x-lib-mod.d.ts
vendored
Normal file
9
cli/tests/bundle/https_deno.land-x-lib-mod.d.ts
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export * as a from "./a.ts";
|
||||||
|
export * as b from "./b.js";
|
||||||
|
export * as c from "./c.js";
|
||||||
|
|
||||||
|
export interface A {
|
||||||
|
a: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mod: A[];
|
5
cli/tests/bundle/https_deno.land-x-lib-mod.js
Normal file
5
cli/tests/bundle/https_deno.land-x-lib-mod.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export * as a from "./a.ts";
|
||||||
|
export * as b from "./b.js";
|
||||||
|
export * as c from "./c.js";
|
||||||
|
|
||||||
|
export const mod = [];
|
|
@ -838,6 +838,49 @@ fn bundle_exports() {
|
||||||
assert_eq!(output.stderr, b"");
|
assert_eq!(output.stderr, b"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bundle_exports_no_check() {
|
||||||
|
// First we have to generate a bundle of some module that has exports.
|
||||||
|
let mod1 = util::root_path().join("cli/tests/subdir/mod1.ts");
|
||||||
|
assert!(mod1.is_file());
|
||||||
|
let t = TempDir::new().expect("tempdir fail");
|
||||||
|
let bundle = t.path().join("mod1.bundle.js");
|
||||||
|
let mut deno = util::deno_cmd()
|
||||||
|
.current_dir(util::root_path())
|
||||||
|
.arg("bundle")
|
||||||
|
.arg("--no-check")
|
||||||
|
.arg(mod1)
|
||||||
|
.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());
|
||||||
|
|
||||||
|
// Now we try to use that bundle from another module.
|
||||||
|
let test = t.path().join("test.js");
|
||||||
|
std::fs::write(
|
||||||
|
&test,
|
||||||
|
"
|
||||||
|
import { printHello3 } from \"./mod1.bundle.js\";
|
||||||
|
printHello3(); ",
|
||||||
|
)
|
||||||
|
.expect("error writing file");
|
||||||
|
|
||||||
|
let output = util::deno_cmd()
|
||||||
|
.current_dir(util::root_path())
|
||||||
|
.arg("run")
|
||||||
|
.arg(&test)
|
||||||
|
.output()
|
||||||
|
.expect("failed to spawn script");
|
||||||
|
// check the output of the test.ts program.
|
||||||
|
assert!(std::str::from_utf8(&output.stdout)
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.ends_with("Hello"));
|
||||||
|
assert_eq!(output.stderr, b"");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bundle_circular() {
|
fn bundle_circular() {
|
||||||
// First we have to generate a bundle of some module that has exports.
|
// First we have to generate a bundle of some module that has exports.
|
||||||
|
@ -1051,6 +1094,52 @@ fn bundle_import_map() {
|
||||||
assert_eq!(output.stderr, b"");
|
assert_eq!(output.stderr, b"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bundle_import_map_no_check() {
|
||||||
|
let import = util::root_path().join("cli/tests/bundle_im.ts");
|
||||||
|
let import_map_path = util::root_path().join("cli/tests/bundle_im.json");
|
||||||
|
assert!(import.is_file());
|
||||||
|
let t = TempDir::new().expect("tempdir fail");
|
||||||
|
let bundle = t.path().join("import_map.bundle.js");
|
||||||
|
let mut deno = util::deno_cmd()
|
||||||
|
.current_dir(util::root_path())
|
||||||
|
.arg("bundle")
|
||||||
|
.arg("--no-check")
|
||||||
|
.arg("--importmap")
|
||||||
|
.arg(import_map_path)
|
||||||
|
.arg("--unstable")
|
||||||
|
.arg(import)
|
||||||
|
.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());
|
||||||
|
|
||||||
|
// Now we try to use that bundle from another module.
|
||||||
|
let test = t.path().join("test.js");
|
||||||
|
std::fs::write(
|
||||||
|
&test,
|
||||||
|
"
|
||||||
|
import { printHello3 } from \"./import_map.bundle.js\";
|
||||||
|
printHello3(); ",
|
||||||
|
)
|
||||||
|
.expect("error writing file");
|
||||||
|
|
||||||
|
let output = util::deno_cmd()
|
||||||
|
.current_dir(util::root_path())
|
||||||
|
.arg("run")
|
||||||
|
.arg(&test)
|
||||||
|
.output()
|
||||||
|
.expect("failed to spawn script");
|
||||||
|
// check the output of the test.ts program.
|
||||||
|
assert!(std::str::from_utf8(&output.stdout)
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.ends_with("Hello"));
|
||||||
|
assert_eq!(output.stderr, b"");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn info_with_compiled_source() {
|
fn info_with_compiled_source() {
|
||||||
let _g = util::http_server();
|
let _g = util::http_server();
|
||||||
|
|
|
@ -17,7 +17,7 @@ use std::str::FromStr;
|
||||||
/// file, that we want to deserialize out of the final config for a transpile.
|
/// file, that we want to deserialize out of the final config for a transpile.
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct TranspileConfigOptions {
|
pub struct EmitConfigOptions {
|
||||||
pub check_js: bool,
|
pub check_js: bool,
|
||||||
pub emit_decorator_metadata: bool,
|
pub emit_decorator_metadata: bool,
|
||||||
pub jsx: String,
|
pub jsx: String,
|
||||||
|
@ -202,7 +202,7 @@ pub fn parse_config(
|
||||||
|
|
||||||
/// A structure for managing the configuration of TypeScript
|
/// A structure for managing the configuration of TypeScript
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TsConfig(Value);
|
pub struct TsConfig(pub Value);
|
||||||
|
|
||||||
impl TsConfig {
|
impl TsConfig {
|
||||||
/// Create a new `TsConfig` with the base being the `value` supplied.
|
/// Create a new `TsConfig` with the base being the `value` supplied.
|
||||||
|
@ -247,15 +247,6 @@ impl TsConfig {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the current configuration as a `TranspileConfigOptions` structure.
|
|
||||||
pub fn as_transpile_config(
|
|
||||||
&self,
|
|
||||||
) -> Result<TranspileConfigOptions, AnyError> {
|
|
||||||
let options: TranspileConfigOptions =
|
|
||||||
serde_json::from_value(self.0.clone())?;
|
|
||||||
Ok(options)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for TsConfig {
|
impl Serialize for TsConfig {
|
||||||
|
|
Loading…
Reference in a new issue