Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bundler #1242

Merged
merged 13 commits into from
Nov 30, 2020
Merged
2 changes: 1 addition & 1 deletion bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_bundler"
repository = "https://github.com/swc-project/swc.git"
version = "0.17.2"
version = "0.17.3"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
Expand Down
62 changes: 39 additions & 23 deletions bundler/src/bundler/chunk/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::{borrow::Cow, collections::HashMap, mem::take};
use swc_atoms::js_word;
use swc_common::{sync::Lock, FileName, SyntaxContext, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_utils::{find_ids, prepend, private_ident};
use swc_ecma_utils::{find_ids, prepend, private_ident, ExprFactory};
use swc_ecma_visit::{noop_fold_type, noop_visit_mut_type, Fold, FoldWith, VisitMut, VisitMutWith};
use util::CHashSet;

Expand Down Expand Up @@ -102,6 +102,7 @@ where
&self,
ctx: &Ctx,
dep_id: ModuleId,
src: &Source,
specifiers: &[Specifier],
) -> Result<Module, Error> {
log::debug!("Merging {:?} directly", dep_id);
Expand All @@ -114,27 +115,25 @@ where
let mut module = self.get_module_for_merging(ctx, dep_id, false)?;
module = self.wrap_esm(ctx, dep_id, module)?;

{
// Inject local_name = wrapped_esm_module_name
// Inject local_name = wrapped_esm_module_name
let module_ident = specifiers
.iter()
.find_map(|specifier| match specifier {
Specifier::Namespace {
local, all: true, ..
} => Some(local.clone()),
_ => None,
})
.unwrap();

let module_ident = specifiers
.iter()
.find_map(|specifier| match specifier {
Specifier::Namespace {
local, all: true, ..
} => Some(local.clone()),
_ => None,
})
.unwrap();

module.body.push(
self.scope
.wrapped_esm_id(dep_id)
.unwrap()
.assign_to(module_ident)
.into_module_item("merge_direct_import"),
);
}
let esm_id = self.scope.wrapped_esm_id(dep_id).unwrap();

module.body.push(
esm_id
.clone()
.assign_to(module_ident.clone())
.into_module_item("merge_direct_import"),
);

let plan = ctx.plan.normal.get(&dep_id);
let default_plan;
Expand All @@ -158,6 +157,23 @@ where
.merge_deps(ctx, false, module, plan, &dep_info, false)
.context("failed to merge dependencies")?;

// Required to handle edge cases liek https://github.com/denoland/deno/issues/8530
for specifier in specifiers {
match specifier {
Specifier::Specific { local, alias } => {
let i = alias.clone().unwrap_or_else(|| local.clone());

let from = esm_id.clone().into_ident().make_member(i.clone());

module.body.push(
from.assign_to(i.with_ctxt(src.export_ctxt))
.into_module_item("namespace_with_normal"),
);
}
Specifier::Namespace { .. } => continue,
}
}

self.handle_import_deps(ctx, &dep_info, &mut module, false);

module
Expand Down Expand Up @@ -336,8 +352,8 @@ where
.iter()
.find(|(src, _)| src.module_id == dep.id);

if let Some((_, specifiers)) = res {
self.merge_direct_import(ctx, dep.id, &specifiers)?
if let Some((src, specifiers)) = res {
self.merge_direct_import(ctx, dep.id, &src, &specifiers)?
} else {
// Common js requires different planning strategy.
self.merge_transitive_import(ctx, dep.id)?
Expand Down
28 changes: 15 additions & 13 deletions bundler/src/bundler/import/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,19 @@ where
idents_to_deglob: HashSet<Id>,
}

impl RawImports {
fn insert(&mut self, import: &ImportDecl) {
for prev in self.imports.iter_mut() {
if prev.src.value == import.src.value {
prev.specifiers.extend(import.specifiers.clone());
return;
}
}

self.imports.push(import.clone());
}
}

impl<L, R> ImportHandler<'_, '_, L, R>
where
L: Load,
Expand Down Expand Up @@ -217,7 +230,7 @@ where
}
}

self.info.imports.push(import.clone());
self.info.insert(&import);
return import;
}

