Skip to content

Commit

Permalink
🔧 improve(@roots/bud-compress): general improvements (#2092)
Browse files Browse the repository at this point in the history
- deprecates bespoke compression functions for `brotli` and `gzip`
- tightens up the public type declarations and bud augmentations for easier configuration

refers:

- #2079 

## Type of change

**PATCH: backwards compatible change**



This PR includes breaking changes to the following core packages:

- none

This PR includes breaking changes to the follow extensions:

- none

## Dependencies

### Adds

- none

### Removes

- none
  • Loading branch information
kellymears authored Feb 9, 2023
1 parent 6a8d448 commit b91f9de
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 123 deletions.
19 changes: 14 additions & 5 deletions sources/@roots/bud-compress/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,20 @@
"src"
],
"type": "module",
"module": "./lib/index.js",
"types": "./lib/index.d.ts",
"exports": {
".": "./lib/index.js",
"./extension": "./lib/extension.js",
"./brotli": "./lib/brotli.js",
"./gzip": "./lib/gzip.js"
"./extension": {
"types": "./lib/extension.d.ts",
"import": "./lib/extension.js"
},
"./brotli": {
"types": "./lib/brotli.d.ts",
"import": "./lib/brotli.js"
},
"./gzip": {
"types": "./lib/gzip.d.ts",
"import": "./lib/gzip.js"
}
},
"typesVersions": {
"*": {
Expand All @@ -70,6 +77,8 @@
]
}
},
"module": "./lib/index.js",
"types": "./lib/index.d.ts",
"devDependencies": {
"@roots/bud": "workspace:sources/@roots/bud",
"@skypack/package-check": "0.2.2",
Expand Down
46 changes: 46 additions & 0 deletions sources/@roots/bud-compress/src/brotli.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {factory, Bud} from '@repo/test-kit/bud'
import {beforeEach, describe, expect, it, vitest} from 'vitest'
import BudBrotli from './brotli.js'
import BudGzip from './gzip.js'

import Brotli from './brotli.js'
import Compression from './extension.js'

describe(`@roots/bud-compress`, () => {
let bud: Bud
let compress: Compression
let brotli: Brotli

beforeEach(async () => {
bud = await factory()
brotli = new Brotli(bud)
compress = new Compression(bud)

await bud.extensions.add([BudBrotli, BudGzip])
await compress.register(bud)
})

it(`should be constructable`, () => {
expect(brotli).toBeInstanceOf(Brotli)
})

it(`should call enabled when config is called`, () => {
const enableSpy = vitest.spyOn(brotli, 'enable')
brotli.config()
expect(enableSpy).toHaveBeenCalled()
})
it(`should call setOptions when config is called`, () => {
const options = {
algorithm: `test.algorithm`,
filename: `test.filename`,
test: /test-regex$/,
compressionOptions: {test: `option`},
threshold: 9001,
minRatio: 0.1,
deleteOriginalAssets: false,
}
const setOptionsSpy = vitest.spyOn(brotli, 'setOptions')
brotli.config(options)
expect(setOptionsSpy).toHaveBeenCalledWith(options)
})
})
38 changes: 8 additions & 30 deletions sources/@roots/bud-compress/src/brotli.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Bud, Extension} from '@roots/bud-framework'
import {
bind,
disabled,
label,
options,
plugin,
Expand All @@ -10,12 +11,7 @@ import Plugin from 'compression-webpack-plugin'
import type {Options} from './extension.js'

/**
* Bud compression extension brotli adapter
*
* @public
* @decorator `@label`
* @decorator `@plugin`
* @decorator `@options`
* Brotli compression configuration
*/
@label(`@roots/bud-compress/brotli`)
@plugin(Plugin)
Expand All @@ -28,43 +24,25 @@ import type {Options} from './extension.js'
minRatio: 0.8,
deleteOriginalAssets: false,
})
@disabled
export default class BudBrotli extends Extension<Options, Plugin> {
/**
* `register` callback
*
* @public
* @decorator `@bind`
*/
@bind
public override async register(bud: Bud) {
bud.api.bindFacade(`brotli`, this.config)
}

/**
* `bud.brotli` fn
*
* @public
* @decorator `@bind`
* @deprecated Use `bud.compress.brotli.setOptions()` instead.
*/
@bind
public async config(options: Options): Promise<Bud> {
this.app.hooks.on(`feature.brotli`, true)

public async config(options?: Options): Promise<Bud> {
this.enable()
options && this.setOptions(options)

return this.app
}

/**
* `when` callback
*
* @returns true when `feature.brotli` is true
*
* @public
* @decorator `@bind`
*/
@bind
public override async when(bud: Bud) {
return bud.hooks.filter(`feature.brotli`)
}
}

export type {Options}
31 changes: 29 additions & 2 deletions sources/@roots/bud-compress/src/extension.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
import {describe, expect, it, test} from 'vitest'
import {factory, Bud} from '@repo/test-kit/bud'
import {beforeEach, describe, expect, it, test} from 'vitest'
import BudBrotli from './brotli.js'
import BudGzip from './gzip.js'

import Extension from './index.js'

describe(`@roots/bud-compress`, () => {
let bud: Bud
let compress: Extension

beforeEach(async () => {
bud = await factory()
compress = new Extension(bud)
await bud.extensions.add([BudBrotli, BudGzip])
await compress.register(bud)
})

it(`should be constructable`, () => {
expect(Extension).toBeInstanceOf(Function)
})

test.todo(`improve this spec`)
it(`should have gzip interface`, () => {
expect(compress.gzip).toBeInstanceOf(BudGzip)
})

it(`should have br interface`, () => {
expect(compress.brotli).toBeInstanceOf(BudBrotli)
})

it(`should have gzip disabled`, () => {
expect(compress.gzip.enabled).toBe(false)
})

it(`should have brotli disabled`, () => {
expect(compress.brotli.enabled).toBe(false)
})
})
34 changes: 15 additions & 19 deletions sources/@roots/bud-compress/src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,37 @@
import type {Bud} from '@roots/bud-framework'
import type {Modules} from '@roots/bud-framework'
import {Extension} from '@roots/bud-framework/extension'
import {bind, label} from '@roots/bud-framework/extension/decorators'

import Brotli from './brotli.js'
import Gzip from './gzip.js'
import {
bind,
dependsOn,
label,
} from '@roots/bud-framework/extension/decorators'

/**
* Bud compression extension options
* Compression options
*/
export interface Options {
filename: string
algorithm: string
test: RegExp
compressionOptions: {
[key: string]: any
}
compressionOptions: Record<string, any>
threshold: number
minRatio: number
deleteOriginalAssets: boolean
}

/**
* Bud compression extension
*
* @public
* @decorator `@label`
* Compression configuration
*/
@label(`@roots/bud-compress`)
@dependsOn([`@roots/bud-compress/brotli`, `@roots/bud-compress/gzip`])
export default class BudCompressionExtension extends Extension<any, any> {
/**
* `register` callback
*
* @public
* @decorator `@bind`
*/
public declare gzip: Modules[`@roots/bud-compress/gzip`]
public declare brotli: Modules[`@roots/bud-compress/brotli`]

@bind
public override async register(bud: Bud) {
await bud.extensions.add([Brotli, Gzip])
this.gzip = bud.extensions.get(`@roots/bud-compress/gzip`)
this.brotli = bud.extensions.get(`@roots/bud-compress/brotli`)
}
}
44 changes: 44 additions & 0 deletions sources/@roots/bud-compress/src/gzip.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {factory, Bud} from '@repo/test-kit/bud'
import {beforeEach, describe, expect, it, vitest} from 'vitest'

import Gzip from './gzip.js'
import Compression from './extension.js'

describe(`@roots/bud-compress`, () => {
let bud: Bud
let compress: Compression
let gzip: Gzip

beforeEach(async () => {
bud = await factory()
gzip = new Gzip(bud)
compress = new Compression(bud)

await bud.extensions.add([Gzip])
await compress.register(bud)
})

it(`should be constructable`, () => {
expect(gzip).toBeInstanceOf(Gzip)
})

it(`should call enabled when config is called`, () => {
const enableSpy = vitest.spyOn(gzip, 'enable')
gzip.config()
expect(enableSpy).toHaveBeenCalled()
})
it(`should call setOptions when config is called`, () => {
const options = {
algorithm: `test.algorithm`,
filename: `test.filename`,
test: /test-regex$/,
compressionOptions: {test: `option`},
threshold: 9001,
minRatio: 0.1,
deleteOriginalAssets: false,
}
const setOptionsSpy = vitest.spyOn(gzip, 'setOptions')
gzip.config(options)
expect(setOptionsSpy).toHaveBeenCalledWith(options)
})
})
36 changes: 6 additions & 30 deletions sources/@roots/bud-compress/src/gzip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {Bud} from '@roots/bud-framework'
import {Extension} from '@roots/bud-framework/extension'
import {
bind,
disabled,
label,
options,
plugin,
Expand All @@ -11,12 +12,7 @@ import Plugin from 'compression-webpack-plugin'
import type {Options} from './extension.js'

/**
* Bud compression extension gzip adapter
*
* @public
* @decorator `@label`
* @decorator `@plugin`
* @decorator `@options`
* Gzip compression configuration
*/
@label(`@roots/bud-compress/gzip`)
@plugin(Plugin)
Expand All @@ -29,43 +25,23 @@ import type {Options} from './extension.js'
minRatio: 0.8,
deleteOriginalAssets: false,
})
@disabled
export default class BudGzip extends Extension<Options, Plugin> {
/**
* `register` callback
*
* @public
* @decorator `@bind`
*/
@bind
public override async register(bud: Bud) {
bud.api.bindFacade(`gzip`, this.config)
}

/**
* `bud.gzip` fn
*
* @public
* @decorator `@bind`
* @deprecated Use `bud.compress.gzip.setOptions()` instead.
*/
@bind
public async config(options: Options): Promise<Bud> {
this.app.hooks.on(`feature.gzip`, true)

public async config(options?: Options): Promise<Bud> {
this.enable()
options && this.setOptions(options)

return this.app
}

/**
* `when` callback
*
* @returns true when `feature.brotli` is true
*
* @public
* @decorator `@bind`
*/
@bind
public override async when(bud: Bud) {
return bud.hooks.filter(`feature.gzip`)
}
}
3 changes: 3 additions & 0 deletions sources/@roots/bud-compress/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@

import './types'

import type {Options} from './extension.js'
import BudCompressionExtension from './extension.js'

export default BudCompressionExtension
export type {Options}
Loading

0 comments on commit b91f9de

Please sign in to comment.