From 0d3cfc219704730df2a0e920cd514d32714a031b Mon Sep 17 00:00:00 2001 From: Marais Rossouw Date: Fri, 27 Aug 2021 19:54:38 +1000 Subject: [PATCH] feat: build diary core for platform (#17) --- bin/build.js | 60 ++++++++++++++++++++++++++++++++----------------- package.json | 14 +++++++++--- readme.md | 32 +++++++++++++------------- src/global.d.ts | 6 +++++ src/index.ts | 21 +++++++++++------ test/setup.js | 1 + tsconfig.json | 2 +- 7 files changed, 89 insertions(+), 47 deletions(-) create mode 100644 src/global.d.ts create mode 100644 test/setup.js diff --git a/bin/build.js b/bin/build.js index 19a9b10..595521a 100644 --- a/bin/build.js +++ b/bin/build.js @@ -3,28 +3,43 @@ const esbuild = require('esbuild'); const externals = ['diary/utils', 'diary']; -/** - * @param {string} input - * @param {Record<'import'|'require', string>} files - */ -async function bundle(input, files) { - await esbuild.build({ - entryPoints: [input], - bundle: true, - format: 'esm', - platform: 'neutral', - outfile: files.import, - external: externals, - }); +const targets = ['browser', 'worker']; - await esbuild.build({ - entryPoints: [input], - bundle: true, - format: 'cjs', - platform: 'neutral', - outfile: files.require, - external: externals, - }); +async function bundle(input, files, env, neutral) { + const is_neutral_block = Object.keys(files).some(i => targets.includes(i)); + + for (let target of Object.keys(files)) { + const is_neutral = neutral === undefined + ? !targets.includes(target) + : neutral; + + if (!is_neutral && typeof files[target] === 'object') { + await bundle(input, files[target], target, is_neutral); + + continue; + } + + if (!env && is_neutral_block) env = 'node'; + + const format = target === 'import' ? 'esm' : 'cjs'; + const platform = is_neutral ? 'neutral' : ((env === 'worker' ? 'browser' : env) || 'neutral'); + const trg = env || 'neutral'; + + console.log('~> [%s] format: %s platform: %s target: %s', input, format, platform, trg); + + await esbuild.build({ + entryPoints: [input], + bundle: true, + format, + platform, + outfile: files[target], + external: externals, + minifySyntax: true, + define: { + __TARGET__: `"${trg}"`, + }, + }); + } } Promise.all([ @@ -39,5 +54,8 @@ Promise.all([ outfile: 'diary/index.min.js', minify: true, external: externals, + define: { + __TARGET__: '"browser"', + }, }), ]); diff --git a/package.json b/package.json index 824825a..9c8ddca 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,16 @@ "sideEffects": false, "exports": { ".": { - "import": "./diary/index.mjs", - "require": "./diary/index.js" + "worker": { + "import": "./diary/worker/index.mjs", + "require": "./diary/worker/index.js" + }, + "browser": { + "import": "./diary/browser/index.mjs", + "require": "./diary/browser/index.js" + }, + "import": "./diary/node/index.mjs", + "require": "./diary/node/index.js" }, "./json": { "import": "./json/index.mjs", @@ -52,7 +60,7 @@ "bench": "cross-env TS_NODE_PROJECT=tsconfig.test.json DEBUG=standard ROARR_LOG=true node -r ts-eager/register bench/index.ts", "build": "node bin/build && tsc --emitDeclarationOnly", "fmt": "prettier --write --list-different \"{*,bench/**/*,.github/**/*,test/*}.+(ts|json|yml|md)\"", - "test": "cross-env TS_NODE_PROJECT=tsconfig.test.json uvu -r ts-eager/register -i helpers.ts test", + "test": "cross-env TS_NODE_PROJECT=tsconfig.test.json uvu -r ts-eager/register -r test/setup.js -i helpers.ts -i setup.js test", "typecheck": "tsc --noEmit" }, "prettier": { diff --git a/readme.md b/readme.md index c580aa6..cc18ac4 100644 --- a/readme.md +++ b/readme.md @@ -48,13 +48,12 @@ scopedDiary.info('this other important thing happened'); Controlling runtime emission of logs: -### _browser_ +For the code: ```ts +// example.js import { diary } from 'diary'; -localStorage.setItem('DEBUG', 'scopeA:two,scopeB:*'); - const scopeA1 = diary('scopeA:one'); const scopeA2 = diary('scopeA:two'); const scopeB1 = diary('scopeB:one'); @@ -66,24 +65,27 @@ scopeB1.info('message'); // will log ✔ scopeB2.info('message'); // will log ✔ ``` -#### _node_ +### _browser_ ```ts -// example.js -import { diary } from 'diary'; +localStorage.setItem('DEBUG', 'scopeA:two,scopeB:*'); -const scopeA1 = diary('scopeA:one'); -const scopeA2 = diary('scopeA:two'); -const scopeB1 = diary('scopeB:one'); -const scopeB2 = diary('scopeB:two'); +// then your scripts +``` -scopeA1.info('message'); // won't log ✗ -scopeA2.info('message'); // will log ✔ -scopeB1.info('message'); // will log ✔ -scopeB2.info('message'); // will log ✔ +> 💡 Tip - Set this via the DevTools, then hit refresh. Saves you having to re-bundle. + +#### _node_ + +```sh +DEBUG=scopeA:two,scopeB:* node example.js ``` -> `$ DEBUG=scopeA:two,scopeB:* node example.js` +#### _workers_ + +Create an [Environment Variable](https://developers.cloudflare.com/workers/platform/environments) with `DEBUG`. + +> ⚠️ Specifically referencing the Cloudflare Workers #### _programmatic_ diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 0000000..bcbabe2 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,6 @@ +declare const __TARGET__: 'browser' | 'worker' | 'node' | 'neutral'; + +/** + * During workers — this can exist + */ +declare const DEBUG: string; diff --git a/src/index.ts b/src/index.ts index b742f73..ea47bed 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,8 +24,6 @@ export type LogEvent = | { level: 'fatal', error: Error } & Omit | LogEventBase; -const is_node = typeof process < 'u' && typeof process.stdout < 'u'; - const to_reg_exp = (x: string) => new RegExp(x.replace(/\*/g, '.*') + '$'); let allows: RegExp[]; @@ -55,7 +53,16 @@ export const enable = (allows_query: string) => { }; // read `localstorage`/`env` for scope "name"s allowed to log -enable((is_node ? process.env.DEBUG : localStorage.getItem('DEBUG')) || 'a^'); +enable( + (__TARGET__ === 'node' + ? process.env.DEBUG + : __TARGET__ === 'browser' + ? localStorage.getItem('DEBUG') + : __TARGET__ === 'worker' + ? DEBUG + : null + ) || 'a^', +); // ~ Logger @@ -99,7 +106,7 @@ const loglevel_strings: Record = { const default_reporter: Reporter = (event) => { let label = ''; - if (is_node) label = `${loglevel_strings[event.level]} `; + if (__TARGET__ === 'node' || __TARGET__ === 'worker') label = `${loglevel_strings[event.level]} `; if (event.name) label += `[${event.name}] `; console[event.level === 'fatal' ? 'error' : event.level](label + event.message, ...event.extra); @@ -119,8 +126,8 @@ const default_reporter: Reporter = (event) => { * log.info('app has started'); * ``` * - * @param name A name to give this diary instance this can be unique to your application, or not. When logged, it'll - * exist after the level string, eg: `ℹ info [my-fancy-app] app has started` + * @param name A name to give this diary instance this can be unique to your application, or not. + * When logged, it'll exist after the level string, eg: `ℹ info [my-fancy-app] app has started` * @param onEmit The reporter that handles the output of the log messages */ export function diary(name: string, onEmit?: Reporter): Diary { @@ -144,4 +151,4 @@ export const warn = default_diary.warn; export const debug = default_diary.debug; export const info = default_diary.info; export const log = default_diary.log; -export const defaultReporter = default_reporter; \ No newline at end of file +export const defaultReporter = default_reporter; diff --git a/test/setup.js b/test/setup.js new file mode 100644 index 0000000..a849d60 --- /dev/null +++ b/test/setup.js @@ -0,0 +1 @@ +globalThis.__TARGET__ = 'node'; diff --git a/tsconfig.json b/tsconfig.json index 58db3fe..d79f5ce 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,6 +14,6 @@ "diary/*": ["src/*"] } }, - "include": ["src/*.ts"], + "include": ["src/global.d.ts", "src/*.ts"], "exclude": ["node_modules"] }