Merge branch 'main' of git.zomo.dev:zomo/browser-scripts-builder into main
This commit is contained in:
187
src/build.ts
187
src/build.ts
@@ -1,34 +1,32 @@
|
||||
import { build, BuildFailure } from 'esbuild'
|
||||
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'fs'
|
||||
import { DistPath, ScriptPath } from './paths'
|
||||
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 async function (
|
||||
export default function (
|
||||
name: string,
|
||||
watchCallback:
|
||||
| ((meta: UserScriptMetaFull, error: string | null) => void)
|
||||
| false = false
|
||||
): Promise<[UserScriptMetaFull, string | null]> {
|
||||
watchCallback: (meta: UserScriptMetaFull, error: string | null) => void,
|
||||
PrettierConfig: Options,
|
||||
CLIArgs: CLIArgs
|
||||
): [UserScriptMetaFull, string | null] {
|
||||
//read meta file
|
||||
let [metaJson, metaString] = readMeta(name)
|
||||
let outPath = DistPath(name)
|
||||
let pathDist = DistPath(name)
|
||||
|
||||
let error: string | null = null
|
||||
|
||||
console.log('build watch?', !watchCallback ? false : 'obj')
|
||||
|
||||
try {
|
||||
await build({
|
||||
let result = runEsbuild(
|
||||
{
|
||||
entryPoints: [ScriptPath(name).main],
|
||||
outfile: outPath,
|
||||
outfile: pathDist,
|
||||
|
||||
target: 'esnext',
|
||||
platform: 'node',
|
||||
format: 'esm',
|
||||
|
||||
bundle: true,
|
||||
minify: false,
|
||||
minify: CLIArgs.minify,
|
||||
|
||||
define: {
|
||||
UserScriptName: `'${metaJson.name}'`,
|
||||
@@ -39,21 +37,148 @@ export default async function (
|
||||
UserScriptSupportURL: `'${metaJson.supportURL}'`,
|
||||
UserScriptHomepageURL: `'${metaJson.homepageURL}'`,
|
||||
},
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(name, err)
|
||||
error = (err as BuildFailure).message
|
||||
}
|
||||
},
|
||||
result => {
|
||||
let error = runPostEsbuild(
|
||||
name,
|
||||
result,
|
||||
metaString,
|
||||
CLIArgs,
|
||||
PrettierConfig
|
||||
)
|
||||
watchCallback(metaJson, error)
|
||||
},
|
||||
CLIArgs
|
||||
)
|
||||
|
||||
//add UserScript header
|
||||
if (existsSync(outPath)) {
|
||||
if (!error) {
|
||||
let content = readFileSync(outPath).toString()
|
||||
writeFileSync(outPath, metaString + content)
|
||||
} else {
|
||||
unlinkSync(outPath)
|
||||
}
|
||||
}
|
||||
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, '')
|
||||
}
|
||||
|
||||
123
src/main.ts
123
src/main.ts
@@ -1,22 +1,23 @@
|
||||
import {
|
||||
existsSync,
|
||||
lstatSync,
|
||||
readdirSync,
|
||||
unlinkSync,
|
||||
writeFileSync,
|
||||
} from 'fs'
|
||||
import { existsSync, lstatSync, readdirSync, unlinkSync } from 'fs'
|
||||
import commandLineArgs from 'command-line-args'
|
||||
import { DistBase, DistPath, ScriptBase, ScriptPath } from './paths'
|
||||
import { resolveConfig } from 'prettier'
|
||||
import { DistBase, ScriptBase, ScriptPath } from './paths'
|
||||
import { readmeData, updateReadmeFile } from './readmefile'
|
||||
import runBuild from './build'
|
||||
import { UserScriptMetaFull } from './types'
|
||||
|
||||
const CLIArgs = commandLineArgs([
|
||||
{ name: 'watch', alias: 'w', type: Boolean },
|
||||
]) as {
|
||||
export interface CLIArgs {
|
||||
watch: boolean
|
||||
minify: boolean
|
||||
prettier: boolean
|
||||
}
|
||||
|
||||
const CLIArgs = commandLineArgs([
|
||||
{ name: 'watch', alias: 'w', type: Boolean, defaultValue: false },
|
||||
{ name: 'minify', alias: 'm', type: Boolean, defaultValue: false },
|
||||
{ name: 'prettier', alias: 'p', type: Boolean, defaultValue: false },
|
||||
]) as CLIArgs
|
||||
|
||||
//if package.json doesn't exist then there is no point in continuing
|
||||
if (!existsSync('package.json') || !lstatSync('package.json').isFile()) {
|
||||
console.error('package.json not found, unwilling to run')
|
||||
@@ -26,66 +27,54 @@ if (!existsSync('package.json') || !lstatSync('package.json').isFile()) {
|
||||
//delete compiled scripts
|
||||
readdirSync(DistBase).forEach(file => unlinkSync(`${DistBase}/${file}`))
|
||||
|
||||
//compile scripts
|
||||
;(async () => {
|
||||
let scripts = readdirSync(ScriptBase)
|
||||
let scriptMeta: readmeData[] = []
|
||||
|
||||
for (let name of scripts) {
|
||||
let path = ScriptPath(name)
|
||||
|
||||
if (
|
||||
!name.endsWith('_') &&
|
||||
existsSync(path.dir) &&
|
||||
lstatSync(path.dir).isDirectory() &&
|
||||
existsSync(path.main) &&
|
||||
lstatSync(path.main).isFile()
|
||||
) {
|
||||
let id = scriptMeta.length
|
||||
|
||||
function postWatchUpdate(
|
||||
meta: UserScriptMetaFull,
|
||||
error: string | null
|
||||
) {
|
||||
console.log('watch callback')
|
||||
scriptMeta[id] = { meta, error }
|
||||
doErrorFile(path.error, DistPath(name), error)
|
||||
|
||||
console.log('WATCH', name, meta.version)
|
||||
|
||||
updateReadmeFile(scriptMeta)
|
||||
}
|
||||
|
||||
let [meta, error] = await runBuild(
|
||||
name,
|
||||
CLIArgs.watch ? postWatchUpdate : false
|
||||
)
|
||||
scriptMeta[id] = { meta, error }
|
||||
|
||||
console.log(name, meta.version)
|
||||
|
||||
doErrorFile(path.error, DistPath(name), error)
|
||||
}
|
||||
//read prettierrc file and make sure `babel` is the configured parser
|
||||
const PrettierConfig = (() => {
|
||||
let config = resolveConfig.sync(process.cwd()) || {}
|
||||
return {
|
||||
...config,
|
||||
parser: 'babel',
|
||||
}
|
||||
|
||||
updateReadmeFile(scriptMeta)
|
||||
|
||||
console.log('\nFinished Compiling\n')
|
||||
if (CLIArgs.watch) console.log('Listening for Changes\n')
|
||||
})()
|
||||
|
||||
function doErrorFile(
|
||||
pathError: string,
|
||||
pathOutFile: string,
|
||||
error: string | null
|
||||
) {
|
||||
if (error !== null) {
|
||||
writeFileSync(pathError, `${new Date().toISOString()}\n\n${error}`)
|
||||
//compile scripts
|
||||
let scripts = readdirSync(ScriptBase)
|
||||
let scriptMeta: readmeData[] = []
|
||||
|
||||
if (existsSync(pathOutFile)) {
|
||||
unlinkSync(pathOutFile)
|
||||
for (let name of scripts) {
|
||||
let path = ScriptPath(name)
|
||||
|
||||
if (
|
||||
!name.endsWith('_') &&
|
||||
existsSync(path.dir) &&
|
||||
lstatSync(path.dir).isDirectory() &&
|
||||
existsSync(path.main) &&
|
||||
lstatSync(path.main).isFile()
|
||||
) {
|
||||
let id = scriptMeta.length
|
||||
|
||||
function postWatchUpdate(
|
||||
meta: UserScriptMetaFull,
|
||||
error: string | null
|
||||
) {
|
||||
scriptMeta[id] = { meta, error }
|
||||
console.log('WATCH', name, meta.version)
|
||||
updateReadmeFile(scriptMeta)
|
||||
}
|
||||
} else if (existsSync(pathError)) {
|
||||
unlinkSync(pathError)
|
||||
|
||||
let [meta, error] = runBuild(
|
||||
name,
|
||||
postWatchUpdate,
|
||||
PrettierConfig,
|
||||
CLIArgs
|
||||
)
|
||||
scriptMeta[id] = { meta, error }
|
||||
|
||||
console.log(name, meta.version)
|
||||
}
|
||||
}
|
||||
|
||||
updateReadmeFile(scriptMeta)
|
||||
|
||||
console.log(
|
||||
`\nFinished Compiling\n${CLIArgs.watch ? 'Listening for Changes\n' : ''}`
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user