swc_bundler/bundler/helpers/
mod.rs

1use std::sync::atomic::{AtomicBool, Ordering::SeqCst};
2
3use once_cell::sync::Lazy;
4use swc_common::{FileName, FilePathMapping, SourceMap};
5use swc_ecma_ast::*;
6use swc_ecma_parser::parse_file_as_module;
7use swc_ecma_utils::{drop_span, prepend_stmts};
8
9#[derive(Debug, Default)]
10pub(crate) struct Helpers {
11    /// `__swcpack_require__`
12    pub require: AtomicBool,
13}
14
15fn parse(code: &'static str, name: &'static str) -> Vec<ModuleItem> {
16    let cm = SourceMap::new(FilePathMapping::empty());
17    let fm = cm.new_source_file(FileName::Custom(name.into()).into(), code);
18    parse_file_as_module(
19        &fm,
20        Default::default(),
21        Default::default(),
22        None,
23        &mut Vec::new(),
24    )
25    .map(|script| drop_span(script.body))
26    .map_err(|_| {})
27    .unwrap()
28}
29
30macro_rules! define {
31    (
32        $(
33            $name:ident {
34                build: $build:ident
35            }
36        )*
37    ) => {
38        $(
39            fn $build(to: &mut Vec<ModuleItem>) {
40                static STMTS: Lazy<Vec<ModuleItem>> = Lazy::new(|| {
41                    parse(include_str!(concat!("_", stringify!($name), ".js")), stringify!($name))
42                });
43
44                to.extend((*STMTS).clone());
45            }
46        )*
47    };
48}
49
50define!(require {
51    build: build_swcpack_require
52});
53
54impl Helpers {
55    pub fn extend(&self, rhs: &Self) {
56        if rhs.require.load(SeqCst) {
57            self.require.store(true, SeqCst);
58        }
59    }
60
61    pub fn add_to(&self, to: &mut Vec<ModuleItem>) {
62        let mut buf = Vec::new();
63
64        if self.require.load(SeqCst) {
65            build_swcpack_require(&mut buf);
66        }
67
68        prepend_stmts(to, buf.into_iter());
69    }
70}