swc/bundler/examples/path.rs
강동윤 9879fa59c8
bundler: fix bugs (#1105)
swc_bundler:
 - Correct lca for circular dependencies.
 - Handle namespaced imports. (#1109)
 - Handle namespaced reexports. (#1110)
 - Handle shorthand properly. (#1111)
 - Implement `import.meta` (#1115)
 - Handle reexport mixed with imports correctly. (#1116)
 - Handle export default decls in computed-key modules. 
 - Remove all export * from. output. (#1118)
 - Handle export of class or function declaration in a computed module properly. (#1119)


swc_ecma_transforms:
 - Do not rename class members. (#1117)
2020-10-02 11:07:40 +09:00

117 lines
3.1 KiB
Rust

use anyhow::Error;
use std::{collections::HashMap, io::stdout};
use swc_bundler::{BundleKind, Bundler, Config, Hook, Load, Resolve};
use swc_common::{sync::Lrc, FileName, FilePathMapping, Globals, SourceMap, Span};
use swc_ecma_ast::Expr;
use swc_ecma_codegen::{text_writer::JsWriter, Emitter};
use swc_ecma_parser::{lexer::Lexer, EsConfig, Parser, StringInput, Syntax};
fn main() {
testing::init();
let globals = Globals::new();
let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
// This example does not use core modules.
let external_modules = vec![];
let bundler = Bundler::new(
&globals,
cm.clone(),
PathLoader { cm: cm.clone() },
PathResolver,
Config {
require: true,
external_modules,
..Default::default()
},
Box::new(Noop),
);
let mut entries = HashMap::default();
entries.insert("main".to_string(), FileName::Real("assets/main.js".into()));
let mut bundles = bundler.bundle(entries).expect("failed to bundle");
assert_eq!(
bundles.len(),
1,
"There's no conditional / dynamic imports and we provided only one entry"
);
let bundle = bundles.pop().unwrap();
assert_eq!(
bundle.kind,
BundleKind::Named {
name: "main".into()
},
"We provided it"
);
let wr = stdout();
let mut emitter = Emitter {
cfg: swc_ecma_codegen::Config { minify: false },
cm: cm.clone(),
comments: None,
wr: Box::new(JsWriter::new(cm.clone(), "\n", wr.lock(), None)),
};
emitter.emit_module(&bundle.module).unwrap();
}
struct PathLoader {
cm: Lrc<SourceMap>,
}
impl Load for PathLoader {
fn load(
&self,
file: &FileName,
) -> Result<(Lrc<swc_common::SourceFile>, swc_ecma_ast::Module), Error> {
let file = match file {
FileName::Real(v) => v,
_ => unreachable!(),
};
let fm = self.cm.load_file(file)?;
let lexer = Lexer::new(
Syntax::Es(EsConfig {
..Default::default()
}),
Default::default(),
StringInput::from(&*fm),
None,
);
let mut parser = Parser::new_from(lexer);
let module = parser.parse_module().expect("This should not happen");
Ok((fm, module))
}
}
struct PathResolver;
impl Resolve for PathResolver {
fn resolve(&self, base: &FileName, module_specifier: &str) -> Result<FileName, Error> {
assert!(
module_specifier.starts_with("."),
"We are not using node_modules within this example"
);
let base = match base {
FileName::Real(v) => v,
_ => unreachable!(),
};
Ok(FileName::Real(
base.parent()
.unwrap()
.join(module_specifier)
.with_extension("js"),
))
}
}
struct Noop;
impl Hook for Noop {
fn get_import_meta_url(&self, _: Span, _: &FileName) -> Result<Option<Expr>, Error> {
unimplemented!()
}
}