-
Notifications
You must be signed in to change notification settings - Fork 18
/
transformer.js
135 lines (109 loc) · 4.02 KB
/
transformer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { execSync } from 'child_process'
import { basename, extname } from 'path'
import { pathToFileURL } from 'url'
import * as SvelteCompiler from 'svelte/compiler'
import { getSvelteConfig } from './svelteconfig.js'
import { dynamicImport, IS_COMMON_JS, isSvelte3, isSvelteModule } from './utils.js'
const currentFileExtension = (global.__dirname !== undefined ? extname(__filename) : extname(pathToFileURL(import.meta.url).toString())).replace('.', '')
/**
* Jest will only call this method when running in ESM mode.
*/
const processAsync = async (source, filename, jestOptions) => {
const options = jestOptions && jestOptions.transformerConfig ? jestOptions.transformerConfig : {}
const { preprocess, rootMode, debug } = options
if (IS_COMMON_JS) {
throw new Error('Running svelte-jester-transformer async in unsupported CJS mode')
}
if (debug) {
console.debug(`Running svelte-jester-transformer async in mode ${currentFileExtension}.`)
}
if (!preprocess) {
return compiler('esm', options, filename, source)
}
const svelteConfigPath = getSvelteConfig(rootMode, filename, preprocess)
const svelteConfig = await dynamicImport(svelteConfigPath)
const processed = await SvelteCompiler.preprocess(
source,
svelteConfig.default.preprocess || {},
{ filename }
)
return compiler('esm', options, filename, processed.code, processed.map)
}
/**
* Starts a new process, so it has a higher overhead than processAsync.
* However, Jest calls this method in CJS mode.
*/
const processSync = (source, filename, jestOptions) => {
const options = jestOptions && jestOptions.transformerConfig ? jestOptions.transformerConfig : {}
const { preprocess, rootMode, maxBuffer, showConsoleLog, debug, svelteVersion } = options
if (!isSvelte3(svelteVersion)) {
throw new Error('Jest is being called in CJS mode. You must use ESM mode in Svelte 4+')
}
if (!IS_COMMON_JS) {
throw new Error('Running svelte-jester-transformer sync in unsupported ESM mode')
}
if (debug) {
console.debug(`Running svelte-jester-transformer sync in mode ${currentFileExtension}.`)
}
if (!preprocess) {
return compiler('cjs', options, filename, source)
}
const svelteConfig = getSvelteConfig(rootMode, filename, preprocess)
const preprocessor = require.resolve('./preprocess.js')
const preprocessResult = execSync(
`node --unhandled-rejections=strict --abort-on-uncaught-exception "${preprocessor}"`,
{
env: { ...process.env, source, filename, svelteConfig, showConsoleLog },
maxBuffer: maxBuffer || 10 * 1024 * 1024
}
).toString()
const parsedPreprocessResult = JSON.parse(preprocessResult)
return compiler('cjs', options, filename, parsedPreprocessResult.code, parsedPreprocessResult.map)
}
const compiler = (format, options = {}, filename, processedCode, processedMap) => {
const opts = {
filename: basename(filename),
css: isSvelte3(options.svelteVersion) ? true : 'injected',
accessors: true,
dev: true,
sourcemap: processedMap,
...options.compilerOptions
}
if (isSvelte3(options.svelteVersion)) {
opts.format = format
}
const compile = isSvelteModule(filename) ? compileModule : compileComponent
let result
try {
result = compile(processedCode, opts)
} catch (error) {
let msg = error.message
if (error.frame) {
msg += '\n' + error.frame
}
console.error(msg)
throw error
}
if (options.debug) {
console.log(result.js.code)
}
const esInterop = format === 'cjs' ? 'Object.defineProperty(exports, "__esModule", { value: true });' : ''
return {
code: result.js.code + esInterop,
map: JSON.stringify(result.js.map)
}
}
const compileComponent = (processedCode, opts) => {
return SvelteCompiler.compile(processedCode, opts)
}
const compileModule = (processedCode, opts) => {
return SvelteCompiler.compileModule(processedCode, {
filename: opts.filename,
dev: opts.dev,
generate: opts.ssr ? 'server' : 'client'
})
}
export default {
process: processSync,
processAsync
}