| 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}})()` |
| } |
|
|
| |
| 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) |
| } |
|
|