Skip to content

Commit

Permalink
spack: enhancement (#845)
Browse files Browse the repository at this point in the history
 - Handle modules (via swcrc)
 - swc.bundle([conf1, conf2])
 - Correct chunking
  • Loading branch information
kdy1 authored Jun 15, 2020
1 parent aea757d commit 31020e4
Show file tree
Hide file tree
Showing 40 changed files with 566 additions and 133 deletions.
4 changes: 4 additions & 0 deletions .github/ISSUE_TEMPLATE/crash_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ assignees: ''

3. Error message gained from `swc --sync <input.js>`
(--sync is required to get panic message)

4. Backtrace

(You can get it by invoking swc by setting an environment varaible`SWC_DEBUG` to `1`, invoke swc like `SWC_DEBUG=1 npx swc foo.js` on linux / darwin)
2 changes: 1 addition & 1 deletion common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "swc_common"
version = "0.5.13"
version = "0.5.14"
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
license = "Apache-2.0/MIT"
repository = "https://github.com/swc-project/swc.git"
Expand Down
2 changes: 2 additions & 0 deletions ecmascript/transforms/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ macro_rules! validate {
}};
}

#[macro_export]
macro_rules! noop_fold_type {
($F:ty, $N:tt) => {
impl Fold<swc_ecma_ast::$N> for $F {
Expand Down Expand Up @@ -316,6 +317,7 @@ macro_rules! noop_fold_type {
};
}

#[macro_export]
macro_rules! noop_visit_type {
($F:ty, $N:tt) => {
impl Visit<swc_ecma_ast::$N> for $F {
Expand Down
1 change: 1 addition & 0 deletions native/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ neon-build = "0.4.0"
[dependencies]
swc = { path = "../" }
spack = { path = "../spack" }
backtrace = "0.3"
fxhash = "0.2"
anyhow = "1"
serde_json = "1"
Expand Down
136 changes: 67 additions & 69 deletions native/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ use fxhash::FxHashMap;
use neon::prelude::*;
use serde::Deserialize;
use spack::{
config::EntryConfig,
load::Load,
resolve::{NodeResolver, Resolve},
BundleKind,
};
use std::{path::PathBuf, sync::Arc};
use std::{
panic::{catch_unwind, AssertUnwindSafe},
sync::Arc,
};
use swc::{config::SourceMapsConfig, Compiler, TransformOutput};

struct ConfigItem {
Expand Down Expand Up @@ -38,77 +40,73 @@ impl Task for BundleTask {
type JsEvent = JsValue;

fn perform(&self) -> Result<Self::Output, Self::Error> {
let working_dir = PathBuf::from(self.config.static_items.working_dir.clone());
let bundler = spack::Bundler::new(
working_dir.clone(),
self.swc.clone(),
self.config
.static_items
.config
.options
.as_ref()
.map(|options| options.clone())
.unwrap_or_else(|| {
serde_json::from_value(serde_json::Value::Object(Default::default())).unwrap()
}),
&self.config.resolver,
&self.config.loader,
);
let entries = match &self.config.static_items.config.entry {
EntryConfig::File(name) => {
let mut m = FxHashMap::default();
m.insert(name.clone(), working_dir.join(name));
m
}
EntryConfig::Multiple(files) => {
let mut m = FxHashMap::default();
for name in files {
m.insert(name.clone(), working_dir.join(name));
}
m
}
EntryConfig::Files(v) => v
let res = catch_unwind(AssertUnwindSafe(|| {
let bundler = spack::Bundler::new(
self.swc.clone(),
self.config
.static_items
.config
.options
.as_ref()
.map(|options| options.clone())
.unwrap_or_else(|| {
serde_json::from_value(serde_json::Value::Object(Default::default()))
.unwrap()
}),
&self.config.resolver,
&self.config.loader,
);

let result = bundler.bundle(&self.config.static_items.config)?;

let result = result
.into_iter()
.map(|(k, v)| (k.clone(), working_dir.clone().join(v)))
.collect(),
.map(|bundle| match bundle.kind {
BundleKind::Named { name } | BundleKind::Lib { name } => {
Ok((name, bundle.module))
}
BundleKind::Dynamic => bail!("unimplemented: dynamic code splitting"),
})
.map(|res| {
res.and_then(|(k, m)| {
// TODO: Source map
let minify = self
.config
.static_items
.config
.options
.as_ref()
.map(|v| {
v.config
.as_ref()
.map(|v| v.minify)
.flatten()
.unwrap_or(false)
})
.unwrap_or(false);

let output =
self.swc
.print(&m, SourceMapsConfig::Bool(true), None, minify)?;

Ok((k, output))
})
})
.collect::<Result<_, _>>()?;

Ok(result)
}));

let err = match res {
Ok(v) => return v,
Err(err) => err,
};

let result = bundler.bundle(entries)?;

let result = result
.into_iter()
.map(|bundle| match bundle.kind {
BundleKind::Named { name } | BundleKind::Lib { name } => Ok((name, bundle.module)),
BundleKind::Dynamic => bail!("unimplemented: dynamic code splitting"),
})
.map(|res| {
res.and_then(|(k, m)| {
// TODO: Source map
let minify = self
.config
.static_items
.config
.options
.as_ref()
.map(|v| {
v.config
.as_ref()
.map(|v| v.minify)
.flatten()
.unwrap_or(false)
})
.unwrap_or(false);

let output = self
.swc
.print(&m, SourceMapsConfig::Bool(true), None, minify)?;

Ok((k, output))
})
})
.collect::<Result<_, _>>()?;
if let Some(s) = err.downcast_ref::<String>() {
bail!("panic detected: {}", s);
}

Ok(result)
bail!("panic detected")
}

fn complete(
Expand Down
10 changes: 10 additions & 0 deletions native/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ extern crate serde;
extern crate swc;

use anyhow::{Context as _, Error};
use backtrace::Backtrace;
use neon::prelude::*;
use path_clean::clean;
use std::{
env,
panic::set_hook,
path::{Path, PathBuf},
sync::Arc,
};
Expand All @@ -26,6 +29,13 @@ use swc::{
mod bundle;

fn init(_cx: MethodContext<JsUndefined>) -> NeonResult<ArcCompiler> {
if cfg!(debug_assertions) || env::var("SWC_DEBUG").unwrap_or_else(|_| String::new()) == "1" {
set_hook(Box::new(|_panic_info| {
let backtrace = Backtrace::new();
println!("Backtrace: {:?}", backtrace);
}));
}

let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));

let handler = Arc::new(Handler::with_tty_emitter(
Expand Down
10 changes: 10 additions & 0 deletions node-swc/__tests__/spack/config_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,14 @@ it('should handle multiple entry in spack.config.js', async () => {

expect(result.b).toBeTruthy();
expect(result.b.code.replace('\n', '')).toBe(`console.log('bar');`);
});

it('should respect .swcrc', async () => {
const result = await swc.bundle(path.join(__dirname, '../../tests/spack/config-swcrc/spack.config.js'));

expect(result.a).toBeTruthy();
expect(result.a.code).toContain(`require('./common-`);

expect(result.b).toBeTruthy();
expect(result.b.code).toContain(`require('./common-`);
});
34 changes: 34 additions & 0 deletions node-swc/__tests__/spack/multi_entry_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const swc = require("../../..");
const path = require('path');


it('should handle multiple entries on same level', async () => {
const result = await swc.bundle({
entry: {
a: path.join(__dirname, '../../tests/spack/mutli-entry-same-level/src/a.js'),
b: path.join(__dirname, '../../tests/spack/mutli-entry-same-level/src/b.js'),
}
});

expect(result.a).toBeTruthy();
expect(result.a.code).toContain(`import { foo } from './common-`);

expect(result.b).toBeTruthy();
expect(result.b.code).toContain(`import { foo } from './common-`);
});


it('should handle multiple entries on different level', async () => {
const result = await swc.bundle({
entry: {
web: path.join(__dirname, '../../tests/spack/mutli-entry-different-level/src/web/index.js'),
a: path.join(__dirname, '../../tests/spack/mutli-entry-different-level/src/a.js'),
}
});

expect(result.a).toBeTruthy();
expect(result.a.code).toContain(`import { foo } from './common-`);

expect(result.web).toBeTruthy();
expect(result.web.code).toContain(`../common`);
});
14 changes: 14 additions & 0 deletions node-swc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,20 @@ export class Compiler extends wrapNativeSuper(native.Compiler) {
async bundle(options?: BundleInput | string): Promise<{ [name: string]: Output }> {
const opts = await compileBundleOptions(options);

if (Array.isArray(opts)) {
const all = await Promise.all(opts.map(async (opt) => {
return this.bundle(opt)
}));
let obj = {} as any;
for (const o of all) {
obj = {
...obj,
...o,
};
}
return obj;
}

return new Promise((resolve, reject) => {
super.bundle({
...opts,
Expand Down
16 changes: 12 additions & 4 deletions node-swc/src/spack/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,21 @@ export async function compileBundleOptions(c: BundleInput | string | undefined):

try {
const file = typeof f === 'string' ? f : path.resolve('spack.config.js');
let configFromFile = require(file);
if (configFromFile.default) {
configFromFile = configFromFile.default;
let configFromFile: BundleInput = require(file);
if ((configFromFile as any).default) {
configFromFile = (configFromFile as any).default;
}
if (Array.isArray(configFromFile)) {
if (Array.isArray(f)) {
return [...configFromFile, ...f]
}
if (typeof f !== 'string') {
configFromFile.push(f);
}
return configFromFile;
}
return Object.assign({}, configFromFile, c);
} catch (e) {
console.log(e);
if (typeof f === 'string') {
throw new Error(`Config file does not exist at ${c}`)
}
Expand Down
5 changes: 5 additions & 0 deletions node-swc/tests/spack/config-swcrc/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"module": {
"type": "commonjs"
}
}
1 change: 1 addition & 0 deletions node-swc/tests/spack/config-swcrc/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('Prevent inlinig')
1 change: 1 addition & 0 deletions node-swc/tests/spack/config-swcrc/entry1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './common'
1 change: 1 addition & 0 deletions node-swc/tests/spack/config-swcrc/entry2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './common'
8 changes: 8 additions & 0 deletions node-swc/tests/spack/config-swcrc/spack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const path = require('path');

module.exports = {
entry: {
a: path.join(__dirname, 'entry1.js'),
b: path.join(__dirname, 'entry2.js'),
},
}
3 changes: 3 additions & 0 deletions node-swc/tests/spack/mutli-entry-different-level/src/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { foo } from './common'

console.log(foo)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
console.log('loading foo')
export const foo = 'FOO';
console.log('loaded foo')


Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '../common';
3 changes: 3 additions & 0 deletions node-swc/tests/spack/mutli-entry-same-level/src/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { foo } from './common'

console.log(foo)
3 changes: 3 additions & 0 deletions node-swc/tests/spack/mutli-entry-same-level/src/b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { foo } from './common'

console.log(foo)
5 changes: 5 additions & 0 deletions node-swc/tests/spack/mutli-entry-same-level/src/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
console.log('loading foo')
export const foo = 'FOO';
console.log('loaded foo')


2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/core",
"version": "1.2.2",
"version": "1.2.3",
"description": "Super-fast alternative for babel",
"main": "./index.js",
"author": "강동윤 <kdy1997.dev@gmail.com>",
Expand Down
2 changes: 1 addition & 1 deletion spack/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
*.js
/*.js
*.d.ts
*.map
Loading

0 comments on commit 31020e4

Please sign in to comment.