Skip to content

Commit

Permalink
fix: include hash with bud.assets calls (#1424)
Browse files Browse the repository at this point in the history
* 🐛 fix(none): fix: bud.assets shorthand hashing

* 📚 docs(none): update bud.assets documentation

* 🧪 test(none): fix bud.assets unit test
  • Loading branch information
kellymears authored May 21, 2022
1 parent 0fd2575 commit 6fb4c53
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 70 deletions.
43 changes: 23 additions & 20 deletions sources/@repo/docs/content/docs/bud.assets.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ You may specify a path to a specific file or use glob syntax to match many files

This function is pretty flexible and accepts a few different ways of specifying what you want to copy.

```ts
```ts title='bud.config.js'
(
...request: Array<
| string
Expand Down Expand Up @@ -41,37 +41,44 @@ Use a single `string` to copy the entire images directory. Relative to source di
bud.assets('images')
```

### Copying using an object

You can specify `CopyPlugin.ObjectPattern` object(s) directly:

```js title='bud.config.js'
bud.assets({
from: bud.path('assets/some-file.svg'),
to: bud.path('dist/some-file.svg'),
noErrorOnMissing: false,
})
```

### Copying using source/destination tuples

You can use an array of tuples to specify a set of copy jobs.
You can also specify the source and destination using a tuple.

The first item in each tuple is the source and the second is the destination:

```js title='bud.config.js'
bud.assets([
['images', 'images'], // @src/images => @dist/images
['fonts', 'fonts'],
])
```

```js title='bud.config.js'
bud.assets([
[bud.path('@src/assets/asset.png'), bud.path('@dist/asset.png')],
[bud.path('@src/fonts'), bud.path('@dist/fonts')],
])
```

### Copying using an object

You can specify [`CopyPlugin.ObjectPattern`](https://github.com/webpack-contrib/copy-webpack-plugin#patterns) object(s) directly:

```js title='bud.config.js'
bud.assets({
from: bud.path('assets/some-file.svg'),
to: bud.path('dist/some-file.svg'),
noErrorOnMissing: false,
})
```

### Copying from multiple sources

To specify additional copy sources you can add additional parameters.

```js title='bud.config.js'
bud.assets('fonts/**/*.woff', 'images')
bud.assets('fonts', 'images')
```

```js title='bud.config.js'
Expand Down Expand Up @@ -118,8 +125,4 @@ if you are referencing a font file from your stylesheet, the font will already b
in your distribution. You don't need to manually require it with **bud.assets**, although
there is probably no real harm in doing so.

[bud.assets](/docs/bud.assets) is specifically for compiling files which are not already included elsewhere.

```
```
**bud.assets** is specifically for compiling files which are not already included elsewhere.
54 changes: 17 additions & 37 deletions sources/@roots/bud-api/src/methods/assets/assets.method.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {Bud} from '@roots/bud-framework'
import CopyPlugin from 'copy-webpack-plugin'
import {isArray, isString} from 'lodash'
import {normalize} from 'path'
import {join, normalize} from 'path'

import type {method} from './assets.interface'

Expand All @@ -22,31 +22,13 @@ export const assets: method = async function assets(
* when destructuring bud even though the context of
* this function will be bound.
*/
const ctx = this as Bud

/**
* We know it's not a directory
* - when it ends with a globstar
*
* We'll say it's a directory when:
* - a pattern ends with `/`
* - a pattern has segments and it's last path segment does not contain a `.`
* - a pattern has no segments and does not contain a dot
*/
const isDirectoryish = (pattern: string) => {
if (pattern.includes('*')) return false
if (pattern.endsWith('/')) return true
if (pattern.includes('/') && !pattern.split('/').pop().includes('.'))
return true

return !pattern.split('/').pop().includes('.')
}
const app = this as Bud

/**
* Replace a leading dot with the project path
*/
const fromDotRel = (pattern: string) =>
pattern?.startsWith('./') ? pattern.replace('./', ctx.path()) : pattern
pattern?.startsWith('./') ? pattern.replace('./', app.path()) : pattern

/**
* Take an input string and return a {@link CopyPlugin.ObjectPattern}
Expand All @@ -58,14 +40,12 @@ export const assets: method = async function assets(
* - Replace leading dot with project path
* - Append wildcard glob to directory requests
*/
const from = isDirectoryish(input)
? fromDotRel(toWildcard(input))
: fromDotRel(input)
const from = fromDotRel(input)

return {
from,
to: ctx.path('@name'),
context: ctx.path('@src'),
from: from,
to: app.path('@name'),
context: input.startsWith('/') ? undefined : app.path('@src'),
noErrorOnMissing: true,
}
}
Expand All @@ -76,21 +56,21 @@ export const assets: method = async function assets(
* @param tuple - [origin, destination]
* @returns
*/
const makeFromTo = ([from, to]: [string, string]) => {
const makeFromTo = (input: [string, string]) => {
let [from, to] = input

/**
* Process raw user input.
*
* - Replace leading dot with project path
* - Append wildcard glob to directory requests
*/
from = isDirectoryish(from)
? fromDotRel(toWildcard(from))
: fromDotRel(from)
from = fromDotRel(from)

return {
from,
to,
context: ctx.path('@src'),
to: to ? join(to, app.path('@name')) : app.path('@name'),
context: app.path('@src'),
noErrorOnMissing: true,
}
}
Expand All @@ -103,21 +83,21 @@ export const assets: method = async function assets(
}

if (appearsTupled(request)) {
ctx.extensions.get('copy-webpack-plugin').setOptions(options => ({
app.extensions.get('copy-webpack-plugin').setOptions(options => ({
...(options ?? {}),
patterns: [
...(options?.patterns ?? []),
...request.flat().map(makeFromTo),
],
}))

return ctx
return app
}

ctx.extensions.get('copy-webpack-plugin').setOptions(options => ({
app.extensions.get('copy-webpack-plugin').setOptions(options => ({
...(options ?? {}),
patterns: [...(options?.patterns ?? []), ...request.flat().map(parse)],
}))

return ctx
return app
}
9 changes: 6 additions & 3 deletions sources/@roots/bud-framework/src/methods/setPublicPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ export interface setPublicPath {
}

/**
* By default it is assumed that assets are served from webroot (`/`).
* You can use this method to replace this value for apps served from
* a subdirectory.
* Set the application public path (e.g. `/assets`)
*
* @remarks
* The default public path is `/`
*
* @example
* Set the default path using a string
Expand All @@ -32,6 +33,8 @@ export interface setPublicPath {
* })
* ```
*
* @see {@link https://bud.js.org/docs/bud.setPublicPath}
*
* @public
*/
export const setPublicPath: setPublicPath = function (publicPath) {
Expand Down
17 changes: 7 additions & 10 deletions tests/unit/bud-api/methods/assets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('bud.assets', function () {
expect(JSON.stringify(patterns)).toEqual(
JSON.stringify([
{
from: 'images/**/*',
from: 'images',
to: bud.path('@name'),
context: bud.path('@src'),
noErrorOnMissing: true,
Expand All @@ -54,13 +54,13 @@ describe('bud.assets', function () {
expect(JSON.stringify(options.patterns)).toEqual(
JSON.stringify([
{
from: 'images/**/*',
from: 'images',
to: bud.path('@name'),
context: bud.path('@src'),
noErrorOnMissing: true,
},
{
from: 'fonts/**/*',
from: 'fonts',
to: bud.path('@name'),
context: bud.path('@src'),
noErrorOnMissing: true,
Expand All @@ -80,10 +80,7 @@ describe('bud.assets', function () {
it('adds tupled assets', async () => {
await bud.api.call('assets', [
[bud.path('@src/images'), bud.path('@dist/images')],
[
bud.path('@src/fonts/font.woff'),
bud.path('@dist/fonts/font.woff'),
],
[bud.path('@src/fonts/font.woff')],
])

const patterns = bud.extensions
Expand All @@ -93,14 +90,14 @@ describe('bud.assets', function () {
expect(JSON.stringify(patterns)).toEqual(
JSON.stringify([
{
from: bud.path('@src/images/**/*'),
to: bud.path('@dist/images'),
from: bud.path('@src/images'),
to: bud.path('@dist/images/@name'),
context: bud.path('@src'),
noErrorOnMissing: true,
},
{
from: bud.path('@src/fonts/font.woff'),
to: bud.path('@dist/fonts/font.woff'),
to: bud.path('@name'),
context: bud.path('@src'),
noErrorOnMissing: true,
},
Expand Down

0 comments on commit 6fb4c53

Please sign in to comment.