Skip to content

Commit

Permalink
fix cjs __exportStar not used (close #389)
Browse files Browse the repository at this point in the history
  • Loading branch information
ije committed Aug 5, 2022
1 parent 6f651ad commit 007ac43
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 26 deletions.
2 changes: 1 addition & 1 deletion packages/esm-cjs-lexer/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/esm-cjs-lexer/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "esm-cjs-lexer"
version = "0.7.3"
version = "0.7.4"
description = "A WASM module to parse commonjs exports for ESM."
repository = "https://github.com/ije/esm.sh"
license = "MIT"
Expand Down
26 changes: 14 additions & 12 deletions packages/esm-cjs-lexer/src/cjs.rs
Expand Up @@ -25,8 +25,8 @@ pub struct ExportsParser {
pub node_env: String,
pub call_mode: bool,
pub fn_returned: bool,
pub idents: IndexMap<String, IdentKind>,
pub exports_alias: IndexSet<String>,
pub idents: IndexMap<String, IdentKind>,
pub exports: IndexSet<String>,
pub reexports: IndexSet<String>,
}
Expand Down Expand Up @@ -397,8 +397,8 @@ impl ExportsParser {
}

// var foo = module.exports = {};
// foo.bar = function() {};
fn mark_exports_alias(&mut self, decl: &VarDeclarator) {
// foo === module.exports;
fn try_to_mark_exports_alias(&mut self, decl: &VarDeclarator) {
if let Pat::Ident(id) = &decl.name {
if let Some(init) = &decl.init {
if is_member(init, "module", "exports") {
Expand Down Expand Up @@ -545,7 +545,7 @@ impl ExportsParser {
Stmt::Decl(decl) => match decl {
Decl::Var(var) => {
for decl in &var.decls {
self.mark_exports_alias(decl);
self.try_to_mark_exports_alias(decl);
match &decl.name {
Pat::Ident(BindingIdent { id, .. }) => {
let id = id.sym.as_ref();
Expand Down Expand Up @@ -659,13 +659,9 @@ impl ExportsParser {
self.idents.insert(obj_name.into(), IdentKind::Object(props));
} else if let Some(FnDesc { stmts, mut extends }) = self.as_function(obj) {
extends.push(key.to_owned());
self.idents.insert(
obj_name.into(),
IdentKind::Fn(FnDesc {
stmts: stmts,
extends: extends,
}),
);
self
.idents
.insert(obj_name.into(), IdentKind::Fn(FnDesc { stmts, extends }));
}
}
}
Expand Down Expand Up @@ -740,7 +736,7 @@ impl ExportsParser {
// var foo = exports.foo || (exports.foo = {})
Stmt::Decl(Decl::Var(VarDecl { decls, .. })) => {
for decl in decls {
self.mark_exports_alias(decl);
self.try_to_mark_exports_alias(decl);
if let Some(init_expr) = &decl.init {
for bare_export_name in self.get_bare_export_names(init_expr) {
self.exports.insert(bare_export_name);
Expand All @@ -767,6 +763,8 @@ impl ExportsParser {
// Object.assign(module, { exports: require('lib') })
// (function() { ... })()
// require("tslib").__exportStar(..., exports)
// tslib.__exportStar(..., exports)
// __exportStar(..., exports)
Expr::Call(call) => {
if is_object_static_mothod_call(&call, "defineProperty") && call.args.len() >= 3 {
let arg0 = &call.args[0];
Expand Down Expand Up @@ -1099,6 +1097,7 @@ fn is_iife_call(call: &CallExpr) -> Option<Vec<Stmt>> {
// (0, require("tslib").__exportStar)(..., exports)
// const tslib = require("tslib"); (0, tslib.__exportStar)(..., exports)
// const {__exportStar} = require("tslib"); (0, __exportStar)(..., exports)
// const __exportStar = () => {}; __exportStar(..., exports)
fn is_tslib_export_star_call(call: &CallExpr) -> bool {
if let Some(callee) = with_expr_callee(call) {
match callee {
Expand All @@ -1107,6 +1106,9 @@ fn is_tslib_export_star_call(call: &CallExpr) -> bool {
return prop.sym.as_ref().eq("__exportStar");
}
}
Expr::Ident(id) => {
return id.sym.as_ref().eq("__exportStar");
}
Expr::Paren(ParenExpr { expr, .. }) => match expr.as_ref() {
Expr::Member(MemberExpr { prop, .. }) => {
if let Expr::Ident(prop) = prop.as_ref() {
Expand Down
28 changes: 28 additions & 0 deletions packages/esm-cjs-lexer/src/test.rs
Expand Up @@ -136,6 +136,19 @@ mod tests {
assert_eq!(reexports.join(","), "lib");
}

#[test]
fn parse_cjs_exports_case_9_1() {
let source = r#"
var lib = require("lib")
module.exports = lib
"#;
let swc = SWC::parse("index.cjs", source).expect("could not parse module");
let (_, reexports) = swc
.parse_cjs_exports("development", false)
.expect("could not parse exports");
assert_eq!(reexports.join(","), "lib");
}

#[test]
fn parse_cjs_exports_case_10() {
let source = r#"
Expand Down Expand Up @@ -603,6 +616,21 @@ mod tests {
assert_eq!(reexorts.join(","), "./crossPlatformSha256");
}

#[test]
fn parse_cjs_exports_case_19_5() {
let source = r#"
var __exportStar = function() {}
Object.defineProperty(exports, "foo", { value: 1 });
__exportStar(require("./bar"), exports);
"#;
let swc = SWC::parse("index.cjs", source).expect("could not parse module");
let (exports, reexorts) = swc
.parse_cjs_exports("production", true)
.expect("could not parse exports");
assert_eq!(exports.join(","), "foo");
assert_eq!(reexorts.join(","), "./bar");
}

#[test]
fn parse_cjs_exports_case_20_1() {
let source = r#"
Expand Down
18 changes: 9 additions & 9 deletions packages/esm-node-services/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/esm-node-services/package.json
@@ -1,6 +1,6 @@
{
"name": "esm-node-services",
"version": "0.7.2",
"version": "0.7.3",
"description": "Node services for esm.sh",
"main": "index.js",
"scripts": {
Expand All @@ -12,7 +12,7 @@
"index.js"
],
"dependencies": {
"esm-cjs-lexer": "^0.7.3",
"esm-cjs-lexer": "^0.7.4",
"enhanced-resolve": "^5.10.0"
},
"repository": "https://github.com/ije/esm.sh",
Expand Down
2 changes: 1 addition & 1 deletion server/node_services.go
Expand Up @@ -189,7 +189,7 @@ func parseCJSModuleExports(buildDir string, importPath string, nodeEnv string) (
return
}

fmt.Println(ret)
fmt.Println(ret, err)
if ret.Error != "" {
if ret.Stack != "" {
log.Errorf("[ns] parseCJSModuleExports: %s\n---\n%s\n---", ret.Error, ret.Stack)
Expand Down
7 changes: 7 additions & 0 deletions test/issue-389/issue-389.test.ts
@@ -0,0 +1,7 @@
import { equal } from "https://deno.land/std@0.145.0/testing/asserts.ts";

import { Value } from "http://localhost:8080/@sinclair/typebox@0.24.27/value?dev";

Deno.test("issue #389", () => {
equal(typeof Value, "function");
});

0 comments on commit 007ac43

Please sign in to comment.