diff --git a/fresh.config.ts b/fresh.config.ts index 30940fe..0f059ef 100644 --- a/fresh.config.ts +++ b/fresh.config.ts @@ -3,6 +3,6 @@ import { cssBundler } from './plugins/css_bundler/plugin.ts' export default defineConfig({ plugins: [ - cssBundler(import.meta.resolve('./src/stylesheets')), + cssBundler(import.meta.resolve('./src/stylesheets'), { logLevel: 'error' }), ], }) diff --git a/plugins/css_bundler/plugin.ts b/plugins/css_bundler/plugin.ts index 0fba306..c9c095a 100644 --- a/plugins/css_bundler/plugin.ts +++ b/plugins/css_bundler/plugin.ts @@ -1,13 +1,24 @@ import { Plugin } from '$fresh/server.ts' import { fromFileUrl } from '$std/path/mod.ts' import { bundleCss } from './src/bundler.ts' +import { Logger } from './src/helpers.ts' import { cssHandler } from './src/middleware.ts' -export function cssBundler(sourceDir: string, pattern = /main.css/): Plugin { +export function cssBundler( + sourceDir: string, + { pattern = /main.css/, logLevel }: { + pattern?: RegExp + logLevel?: 'disabled' | 'info' | 'error' + }, +): Plugin { + const logger = new Logger({ + logLevel: logLevel === 'info' ? 2 : logLevel === 'error' ? 1 : 0, + }) + return { name: 'css_bundler', middlewares: [{ - middleware: { handler: cssHandler(sourceDir) }, + middleware: { handler: cssHandler(sourceDir, logger) }, path: '/', }], async buildStart(config) { @@ -18,7 +29,9 @@ export function cssBundler(sourceDir: string, pattern = /main.css/): Plugin { //Get all source stylesheets for await (const entry of Deno.readDir(fromFileUrl(sourceDir))) { if (entry.isFile && entry.name.match(pattern)) { - tasks.push(bundleCss(sourceDir, outDir, entry.name, config.dev)) + tasks.push( + bundleCss(sourceDir, outDir, entry.name, config.dev, logger), + ) } } diff --git a/plugins/css_bundler/src/builder.ts b/plugins/css_bundler/src/builder.ts index 399ddea..1f54d3d 100644 --- a/plugins/css_bundler/src/builder.ts +++ b/plugins/css_bundler/src/builder.ts @@ -3,11 +3,12 @@ import { bundleAsync } from 'lightningcss' import { cssImports, cssUrls, Logger, uInt8ArrayConcat } from './helpers.ts' export async function builder( - { filename, dev, assetDir, remote }: { + { filename, dev, assetDir, remote, logger }: { filename: string dev: boolean assetDir: string remote?: string + logger: Logger }, ) { const { code, map } = await bundleAsync({ @@ -22,13 +23,13 @@ export async function builder( if (pathOrUrl.startsWith('https://')) { //use cache for remote if (cssImports.has(pathOrUrl)) { - Logger.info('using cache for', `${pathOrUrl}`) + logger.info('using cache for', `${pathOrUrl}`) const filepath = cssImports.get(pathOrUrl)! return Deno.readTextFile(filepath) } //update cache for new remote - Logger.info('fetching and caching', `${pathOrUrl}`) + logger.info('fetching and caching', `${pathOrUrl}`) const response = await fetch(pathOrUrl) const file = await response.arrayBuffer() const filename = encodeURIComponent(pathOrUrl.toString()) @@ -42,6 +43,7 @@ export async function builder( dev, assetDir, remote: pathOrUrl, + logger, }) if (map) { @@ -66,21 +68,21 @@ export async function builder( resolve(specifier, from) { if (remote) { const url = new URL(specifier, remote) - Logger.info('resolve remote imports', url.toString()) + logger.info('resolve remote imports', url.toString()) return url.toString() } //resolve local files normally if (!specifier.startsWith('https://') && !from.startsWith('https://')) { - Logger.info('resolve local file', specifier) + logger.info('resolve local file', specifier) return resolve(parse(from).dir, specifier) } //construct asset url const baseUrl = from.startsWith('https://') ? from : toFileUrl(from) const url = new URL(specifier, baseUrl) - Logger.info('resolve remote file', url.toString()) + logger.info('resolve remote file', url.toString()) return url.toString() }, diff --git a/plugins/css_bundler/src/bundler.ts b/plugins/css_bundler/src/bundler.ts index 22469ec..6e0378c 100644 --- a/plugins/css_bundler/src/bundler.ts +++ b/plugins/css_bundler/src/bundler.ts @@ -7,15 +7,16 @@ export async function bundleCss( assetDir: string, pathname: string, dev: boolean, + logger: Logger, ) { const filename = fromFileUrl(join(sourceDir, pathname)) - Logger.info('bundling', filename) + logger.info('bundling', filename) //prevent Deno from exiting before bundle setTimeout(() => {}, 3_000) try { - const { code, map } = await builder({ filename, dev, assetDir }) + const { code, map } = await builder({ filename, dev, assetDir, logger }) if (map) { //# sourceMappingURL=fresh_dev_client.js.map @@ -35,7 +36,7 @@ export async function bundleCss( await Deno.writeFile(join(assetDir, pathname), code) } } catch (error) { - Logger.error('error during bundle, cleaning cache', error) + logger.error('error during bundle, cleaning cache', error) cssImports.clear() } } diff --git a/plugins/css_bundler/src/helpers.ts b/plugins/css_bundler/src/helpers.ts index 9647874..6c6a765 100644 --- a/plugins/css_bundler/src/helpers.ts +++ b/plugins/css_bundler/src/helpers.ts @@ -1,7 +1,14 @@ export class Logger { - static readonly #name = 'bundle_css' + readonly #name = 'bundle_css' + #logLevel: 0 | 1 | 2 + + constructor({ logLevel }: { logLevel: 0 | 1 | 2 }) { + this.#logLevel = logLevel + } + + info(message: string, path?: string) { + if (this.#logLevel < 2) return - static info(message: string, path?: string) { console.log( `%c[${this.#name}]%c ${message} %c${path ?? ''}`, 'color: blue; font-weight: bold', @@ -10,7 +17,9 @@ export class Logger { ) } - static error(message: string, error?: Error) { + error(message: string, error?: Error) { + if (this.#logLevel < 1) return + console.error( `%c[${this.#name}]%c ${message} %c${error?.toString() ?? ''}`, 'color: red; font-weight: bold', diff --git a/plugins/css_bundler/src/middleware.ts b/plugins/css_bundler/src/middleware.ts index 19d2e53..d3302ec 100644 --- a/plugins/css_bundler/src/middleware.ts +++ b/plugins/css_bundler/src/middleware.ts @@ -3,8 +3,12 @@ import { contentType } from '$fresh/src/server/deps.ts' import { ensureDir } from '$std/fs/ensure_dir.ts' import { join, parse } from '$std/path/mod.ts' import { bundleCss } from './bundler.ts' +import { Logger } from './helpers.ts' -export function cssHandler(sourceDir: string): MiddlewareHandler { +export function cssHandler( + sourceDir: string, + logger: Logger, +): MiddlewareHandler { return async (_, ctx) => { const assetDir = join(ctx.config.build.outDir, '/static') await ensureDir(assetDir) @@ -24,7 +28,13 @@ export function cssHandler(sourceDir: string): MiddlewareHandler { }) } - await bundleCss(sourceDir, assetDir, ctx.url.pathname, ctx.config.dev) + await bundleCss( + sourceDir, + assetDir, + ctx.url.pathname, + ctx.config.dev, + logger, + ) const file = await Deno.readFile(filename) return new Response(file, { headers: {