mirror of
https://github.com/swc-project/swc.git
synced 2024-12-01 01:13:56 +03:00
9879fa59c8
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)
117 lines
3.1 KiB
Rust
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!()
|
|
}
|
|
}
|