Skip to content

Commit e97350b

Browse files
committed
refactor: simplify js generate
1 parent 60d8cf7 commit e97350b

File tree

2 files changed

+122
-213
lines changed

2 files changed

+122
-213
lines changed

packages/bundle-utils/src/js.ts

Lines changed: 109 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,16 @@ function _generate(
158158
const codeMaps = new Map<string, RawSourceMap>()
159159
const { type, sourceMap, isGlobal, locale, jit } = options
160160

161-
const codegenFn: CodeGenFunction = jit
161+
const _codegenFn: CodeGenFunction = jit
162162
? generateResourceAst
163163
: generateMessageFunction
164164

165+
function codegenFn(value: string) {
166+
const { code, map } = _codegenFn(value, options, pathStack)
167+
sourceMap && map != null && codeMaps.set(value, map)
168+
return code
169+
}
170+
165171
const componentNamespace = '_Component'
166172

167173
walk(node, {
@@ -173,174 +179,114 @@ function _generate(
173179
*/
174180
// @ts-ignore
175181
enter(node: Node, parent: Node) {
182+
if (parent?.type === 'ArrayExpression') {
183+
const lastIndex = itemsCountStack.length - 1
184+
const currentCount = parent.elements.length - itemsCountStack[lastIndex]
185+
186+
pathStack.push(currentCount.toString())
187+
itemsCountStack[lastIndex] = --itemsCountStack[lastIndex]
188+
}
189+
176190
switch (node.type) {
177191
case 'Program':
178192
if (type === 'plain') {
179193
generator.push(`const resource = `)
180194
} else if (type === 'sfc') {
181-
// for 'sfc'
182-
const variableName =
183-
type === 'sfc' ? (!isGlobal ? '__i18n' : '__i18nGlobal') : ''
184-
const localeName =
185-
type === 'sfc' ? (locale != null ? locale : `""`) : ''
186-
const exportSyntax = 'export default'
187-
generator.push(`${exportSyntax} function (Component) {`)
195+
const localeName = JSON.stringify(locale ?? '')
196+
const variableName = !isGlobal ? '__i18n' : '__i18nGlobal'
197+
generator.push(`export default function (Component) {`)
188198
generator.indent()
189-
const componentVariable = `Component`
190-
generator.pushline(
191-
`const ${componentNamespace} = ${componentVariable}`
192-
)
199+
generator.pushline(`const ${componentNamespace} = Component`)
193200
generator.pushline(
194201
`${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`
195202
)
196203
generator.push(`${componentNamespace}.${variableName}.push({`)
197204
generator.indent()
198-
generator.pushline(`"locale": ${JSON.stringify(localeName)},`)
205+
generator.pushline(`"locale": ${localeName},`)
199206
generator.push(`"resource": `)
200207
}
201208
break
202209
case 'ObjectExpression':
203-
generator.push(`{`)
210+
generator.push('{')
204211
generator.indent()
205212
propsCountStack.push(node.properties.length)
206-
if (parent != null && parent.type === 'ArrayExpression') {
207-
const lastIndex = itemsCountStack.length - 1
208-
const currentCount =
209-
parent.elements.length - itemsCountStack[lastIndex]
210-
pathStack.push(currentCount.toString())
211-
itemsCountStack[lastIndex] = --itemsCountStack[lastIndex]
212-
}
213-
break
214-
case 'Property':
215-
if (parent != null && parent.type === 'ObjectExpression') {
216-
if (node != null) {
217-
if (
218-
isJSONablePrimitiveLiteral(node.value) &&
219-
(node.key.type === 'Literal' || node.key.type === 'Identifier')
220-
) {
221-
// prettier-ignore
222-
const name = node.key.type === 'Literal'
223-
? String(node.key.value)
224-
: node.key.name
225-
if (
226-
(node.value.type === 'Literal' &&
227-
isString(node.value.value)) ||
228-
node.value.type === 'TemplateLiteral'
229-
) {
230-
const value = getValue(node.value) as string
231-
generator.push(`${JSON.stringify(name)}: `)
232-
pathStack.push(name)
233-
const { code, map } = codegenFn(value, options, pathStack)
234-
sourceMap && map != null && codeMaps.set(value, map)
235-
generator.push(`${code}`, node.value, value)
236-
skipStack.push(false)
237-
} else {
238-
const value = getValue(node.value)
239-
if (forceStringify) {
240-
const strValue = JSON.stringify(value)
241-
generator.push(`${JSON.stringify(name)}: `)
242-
pathStack.push(name)
243-
const { code, map } = codegenFn(
244-
strValue,
245-
options,
246-
pathStack
247-
)
248-
sourceMap && map != null && codeMaps.set(strValue, map)
249-
generator.push(`${code}`, node.value, strValue)
250-
} else {
251-
generator.push(
252-
`${JSON.stringify(name)}: ${JSON.stringify(value)}`
253-
)
254-
pathStack.push(name)
255-
}
256-
skipStack.push(false)
257-
}
258-
} else if (
259-
(node.value.type === 'FunctionExpression' ||
260-
node.value.type === 'ArrowFunctionExpression') &&
261-
(node.key.type === 'Literal' || node.key.type === 'Identifier')
262-
) {
263-
// prettier-ignore
264-
const name = node.key.type === 'Literal'
265-
? String(node.key.value)
266-
: node.key.name
267-
generator.push(`${JSON.stringify(name)}: `)
268-
pathStack.push(name)
269-
const code = generateJavaScript(node.value)
270-
generator.push(`${code}`, node.value, code)
271-
skipStack.push(false)
272-
} else if (
273-
(node.value.type === 'ObjectExpression' ||
274-
node.value.type === 'ArrayExpression') &&
275-
(node.key.type === 'Literal' || node.key.type === 'Identifier')
276-
) {
277-
// prettier-ignore
278-
const name = node.key.type === 'Literal'
279-
? String(node.key.value)
280-
: node.key.name
281-
generator.push(`${JSON.stringify(name)}: `)
282-
pathStack.push(name)
283-
} else {
284-
// for Regex, function, etc.
285-
skipStack.push(true)
286-
}
287-
}
288-
const lastIndex = propsCountStack.length - 1
289-
propsCountStack[lastIndex] = --propsCountStack[lastIndex]
290-
}
291213
break
292214
case 'ArrayExpression':
293-
generator.push(`[`)
215+
generator.push('[')
294216
generator.indent()
295-
if (parent != null && parent.type === 'ArrayExpression') {
296-
const lastIndex = itemsCountStack.length - 1
297-
const currentCount =
298-
parent.elements.length - itemsCountStack[lastIndex]
299-
pathStack.push(currentCount.toString())
300-
itemsCountStack[lastIndex] = --itemsCountStack[lastIndex]
301-
}
302217
itemsCountStack.push(node.elements.length)
303218
break
219+
case 'Property':
220+
if (parent?.type !== 'ObjectExpression') break
221+
if (node.key.type !== 'Literal' && node.key.type !== 'Identifier')
222+
break
223+
224+
// prettier-ignore
225+
const name = node.key.type === 'Literal'
226+
? String(node.key.value)
227+
: node.key.name
228+
const strName = JSON.stringify(name)
229+
if (isJSONablePrimitiveLiteral(node.value)) {
230+
generator.push(`${strName}: `)
231+
pathStack.push(name)
232+
const value = getValue(node.value) as string
233+
const strValue = JSON.stringify(value)
234+
if (
235+
(node.value.type === 'Literal' && isString(node.value.value)) ||
236+
node.value.type === 'TemplateLiteral'
237+
) {
238+
generator.push(codegenFn(value), node.value, value)
239+
} else if (forceStringify) {
240+
generator.push(codegenFn(strValue), node.value, strValue)
241+
} else {
242+
generator.push(strValue)
243+
}
244+
skipStack.push(false)
245+
} else if (
246+
node.value.type === 'ArrayExpression' ||
247+
node.value.type === 'ObjectExpression'
248+
) {
249+
generator.push(`${strName}: `)
250+
pathStack.push(name)
251+
skipStack.push(false)
252+
} else if (
253+
node.value.type === 'FunctionExpression' ||
254+
node.value.type === 'ArrowFunctionExpression'
255+
) {
256+
generator.push(`${strName}: `)
257+
pathStack.push(name)
258+
const code = generateJavaScript(node.value, {
259+
format: { compact: true }
260+
})
261+
generator.push(code, node.value, code)
262+
skipStack.push(false)
263+
} else {
264+
// for Regex, function, etc.
265+
skipStack.push(true)
266+
}
267+
const lastIndex = propsCountStack.length - 1
268+
propsCountStack[lastIndex] = --propsCountStack[lastIndex]
269+
break
304270
default:
305-
if (node != null && parent != null) {
306-
if (parent.type === 'ArrayExpression') {
307-
const lastIndex = itemsCountStack.length - 1
308-
const currentCount =
309-
parent.elements.length - itemsCountStack[lastIndex]
310-
pathStack.push(currentCount.toString())
311-
if (isJSONablePrimitiveLiteral(node)) {
312-
if (
313-
(node.type === 'Literal' && isString(node.value)) ||
314-
node.type === 'TemplateLiteral'
315-
) {
316-
const value = getValue(node) as string
317-
const { code, map } = codegenFn(value, options, pathStack)
318-
sourceMap && map != null && codeMaps.set(value, map)
319-
generator.push(`${code}`, node, value)
320-
} else {
321-
const value = getValue(node)
322-
if (forceStringify) {
323-
const strValue = JSON.stringify(value)
324-
const { code, map } = codegenFn(
325-
strValue,
326-
options,
327-
pathStack
328-
)
329-
sourceMap && map != null && codeMaps.set(strValue, map)
330-
generator.push(`${code}`, node, strValue)
331-
} else {
332-
generator.push(`${JSON.stringify(value)}`)
333-
}
334-
}
335-
skipStack.push(false)
271+
if (parent?.type === 'ArrayExpression') {
272+
if (isJSONablePrimitiveLiteral(node)) {
273+
const value = getValue(node) as string
274+
const strValue = JSON.stringify(value)
275+
if (
276+
(node.type === 'Literal' && isString(node.value)) ||
277+
node.type === 'TemplateLiteral'
278+
) {
279+
generator.push(codegenFn(value), node, value)
280+
} else if (forceStringify) {
281+
generator.push(codegenFn(strValue), node, strValue)
336282
} else {
337-
// for Regex, function, etc.
338-
skipStack.push(true)
283+
generator.push(strValue)
339284
}
340-
itemsCountStack[lastIndex] = --itemsCountStack[lastIndex]
285+
skipStack.push(false)
286+
} else {
287+
// for Regex, function, etc.
288+
skipStack.push(true)
341289
}
342-
} else {
343-
// ...
344290
}
345291
break
346292
}
@@ -355,14 +301,14 @@ function _generate(
355301
leave(node: Node, parent: Node) {
356302
switch (node.type) {
357303
case 'Program':
358-
if (type === 'sfc') {
304+
if (type === 'plain') {
305+
generator.push('\n')
306+
generator.push('export default resource')
307+
} else if (type === 'sfc') {
359308
generator.deindent()
360-
generator.push(`})`)
309+
generator.push('})')
361310
generator.deindent()
362-
generator.pushline(`}`)
363-
} else if (type === 'plain') {
364-
generator.push(`\n`)
365-
generator.push('export default resource')
311+
generator.pushline('}')
366312
}
367313
break
368314
case 'ObjectExpression':
@@ -371,57 +317,31 @@ function _generate(
371317
propsCountStack.pop()
372318
}
373319
generator.deindent()
374-
generator.push(`}`)
375-
if (parent != null && parent.type === 'ArrayExpression') {
376-
if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
377-
pathStack.pop()
378-
generator.pushline(`,`)
379-
}
380-
}
381-
break
382-
case 'Property':
383-
if (parent != null && parent.type === 'ObjectExpression') {
384-
if (propsCountStack[propsCountStack.length - 1] !== 0) {
385-
pathStack.pop()
386-
if (!skipStack.pop()) {
387-
generator.pushline(`,`)
388-
}
389-
}
390-
}
320+
generator.push('}')
391321
break
392322
case 'ArrayExpression':
393323
if (itemsCountStack[itemsCountStack.length - 1] === 0) {
394324
pathStack.pop()
395325
itemsCountStack.pop()
396326
}
397327
generator.deindent()
398-
generator.push(`]`)
399-
if (parent != null && parent.type === 'ArrayExpression') {
400-
if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
401-
pathStack.pop()
402-
if (!skipStack.pop()) {
403-
generator.pushline(`,`)
404-
}
405-
}
406-
}
407-
break
408-
case 'Literal':
409-
if (parent != null && parent.type === 'ArrayExpression') {
410-
if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
411-
pathStack.pop()
412-
if (!skipStack.pop()) {
413-
generator.pushline(`,`)
414-
}
415-
} else {
416-
if (!skipStack.pop()) {
417-
generator.pushline(`,`)
418-
}
419-
}
420-
}
328+
generator.push(']')
421329
break
422330
default:
423331
break
424332
}
333+
334+
if (
335+
parent?.type === 'ArrayExpression' ||
336+
parent?.type === 'ObjectExpression'
337+
) {
338+
const stackArr =
339+
node.type === 'Property' ? propsCountStack : itemsCountStack
340+
if (stackArr[stackArr.length - 1] !== 0) {
341+
pathStack.pop()
342+
!skipStack.pop() && generator.pushline(',')
343+
}
344+
}
425345
}
426346
})
427347

0 commit comments

Comments
 (0)