diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index bc36e0c1e25ce..85c03f9a5cbc0 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -1414,9 +1414,33 @@ impl Gen for StringLiteral<'_> { fn gen(&self, p: &mut Codegen, _ctx: Context) { p.add_source_mapping(self.span); let s = self.value.as_str(); - p.wrap_quote(|p, quote| { - print_unquoted_str(s, quote, p); - }); + + let quote = if p.options.minify { + let mut single_cost: u32 = 0; + let mut double_cost: u32 = 0; + for b in s.as_bytes() { + match b { + b'\'' => { + single_cost += 1; + } + b'"' => { + double_cost += 1; + } + _ => {} + } + } + if double_cost > single_cost { + b'\'' + } else { + b'"' + } + } else { + p.quote + }; + + p.print_ascii_byte(quote); + print_unquoted_str(s, quote, p); + p.print_ascii_byte(quote); } } diff --git a/crates/oxc_codegen/src/lib.rs b/crates/oxc_codegen/src/lib.rs index f9c8e9e609821..7db7b14eda96f 100644 --- a/crates/oxc_codegen/src/lib.rs +++ b/crates/oxc_codegen/src/lib.rs @@ -636,13 +636,6 @@ impl<'a> Codegen<'a> { } } - #[inline] - fn wrap_quote(&mut self, mut f: F) { - self.print_ascii_byte(self.quote); - f(self, self.quote); - self.print_ascii_byte(self.quote); - } - fn add_source_mapping(&mut self, span: Span) { if span == SPAN { return; diff --git a/crates/oxc_codegen/tests/integration/snapshots/minify.snap b/crates/oxc_codegen/tests/integration/snapshots/minify.snap index 106343bda7138..cc86223f995c4 100644 --- a/crates/oxc_codegen/tests/integration/snapshots/minify.snap +++ b/crates/oxc_codegen/tests/integration/snapshots/minify.snap @@ -11,43 +11,43 @@ function foo(x: T, y: string, ...restOfParams: Omit): return x; } ---------- -function foo(x:T,y:string,...restOfParams:Omit): T{return x} +function foo(x:T,y:string,...restOfParams:Omit): T{return x} ########## 2 let x: string[] = ['abc', 'def', 'ghi']; ---------- -let x:string[]=['abc','def','ghi']; +let x:string[]=["abc","def","ghi"]; ########## 3 let x: Array = ['abc', 'def', 'ghi',]; ---------- -let x:Array=['abc','def','ghi']; +let x:Array=["abc","def","ghi"]; ########## 4 let x: [string, number] = ['abc', 123]; ---------- -let x:[string,number]=['abc',123]; +let x:[string,number]=["abc",123]; ########## 5 let x: string | number = 'abc'; ---------- -let x:string|number='abc'; +let x:string|number="abc"; ########## 6 let x: string & number = 'abc'; ---------- -let x:string&number='abc'; +let x:string&number="abc"; ########## 7 let x: typeof String = 'string'; ---------- -let x:typeof String='string'; +let x:typeof String="string"; ########## 8 let x: keyof string = 'length'; ---------- -let x:keyof string='length'; +let x:keyof string="length"; ########## 9 let x: keyof typeof String = 'length'; ---------- -let x:keyof typeof String='length'; +let x:keyof typeof String="length"; ########## 10 let x: string['length'] = 123; ---------- -let x:string['length']=123; +let x:string["length"]=123; ########## 11 function isString(value: unknown): asserts value is string { if (typeof value !== 'string') { @@ -55,19 +55,19 @@ function isString(value: unknown): asserts value is string { } } ---------- -function isString(value:unknown): asserts value is string{if(typeof value!=='string'){throw new Error('Not a string')}} +function isString(value:unknown): asserts value is string{if(typeof value!=="string"){throw new Error("Not a string")}} ########## 12 import type { Foo } from 'foo'; ---------- -import type{Foo}from'foo'; +import type{Foo}from"foo"; ########## 13 import { Foo, type Bar } from 'foo'; ---------- -import{Foo,type Bar}from'foo'; +import{Foo,type Bar}from"foo"; ########## 14 export { Foo, type Bar } from 'foo'; ---------- -export{Foo,type Bar}from'foo'; +export{Foo,type Bar}from"foo"; ########## 15 type A = { [K in keyof T as K extends string ? B : K ]: T[K] } ---------- @@ -75,7 +75,7 @@ type A={[K in keyof T as K extends string ? B : K]:T[K]}; ########## 16 class A {readonly type = 'frame'} ---------- -class A{readonly type='frame'} +class A{readonly type="frame"} ########## 17 let foo: { (t: T): void } ---------- @@ -196,4 +196,4 @@ export { default, /* …, */ } from "module-name"; export { default as name16 } from "module-name"; ---------- -import defaultExport from'module-name';import*as name from'module-name';import{export1}from'module-name';import{export1 as alias1}from'module-name';import{default as alias}from'module-name';import{export1,export2}from'module-name';import{export1,export2 as alias2}from'module-name';import{'string name' as alias}from'module-name';import defaultExport,{export1}from'module-name';import defaultExport,*as name from'module-name';import'module-name';import{}from"mod";export let name1,name2;export const name3=1,name4=2;export function functionName(){}export class ClassName{}export function*generatorFunctionName(){}export const {name5,name2:bar}=o;export const [name6,name7]=array;export{name8,name81};export{variable1 as name9,variable2 as name10,name82};export{variable1 as 'string name'};export{name1 as default1};export*from'module-name';export*as name11 from'module-name';export{name12,nameN}from'module-name';export{import1 as name13,import2 as name14,name15}from'module-name';export{default}from'module-name';export{default as name16}from'module-name'; +import defaultExport from"module-name";import*as name from"module-name";import{export1}from"module-name";import{export1 as alias1}from"module-name";import{default as alias}from"module-name";import{export1,export2}from"module-name";import{export1,export2 as alias2}from"module-name";import{"string name" as alias}from"module-name";import defaultExport,{export1}from"module-name";import defaultExport,*as name from"module-name";import"module-name";import{}from"mod";export let name1,name2;export const name3=1,name4=2;export function functionName(){}export class ClassName{}export function*generatorFunctionName(){}export const {name5,name2:bar}=o;export const [name6,name7]=array;export{name8,name81};export{variable1 as name9,variable2 as name10,name82};export{variable1 as "string name"};export{name1 as default1};export*from"module-name";export*as name11 from"module-name";export{name12,nameN}from"module-name";export{import1 as name13,import2 as name14,name15}from"module-name";export{default}from"module-name";export{default as name16}from"module-name"; diff --git a/tasks/minsize/minsize.snap b/tasks/minsize/minsize.snap index 862dd78370982..d7fa503d83eb5 100644 --- a/tasks/minsize/minsize.snap +++ b/tasks/minsize/minsize.snap @@ -1,27 +1,27 @@ | Oxc | ESBuild | Oxc | ESBuild | Original | minified | minified | gzip | gzip | Fixture ------------------------------------------------------------------------------------- -72.14 kB | 24.05 kB | 23.70 kB | 8.61 kB | 8.54 kB | react.development.js +72.14 kB | 24.04 kB | 23.70 kB | 8.61 kB | 8.54 kB | react.development.js -173.90 kB | 61.60 kB | 59.82 kB | 19.55 kB | 19.33 kB | moment.js +173.90 kB | 61.60 kB | 59.82 kB | 19.54 kB | 19.33 kB | moment.js 287.63 kB | 92.61 kB | 90.07 kB | 32.27 kB | 31.95 kB | jquery.js -342.15 kB | 121.77 kB | 118.14 kB | 44.58 kB | 44.37 kB | vue.js +342.15 kB | 121.57 kB | 118.14 kB | 44.64 kB | 44.37 kB | vue.js -544.10 kB | 73.37 kB | 72.48 kB | 26.13 kB | 26.20 kB | lodash.js +544.10 kB | 73.37 kB | 72.48 kB | 26.14 kB | 26.20 kB | lodash.js -555.77 kB | 276.22 kB | 270.13 kB | 91.15 kB | 90.80 kB | d3.js +555.77 kB | 276.21 kB | 270.13 kB | 91.16 kB | 90.80 kB | d3.js -1.01 MB | 467.14 kB | 458.89 kB | 126.74 kB | 126.71 kB | bundle.min.js +1.01 MB | 467.13 kB | 458.89 kB | 126.76 kB | 126.71 kB | bundle.min.js -1.25 MB | 662.66 kB | 646.76 kB | 164.00 kB | 163.73 kB | three.js +1.25 MB | 662.63 kB | 646.76 kB | 164.01 kB | 163.73 kB | three.js -2.14 MB | 740.54 kB | 724.14 kB | 181.37 kB | 181.07 kB | victory.js +2.14 MB | 740.53 kB | 724.14 kB | 181.38 kB | 181.07 kB | victory.js -3.20 MB | 1.02 MB | 1.01 MB | 332.09 kB | 331.56 kB | echarts.js +3.20 MB | 1.02 MB | 1.01 MB | 332.11 kB | 331.56 kB | echarts.js 6.69 MB | 2.39 MB | 2.31 MB | 495.63 kB | 488.28 kB | antd.js -10.95 MB | 3.55 MB | 3.49 MB | 909.67 kB | 915.50 kB | typescript.js +10.95 MB | 3.55 MB | 3.49 MB | 909.73 kB | 915.50 kB | typescript.js