ci: add log level option to css bundler plugin

This commit is contained in:
Julien Oculi 2024-02-06 10:22:30 +01:00
parent 4e7e7b05c7
commit 9415d50564
6 changed files with 53 additions and 18 deletions

View file

@ -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' }),
],
})

View file

@ -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),
)
}
}

View file

@ -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()
},

View file

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

View file

@ -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',

View file

@ -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: {