185 lines
4.9 KiB
TypeScript
185 lines
4.9 KiB
TypeScript
import { buildSync, BuildFailure, BuildOptions } from 'esbuild'
|
|
import { existsSync, writeFileSync, unlinkSync } from 'fs'
|
|
import { DistPath, ScriptBase, ScriptPath } from './paths'
|
|
import { UserScriptMetaFull } from './types'
|
|
import readMeta from './readmeta'
|
|
import { format, Options } from 'prettier'
|
|
import { CLIArgs } from './main'
|
|
|
|
export default function (
|
|
name: string,
|
|
watchCallback: (meta: UserScriptMetaFull, error: string | null) => void,
|
|
PrettierConfig: Options,
|
|
CLIArgs: CLIArgs
|
|
): [UserScriptMetaFull, string | null] {
|
|
//read meta file
|
|
let [metaJson, metaString] = readMeta(name)
|
|
let pathDist = DistPath(name)
|
|
|
|
let result = runEsbuild(
|
|
{
|
|
entryPoints: [ScriptPath(name).main],
|
|
outfile: pathDist,
|
|
|
|
target: 'esnext',
|
|
platform: 'node',
|
|
format: 'esm',
|
|
|
|
bundle: true,
|
|
minify: CLIArgs.minify,
|
|
|
|
define: {
|
|
UserScriptName: `'${metaJson.name}'`,
|
|
UserScriptNamespace: `'${metaJson.namespace}'`,
|
|
UserScriptVersion: `'${metaJson.version}'`,
|
|
|
|
UserScriptDownloadURL: `'${metaJson.downloadURL}'`,
|
|
UserScriptSupportURL: `'${metaJson.supportURL}'`,
|
|
UserScriptHomepageURL: `'${metaJson.homepageURL}'`,
|
|
},
|
|
},
|
|
result => {
|
|
let error = runPostEsbuild(
|
|
name,
|
|
result,
|
|
metaString,
|
|
CLIArgs,
|
|
PrettierConfig
|
|
)
|
|
watchCallback(metaJson, error)
|
|
},
|
|
CLIArgs
|
|
)
|
|
|
|
let error = runPostEsbuild(
|
|
name,
|
|
result,
|
|
metaString,
|
|
CLIArgs,
|
|
PrettierConfig
|
|
)
|
|
|
|
return [metaJson, error]
|
|
}
|
|
|
|
function doErrorFile(
|
|
pathError: string,
|
|
pathOutFile: string,
|
|
error: string | null
|
|
) {
|
|
if (error !== null) {
|
|
writeFileSync(pathError, `${new Date().toISOString()}\n\n${error}`)
|
|
|
|
if (existsSync(pathOutFile)) {
|
|
unlinkSync(pathOutFile)
|
|
}
|
|
} else if (existsSync(pathError)) {
|
|
unlinkSync(pathError)
|
|
}
|
|
}
|
|
|
|
interface RunEsbuildResult {
|
|
content: string | null
|
|
error: string | null
|
|
errorRaw?: BuildFailure
|
|
}
|
|
|
|
function runEsbuild(
|
|
opts: BuildOptions,
|
|
watchCallback: (result: RunEsbuildResult) => void,
|
|
CLIArgs: CLIArgs
|
|
): RunEsbuildResult {
|
|
opts.write = false
|
|
if (CLIArgs.watch) {
|
|
opts.watch = {
|
|
onRebuild(err, res) {
|
|
if (err) {
|
|
watchCallback({
|
|
content: null,
|
|
error: (err as BuildFailure).message,
|
|
errorRaw: err,
|
|
})
|
|
} else if (res) {
|
|
let content = ''
|
|
if (res.outputFiles && res.outputFiles.length > 0) {
|
|
content = res.outputFiles[0].text
|
|
}
|
|
if (content === '') {
|
|
watchCallback({
|
|
content: null,
|
|
error: 'No output',
|
|
})
|
|
}
|
|
watchCallback({
|
|
content,
|
|
error: null,
|
|
})
|
|
} else {
|
|
watchCallback({
|
|
content: null,
|
|
error: 'No result',
|
|
})
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
try {
|
|
let res = buildSync(opts)
|
|
let content = ''
|
|
if (res.outputFiles && res.outputFiles.length > 0) {
|
|
content = clearFilenameComments(res.outputFiles[0].text)
|
|
}
|
|
if (content === '') {
|
|
return {
|
|
content: null,
|
|
error: 'No output',
|
|
}
|
|
}
|
|
return {
|
|
content,
|
|
error: null,
|
|
}
|
|
} catch (err) {
|
|
return {
|
|
content: null,
|
|
error: (err as BuildFailure).message,
|
|
}
|
|
}
|
|
}
|
|
|
|
function runPostEsbuild(
|
|
name: string,
|
|
result: RunEsbuildResult,
|
|
metaString: string,
|
|
CLIArgs: CLIArgs,
|
|
PrettierConfig: Options
|
|
) {
|
|
let error: string | null = null
|
|
let path = ScriptPath(name)
|
|
let pathDist = DistPath(name)
|
|
|
|
if (result.error) {
|
|
console.error(name, result.errorRaw || result.error)
|
|
error = result.error
|
|
} else if (result.content) {
|
|
let content = metaString + result.content
|
|
if (CLIArgs.prettier) {
|
|
content = format(content, PrettierConfig)
|
|
}
|
|
writeFileSync(pathDist, content)
|
|
} else {
|
|
console.error(name, 'No output')
|
|
}
|
|
|
|
doErrorFile(path.error, pathDist, error)
|
|
|
|
return error
|
|
}
|
|
|
|
//remove all filename comments
|
|
function clearFilenameComments(content: string): string {
|
|
let regexp = new RegExp(`//\\s*${ScriptBase}/.*(?:\\n|$)`, 'g')
|
|
return content.replace(regexp, '')
|
|
}
|