Power[] combines products with the same base automatically.
Exp[a x]*Exp[b x]
(* E^(a x + b x) *)
Power[c, a x]*Power[c, b x]
(* c^(a x + b x) *)
You cannot keep the factors separate except by preventing Times[] from evaluating, with one of the Hold* functions, Defer[], or Inactive as Gianluca shows.
I don't quite understand how you used ComplexExpand[] here.
If you're trying to get the output to look a certain way, here are some tools, assuming you wish to compute the output instead of typing it by hand. FactorList[] returns separate, unmultiplied factors in the form {base, exponent}. Power[] can be used to convert a pair back to exponential form. Times[] can be used to multiply the exponential forms. Unless you've done something in between, Times[] will return to the original expression, more or less:
FactorList@ExpandAll[Exp[(a + b) x]]
(* {{1, 1}, {E^(b x), 1}, {E^(a x), 1}} *)
Power @@@ FactorList@ExpandAll[Exp[(a + b) x]]
(* {1, E^(b x), E^(a x)} *)
Times @@ Power @@@ FactorList@ExpandAll[Exp[(a + b) x]]
(* E^(a x + b x) *)
To keep the exponentials from combining, we need to do something before multiplying. All four example codes show an output that looks like E^(b x) E^(a x). The first two return a held form of E^(b x) E^(a x) which prints out with HoldForm invisible. The last two codes output E^(b x) E^(a x) having "deferred" the evaluation of the expression.
Times @@
Replace[Power @@@ FactorList@ExpandAll[Exp[(a + b) x]],
e : Except[_?NumericQ] :> HoldForm[e], 1]
Times @@
HoldForm /@ Power @@@ FactorList@ExpandAll[Exp[(a + b) x]] /.
HoldForm[n_?NumericQ] :> n
(* HoldForm[E^(a*x)]*HoldForm[E^(b*x)] *)
Times @@ Hold /@ Power @@@ FactorList@ExpandAll[Exp[(a + b) x]] /.
HoldForm[n_?NumericQ] :> n // Defer[#] & //
ReplaceAll[Hold[e_] :> e]
Defer[#] &@
Replace[Power @@@ FactorList@ExpandAll[Exp[(a + b) x]],
List[n___?NumericQ, e : Except[_?NumericQ] ...] :>
n*Hold[Times[e]]] /. Hold[e_] :> e
(* E^(b x) E^(a x) *)
Obviously, working with FactorList[] takes some work. Part of the problem here is that I wanted the output to be E^(b x) E^(a x) and not 1 E^(b x) E^(a x). To get that, I needed to let Times[] evaluate the numeric factors but not the exponential factors. To do different things to the factors introduces complexity that is unavoidable.