Expand Down Expand Up @@ -306,17 +319,6 @@ where

if use_ns {
wrapping_required.push(import.src.value.clone());

import.specifiers.retain(|s| match s {
ImportSpecifier::Namespace(_) => true,
_ => false,
});

debug_assert_ne!(
import.specifiers,
vec![],
"forced_ns should be modified only if a namespace import specifier exist"
);
} else {
// De-glob namespace imports
import.specifiers.retain(|s| match s {
Expand Down Expand Up @@ -506,7 +508,7 @@ where
};

if self.top_level {
self.info.imports.push(decl);
self.info.insert(&decl);
return Expr::Call(e);
}

Expand Down
11 changes: 11 additions & 0 deletions bundler/tests/deno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,17 @@ fn deno_8481_1() {
)
}

#[test]
fn deno_8530() {
run("tests/deno/deno-8530/input/entry.ts", &[])
}

#[test]
#[ignore]
fn deno_8545() {
run("tests/deno/deno-8545/input/entry.ts", &[])
}

#[test]
fn merging_order_01() {
run(
Expand Down
9 changes: 9 additions & 0 deletions bundler/tests/deno/deno-8530/input/entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Head from "https://deno.land/x/aleph/head.ts"
import * as Head2 from "https://deno.land/x/aleph/head.ts"
console.log(Head, Head2);
if (typeof Head !== 'function') {
throw new Error()
}
if (typeof Head2 !== 'object') {
throw new Error()
}
18 changes: 18 additions & 0 deletions bundler/tests/deno/deno-8545/input/entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Application, Router } from "https://raw.githubusercontent.com/kdy1/oak-bundle-issue/master/deps.ts";

const app = new Application();
const router = new Router();

router.get("/", (ctx) => {
ctx.response.body = "Index Page";
});

router.get("/users", (ctx) => {
ctx.response.body = "Users Page";
});

app.use(router.routes());
app.use(router.allowedMethods());

console.log(`Now listening on http://0.0.0.0:3000`);
await app.listen("0.0.0.0:3000");
2 changes: 1 addition & 1 deletion ecmascript/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs"]
license = "Apache-2.0/MIT"
name = "swc_ecma_codegen"
repository = "https://github.com/swc-project/swc.git"
version = "0.41.1"
version = "0.41.2"

[dependencies]
bitflags = "1"
Expand Down
5 changes: 4 additions & 1 deletion ecmascript/codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2463,8 +2463,11 @@ fn escape<'s>(cm: &SourceMap, span: Span, s: &'s str, single_quote: Option<bool>
}
'u' => match orig_iter.next() {
Some('{') => {
buf.push('{');
loop {
if orig_iter.next() == Some('}') {
let ch = orig_iter.next();
buf.extend(ch);
if ch == Some('}') {
break;
}
}
Expand Down
16 changes: 16 additions & 0 deletions ecmascript/codegen/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,22 @@ fn integration_01_reduced_01() {
);
}

#[test]
fn dneo_8541_1() {
test_from_to(
"React.createElement('span', null, '\\u{b7}');",
"React.createElement('span', null, '\\u{b7}');",
);
}

#[test]
fn dneo_8541_2() {
test_from_to(
"React.createElement('span', null, '\\u00b7');",
"React.createElement('span', null, '\\u00b7');",
);
}

#[derive(Debug, Clone)]
struct Buf(Arc<RwLock<Vec<u8>>>);
impl Write for Buf {
Expand Down
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/20aca21e32bf7772.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
('\u');
('\u{10FFFF}');
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/37c0f5275362d1c9.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"\u";
"\u{00000000034}";
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/4a0d9236bc523b77.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
('\u');
('\u{0000000000F8}');
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/78e1b8a4f3318967.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"\u\u";
"\u{714E}\u{8336}";
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/cf0eb6e6c4317c33.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
('\u');
('\u{00F8}');
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/d81d71f4121e3193.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
('\u');
('\u{0}');
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/e9682c37a1a959e1.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"\u\u\u";
"\u{20BB7}\u{91CE}\u{5BB6}";