mirror of
https://codeberg.org/demostf/frontend.git
synced 2026-06-03 10:14:13 +02:00
js bundle
This commit is contained in:
parent
305e8ec8ed
commit
d0c1045550
7 changed files with 223 additions and 36 deletions
76
Cargo.lock
generated
76
Cargo.lock
generated
|
|
@ -545,15 +545,30 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23"
|
||||||
|
dependencies = [
|
||||||
|
"crc-catalog 1.1.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc"
|
name = "crc"
|
||||||
version = "3.0.1"
|
version = "3.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
|
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc-catalog",
|
"crc-catalog 2.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc-catalog"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc-catalog"
|
name = "crc-catalog"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
|
@ -746,11 +761,18 @@ dependencies = [
|
||||||
name = "demostf-build"
|
name = "demostf-build"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"base64 0.21.0",
|
"base64 0.21.0",
|
||||||
"const-fnv1a-hash",
|
"const-fnv1a-hash",
|
||||||
"lightningcss",
|
"lightningcss",
|
||||||
"swc",
|
"swc",
|
||||||
|
"swc_atoms",
|
||||||
|
"swc_bundler",
|
||||||
"swc_common",
|
"swc_common",
|
||||||
|
"swc_ecma_ast",
|
||||||
|
"swc_ecma_codegen",
|
||||||
|
"swc_ecma_loader",
|
||||||
|
"swc_ecma_parser",
|
||||||
"urlencoding",
|
"urlencoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2551,6 +2573,12 @@ version = "0.6.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "relative-path"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4bf2521270932c3c7bed1a59151222bd7643c79310f2916f01925e1e16255698"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rend"
|
name = "rend"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
@ -3087,7 +3115,7 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"crc",
|
"crc 3.0.1",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"dirs",
|
"dirs",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
|
|
@ -3380,6 +3408,37 @@ dependencies = [
|
||||||
"triomphe",
|
"triomphe",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "swc_bundler"
|
||||||
|
version = "0.212.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23c39d6d7fef9ee2a951423593764bea1666a4be0cbc89030d0da8f985124870"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"anyhow",
|
||||||
|
"crc 2.1.0",
|
||||||
|
"indexmap",
|
||||||
|
"is-macro",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot 0.12.1",
|
||||||
|
"petgraph",
|
||||||
|
"radix_fmt",
|
||||||
|
"relative-path",
|
||||||
|
"swc_atoms",
|
||||||
|
"swc_common",
|
||||||
|
"swc_ecma_ast",
|
||||||
|
"swc_ecma_codegen",
|
||||||
|
"swc_ecma_loader",
|
||||||
|
"swc_ecma_parser",
|
||||||
|
"swc_ecma_transforms_base",
|
||||||
|
"swc_ecma_transforms_optimization",
|
||||||
|
"swc_ecma_utils",
|
||||||
|
"swc_ecma_visit",
|
||||||
|
"swc_fast_graph",
|
||||||
|
"swc_graph_analyzer",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_cached"
|
name = "swc_cached"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
|
|
@ -3934,6 +3993,19 @@ dependencies = [
|
||||||
"swc_common",
|
"swc_common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "swc_graph_analyzer"
|
||||||
|
version = "0.19.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23f7b0fd7b458e07d47e4a401a452cd60090e9eff93eadf06880e1787e19f293"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"auto_impl",
|
||||||
|
"petgraph",
|
||||||
|
"swc_fast_graph",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_macros_common"
|
name = "swc_macros_common"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,10 @@ urlencoding = "2.1.2"
|
||||||
const-fnv1a-hash = "1.1.0"
|
const-fnv1a-hash = "1.1.0"
|
||||||
swc = "0.259.6"
|
swc = "0.259.6"
|
||||||
swc_common = { version = "0.30.5", features = ["tty-emitter"] }
|
swc_common = { version = "0.30.5", features = ["tty-emitter"] }
|
||||||
|
swc_bundler = "0.212.5"
|
||||||
|
swc_ecma_loader = "0.42.5"
|
||||||
|
swc_ecma_ast = "0.102.5"
|
||||||
|
swc_atoms = "0.4.43"
|
||||||
|
swc_ecma_parser = "0.132.6"
|
||||||
|
swc_ecma_codegen = "0.137.6"
|
||||||
|
anyhow = "1.0.70"
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,141 @@
|
||||||
use std::{path::Path, sync::Arc};
|
use anyhow::Error;
|
||||||
use swc::config::Config;
|
use std::collections::HashMap;
|
||||||
use swc::{self, config::Options, BoolConfig};
|
use std::sync::Arc;
|
||||||
|
use swc_atoms::js_word;
|
||||||
|
use swc_bundler::{Bundler, Load, ModuleData, ModuleRecord};
|
||||||
|
use swc_common::sync::Lrc;
|
||||||
use swc_common::{
|
use swc_common::{
|
||||||
errors::{ColorConfig, Handler},
|
errors::{ColorConfig, Handler},
|
||||||
SourceMap, GLOBALS,
|
FileName, SourceMap, Span, GLOBALS,
|
||||||
};
|
};
|
||||||
|
use swc_ecma_ast::*;
|
||||||
|
use swc_ecma_codegen::text_writer::{omit_trailing_semi, JsWriter, WriteJs};
|
||||||
|
use swc_ecma_codegen::Emitter;
|
||||||
|
use swc_ecma_loader::resolvers::lru::CachingResolver;
|
||||||
|
use swc_ecma_loader::resolvers::node::NodeModulesResolver;
|
||||||
|
use swc_ecma_loader::TargetEnv;
|
||||||
|
use swc_ecma_parser::{parse_file_as_module, Syntax};
|
||||||
|
|
||||||
pub fn bundle_script(script: &str) -> String {
|
pub fn bundle_script(script: &str) -> String {
|
||||||
|
let minify = true;
|
||||||
let output = GLOBALS.set(&Default::default(), || {
|
let output = GLOBALS.set(&Default::default(), || {
|
||||||
let cm = Arc::<SourceMap>::default();
|
let cm = Arc::<SourceMap>::default();
|
||||||
let handler = Arc::new(Handler::with_tty_emitter(
|
|
||||||
ColorConfig::Auto,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
Some(cm.clone()),
|
|
||||||
));
|
|
||||||
let compiler = swc::Compiler::new(cm.clone());
|
|
||||||
|
|
||||||
let fm = cm
|
let globals = Box::leak(Box::default());
|
||||||
// filepath that actually exists relative to the binary
|
let mut bundler = Bundler::new(
|
||||||
.load_file(Path::new(script))
|
globals,
|
||||||
.expect("failed to load file");
|
cm.clone(),
|
||||||
|
Loader { cm: cm.clone() },
|
||||||
compiler
|
CachingResolver::new(
|
||||||
.process_js_file(
|
4096,
|
||||||
fm,
|
NodeModulesResolver::new(TargetEnv::Node, Default::default(), true),
|
||||||
&handler,
|
),
|
||||||
&Options {
|
swc_bundler::Config {
|
||||||
config: Config {
|
require: false,
|
||||||
minify: BoolConfig::new(Some(true)),
|
|
||||||
..Config::default()
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
Box::new(Hook),
|
||||||
|
);
|
||||||
|
let mut entries = HashMap::new();
|
||||||
|
entries.insert(
|
||||||
|
script.trim_end_matches(".js").to_string(),
|
||||||
|
FileName::Real(script.into()),
|
||||||
|
);
|
||||||
|
let modules = bundler.bundle(entries).expect("failed to bundle");
|
||||||
|
|
||||||
|
let mut buf = vec![];
|
||||||
|
|
||||||
|
{
|
||||||
|
let wr = JsWriter::new(cm.clone(), "\n", &mut buf, None);
|
||||||
|
let mut emitter = Emitter {
|
||||||
|
cfg: swc_ecma_codegen::Config {
|
||||||
|
minify,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
cm: cm.clone(),
|
||||||
|
comments: None,
|
||||||
|
wr: if minify {
|
||||||
|
Box::new(omit_trailing_semi(wr)) as Box<dyn WriteJs>
|
||||||
|
} else {
|
||||||
|
Box::new(wr) as Box<dyn WriteJs>
|
||||||
|
},
|
||||||
|
};
|
||||||
|
for module in modules {
|
||||||
|
emitter.emit_module(&module.module).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf
|
||||||
|
});
|
||||||
|
String::from_utf8(output).expect("invalid utf8 bundle")
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Hook;
|
||||||
|
|
||||||
|
impl swc_bundler::Hook for Hook {
|
||||||
|
fn get_import_meta_props(
|
||||||
|
&self,
|
||||||
|
span: Span,
|
||||||
|
module_record: &ModuleRecord,
|
||||||
|
) -> Result<Vec<KeyValueProp>, Error> {
|
||||||
|
let file_name = module_record.file_name.to_string();
|
||||||
|
|
||||||
|
Ok(vec![
|
||||||
|
KeyValueProp {
|
||||||
|
key: PropName::Ident(Ident::new(js_word!("url"), span)),
|
||||||
|
value: Box::new(Expr::Lit(Lit::Str(Str {
|
||||||
|
span,
|
||||||
|
raw: None,
|
||||||
|
value: file_name.into(),
|
||||||
|
}))),
|
||||||
|
},
|
||||||
|
KeyValueProp {
|
||||||
|
key: PropName::Ident(Ident::new(js_word!("main"), span)),
|
||||||
|
value: Box::new(if module_record.is_entry {
|
||||||
|
Expr::Member(MemberExpr {
|
||||||
|
span,
|
||||||
|
obj: Box::new(Expr::MetaProp(MetaPropExpr {
|
||||||
|
span,
|
||||||
|
kind: MetaPropKind::ImportMeta,
|
||||||
|
})),
|
||||||
|
prop: MemberProp::Ident(Ident::new(js_word!("main"), span)),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Expr::Lit(Lit::Bool(Bool { span, value: false }))
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Loader {
|
||||||
|
pub cm: Lrc<SourceMap>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Load for Loader {
|
||||||
|
fn load(&self, f: &FileName) -> Result<ModuleData, Error> {
|
||||||
|
let fm = match f {
|
||||||
|
FileName::Real(path) => self.cm.load_file(path)?,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let module = parse_file_as_module(
|
||||||
|
&fm,
|
||||||
|
Syntax::Es(Default::default()),
|
||||||
|
EsVersion::Es2020,
|
||||||
|
None,
|
||||||
|
&mut vec![],
|
||||||
)
|
)
|
||||||
.expect("failed to process file")
|
.unwrap_or_else(|err| {
|
||||||
|
let handler =
|
||||||
|
Handler::with_tty_emitter(ColorConfig::Always, false, false, Some(self.cm.clone()));
|
||||||
|
err.into_diagnostic(&handler).emit();
|
||||||
|
panic!("failed to parse")
|
||||||
});
|
});
|
||||||
output.code
|
|
||||||
|
Ok(ModuleData {
|
||||||
|
fm,
|
||||||
|
module,
|
||||||
|
helpers: Default::default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
script/test.js
Normal file
3
script/test.js
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export function test() {
|
||||||
|
console.log("import test");
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
function test() {
|
import {test} from './test';
|
||||||
console.log("test");
|
|
||||||
}
|
|
||||||
document.addEventListener("DOMContentLoaded", test);
|
document.addEventListener("DOMContentLoaded", test);
|
||||||
|
if (document.readyState === "complete") {
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
|
@ -47,6 +47,8 @@ pub const fn guess_mime(path: &'static str) -> &'static str {
|
||||||
return "image/png";
|
return "image/png";
|
||||||
} else if ends_with!(path, "css") {
|
} else if ends_with!(path, "css") {
|
||||||
return "text/css";
|
return "text/css";
|
||||||
|
} else if ends_with!(path, "js") {
|
||||||
|
return "text/javascript";
|
||||||
}
|
}
|
||||||
return "text/plain";
|
return "text/plain";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ impl Page for UploadPage {
|
||||||
}
|
}
|
||||||
(self.plugin_section())
|
(self.plugin_section())
|
||||||
}
|
}
|
||||||
script src = (script);
|
script src = (script) type = "text/javascript" {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue