176 lines
4.5 KiB
JavaScript
176 lines
4.5 KiB
JavaScript
import { minifySync } from '@swc/core'
|
|
import { rollup } from 'rollup'
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
import variantsFile from './variants.json' with { type: 'json' }
|
|
import { canSkipCompile } from './can-skip-compile.js'
|
|
import packageJson from '../package.json' with { type: 'json' }
|
|
import progress from 'cli-progress'
|
|
import { spawn, Worker, Pool } from 'threads'
|
|
import json from '@rollup/plugin-json'
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
|
|
export const DEFAULT_GLOBALS = {
|
|
COMPILE_PLAUSIBLE_WEB: false,
|
|
COMPILE_PLAUSIBLE_NPM: false,
|
|
COMPILE_PLAUSIBLE_LEGACY_VARIANT: false,
|
|
COMPILE_CONFIG: false,
|
|
COMPILE_HASH: false,
|
|
COMPILE_OUTBOUND_LINKS: false,
|
|
COMPILE_COMPAT: false,
|
|
COMPILE_LOCAL: false,
|
|
COMPILE_MANUAL: false,
|
|
COMPILE_FILE_DOWNLOADS: false,
|
|
COMPILE_PAGEVIEW_PROPS: false,
|
|
COMPILE_CUSTOM_PROPERTIES: false,
|
|
COMPILE_TAGGED_EVENTS: false,
|
|
COMPILE_REVENUE: false,
|
|
COMPILE_EXCLUSIONS: false,
|
|
COMPILE_TRACKER_SCRIPT_VERSION: packageJson.tracker_script_version
|
|
}
|
|
|
|
const ALL_VARIANTS = variantsFile.legacyVariants.concat(
|
|
variantsFile.manualVariants
|
|
)
|
|
|
|
function shouldCompileVariant(variant) {
|
|
const IS_CE = ['ce', 'ce_test', 'ce_dev'].includes(process.env.MIX_ENV)
|
|
const shouldCompileVariant = IS_CE && variant.ee_only ? false : true
|
|
return shouldCompileVariant
|
|
}
|
|
|
|
export async function compileAll(options = {}) {
|
|
if (process.env.NODE_ENV === 'dev' && canSkipCompile()) {
|
|
console.info(
|
|
'COMPILATION SKIPPED: No changes detected in tracker dependencies'
|
|
)
|
|
return
|
|
}
|
|
|
|
const bundledCode = await bundleCode()
|
|
|
|
const startTime = Date.now()
|
|
const variantsToCompile = ALL_VARIANTS.filter(shouldCompileVariant)
|
|
console.log(`Starting compilation of ${variantsToCompile.length} variants...`)
|
|
|
|
const bar = new progress.SingleBar(
|
|
{ clearOnComplete: true },
|
|
progress.Presets.shades_classic
|
|
)
|
|
bar.start(variantsToCompile.length, 0)
|
|
|
|
const workerPool = Pool(() => spawn(new Worker('./worker-thread.js')))
|
|
variantsToCompile.forEach((variant) => {
|
|
workerPool.queue(async (worker) => {
|
|
await worker.compileFile(variant, { ...options, bundledCode })
|
|
bar.increment()
|
|
})
|
|
})
|
|
|
|
await workerPool.completed()
|
|
await workerPool.terminate()
|
|
bar.stop()
|
|
|
|
console.log(
|
|
`Completed compilation of ${variantsToCompile.length} variants in ${((Date.now() - startTime) / 1000).toFixed(2)}s`
|
|
)
|
|
}
|
|
|
|
export async function compileFile(variant, options) {
|
|
const globals = { ...DEFAULT_GLOBALS, ...variant.globals }
|
|
let code
|
|
|
|
if (variant.entry_point) {
|
|
code = await bundleCode(variant.entry_point)
|
|
} else {
|
|
code = options.bundledCode || (await bundleCode())
|
|
}
|
|
|
|
if (!variant.npm_package) {
|
|
code = wrapInstantlyEvaluatingFunction(code)
|
|
}
|
|
|
|
code = minify(code, globals, variant)
|
|
|
|
if (variant.npm_package) {
|
|
code = addExports(code)
|
|
}
|
|
|
|
if (options.returnCode) {
|
|
return code
|
|
} else {
|
|
fs.writeFileSync(outputPath(variant, options), code)
|
|
}
|
|
}
|
|
|
|
function wrapInstantlyEvaluatingFunction(baseCode) {
|
|
return `(function(){${baseCode}})()`
|
|
}
|
|
|
|
// Works around minification limitation of swc not allowing exports
|
|
function addExports(code) {
|
|
return `${code}\nexport { init, track, DEFAULT_FILE_TYPES }`
|
|
}
|
|
|
|
export function compileWebSnippet() {
|
|
const code = fs.readFileSync(relPath('../src/web-snippet.js')).toString()
|
|
return `
|
|
<script>
|
|
${minify(code)}
|
|
plausible.init()
|
|
</script>
|
|
`
|
|
}
|
|
|
|
async function bundleCode(entryPoint = 'src/plausible.js') {
|
|
const bundle = await rollup({
|
|
input: entryPoint,
|
|
plugins: [json({ compact: true })]
|
|
})
|
|
|
|
const { output } = await bundle.generate({ format: 'esm' })
|
|
|
|
return output[0].code
|
|
}
|
|
|
|
function outputPath(variant, options) {
|
|
if (variant.output_path) {
|
|
return relPath(`../../${variant.output_path}${options.suffix || ''}`)
|
|
} else if (variant.npm_package) {
|
|
return relPath(`../${variant.name}${options.suffix || ''}`)
|
|
} else {
|
|
return relPath(
|
|
`../../priv/tracker/js/${variant.name}${options.suffix || ''}`
|
|
)
|
|
}
|
|
}
|
|
|
|
function minify(code, globals, variant = {}) {
|
|
const minifyOptions = {
|
|
compress: {
|
|
global_defs: globals,
|
|
passes: 4
|
|
},
|
|
mangle: {}
|
|
}
|
|
|
|
if (variant.npm_package) {
|
|
minifyOptions.mangle.reserved = ['init', 'track', 'DEFAULT_FILE_TYPES']
|
|
minifyOptions.mangle.toplevel = true
|
|
}
|
|
|
|
const result = minifySync(code, minifyOptions)
|
|
|
|
if (result.code) {
|
|
return result.code
|
|
} else {
|
|
throw result.error
|
|
}
|
|
}
|
|
|
|
function relPath(segment) {
|
|
return path.join(__dirname, segment)
|
|
}
|