/
esbuild.js
111 lines (97 loc) · 2.91 KB
/
esbuild.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
const { generateIslands, generateIslandsWithSource } = require('./lib/plugin')
const { writeFileSync } = require('fs')
const { mkdir, readFile } = require('fs/promises')
const { dirname } = require('path')
const esbuild = require('esbuild')
const { resolveTsConfig } = require('./lib/typescript')
const { defu } = require('defu')
exports = module.exports = esbuildPlugin
/**@type {import("../lib/types").ESbuildOptions} */
const defaultOptions = {
rootDir: '.',
baseURL: '/public',
atomic: true,
hash: false,
tsconfig: './tsconfig.json',
client: {
tsconfig: './tsconfig.json',
output: './dist/client',
replaceParentNode: false,
},
}
/**
* @param {import('../lib/types').ESbuildOptions} options
* @returns
*/
function esbuildPlugin(options = defaultOptions) {
options = defu(options, defaultOptions)
return {
name: 'preact-island-plugin',
async setup(build) {
build.onLoad({ filter: /\.(js|ts)x?$/ }, async args => {
let generatorOutput
if (args.path.endsWith('.ts') || args.path.endsWith('.tsx')) {
let isIsland = false
const sourceCode = await readFile(args.path, 'utf8')
if (
sourceCode.indexOf('//@island') > -1 ||
sourceCode.indexOf('// @island') > -1
) {
isIsland = true
}
const esbuildTransformOptions = Object.assign(
{},
(options && options.esbuild) || {}
)
const jsCode = await esbuild.transform(sourceCode, {
loader: 'tsx',
platform: 'node',
target: 'node16',
jsx: 'preserve',
tsconfigRaw: {
...(await resolveTsConfig(options.tsconfig)),
},
...esbuildTransformOptions,
})
let inputCode = jsCode.code
if (isIsland) {
inputCode = '//@island\n' + inputCode
}
generatorOutput = generateIslandsWithSource(
inputCode,
args.path,
options
)
} else {
generatorOutput = generateIslands(args.path, options)
}
const { code, paths } = generatorOutput
if (paths.client) {
await mkdir(dirname(paths.client), { recursive: true })
writeFileSync(paths.client, code.client, 'utf8')
await esbuild.build({
entryPoints: [paths.client],
bundle: true,
allowOverwrite: true,
outfile: paths.client,
tsconfigRaw: {
...(await resolveTsConfig(
options.client && options.client.tsconfig
)),
},
platform: 'browser',
jsx: 'automatic',
jsxImportSource: 'preact',
loader: {
'.js': 'jsx',
},
})
}
return {
contents: code.server,
loader: 'jsx',
}
})
},
}
}