Repository: parcel-bundler/parcel
File: packages/transformers/js/src/dependency_collector.rs (Rust)

Code before:
      self.require_node = Some(call.clone());
      return call;
    }

    return node.fold_children_with(self);
  }

  fn fold_new_expr(&mut self, node: ast::NewExpr) -> ast::NewExpr {
    use ast::Expr::*;

    let matched = match &*node.callee {
      Ident(id) => {
        match id.sym {
          js_word!("Worker") | js_word!("SharedWorker") => {
            // Bail if defined in scope
            !self.decls.contains(&(id.sym.clone(), id.span.ctxt()))
          }
          js_word!("Promise") => {
            // Match requires inside promises (e.g. Rollup compiled dynamic imports)
            // new Promise(resolve => resolve(require('foo')))
            // new Promise(resolve => { resolve(require('foo')) })
            // new Promise(function (resolve) { resolve(require('foo')) })
            let was_in_promise = self.in_promise;
            self.in_promise = true;
            let node = swc_ecmascript::visit::fold_new_expr(self, node);
            self.in_promise = was_in_promise;
            return node;
          }
          _ => false,
        }
      }
      _ => false,
    };

    if !matched {
      return node.fold_children_with(self);
    }

    if let Some(args) = &node.args {
      if args.len() > 0 {
        let (specifier, span) = if let Some(s) = match_import_meta_url(&*args[0].expr, self.decls) {
          s
        } else if let Lit(lit) = &*args[0].expr {
          if let ast::Lit::Str(str_) = lit {
            (str_.value.clone(), str_.span)
          } else {
            return node;
          }
        } else {
          return node;
        };

Review comment (suggestion):
Seems like `fold_member_expr` is missing.
All passes touching identifier should implement it and fold `prop` only if `computed` is true.

Code after:
    } else if kind == DependencyKind::Require {
      // Don't continue traversing so that the `require` isn't replaced with undefined
      node
    } else {
      node.fold_children_with(self)
    }
  }

  fn fold_unary_expr(&mut self, node: ast::UnaryExpr) -> ast::UnaryExpr {
    // Don't traverse `typeof require` further to `require` with undefined
    if let ast::UnaryExpr {
      op: ast::UnaryOp::TypeOf,
      arg,
      ..
    } = &node
    {
      if let ast::Expr::Ident(ast::Ident { sym, .. }) = &**arg {
        if sym == &js_word!("require") && !self.decls.contains(&(sym.clone(), node.span.ctxt())) {
          return node;
        }
      }
    }

    node.fold_children_with(self)
  }

  fn fold_new_expr(&mut self, node: ast::NewExpr) -> ast::NewExpr {
    use ast::Expr::*;

    let matched = match &*node.callee {
      Ident(id) => {
        match id.sym {
          js_word!("Worker") | js_word!("SharedWorker") => {
            // Bail if defined in scope
            !self.decls.contains(&(id.sym.clone(), id.span.ctxt()))
          }
          js_word!("Promise") => {
            // Match requires inside promises (e.g. Rollup compiled dynamic imports)
            // new Promise(resolve => resolve(require('foo')))
            // new Promise(resolve => { resolve(require('foo')) })
            // new Promise(function (resolve) { resolve(require('foo')) })
            let was_in_promise = self.in_promise;
            self.in_promise = true;
            let node = swc_ecmascript::visit::fold_new_expr(self, node);
            self.in_promise = was_in_promise;
            return node;
          }
          _ => false,
        }
      }
      _ => false,