mirror of https://github.com/curbengh/hexo-yam
feat(globbing): support disabling basename for each pattern in 'include:' option
This commit is contained in:
parent
9d6b72422b
commit
50d80ccc70
20
README.md
20
README.md
|
@ -58,9 +58,25 @@ minify:
|
|||
- **globOptions** - [micromatch options](https://github.com/micromatch/micromatch#options) to customise how glob patterns match files.
|
||||
- Defaults to `{ basename: true }`, unless the pattern has a slash.
|
||||
- basename is disabled depending on each pattern.
|
||||
- When specifying an array of patterns, e.g. `exclude: ['*foo.html', '**/bar.html']`, basename applies to `'*foo.html'`, but not `'**/bar.html'`.
|
||||
- This means the following options would work,
|
||||
``` yml
|
||||
exclude:
|
||||
- '*foo.html'
|
||||
- '**/bar/*/*.html'
|
||||
globOptions:
|
||||
basename: true # default
|
||||
```
|
||||
- This behaviour doesn't apply to pattern that starts with `!` (negation).
|
||||
- This limitation only applies to `include:` option used in svg, gzip and brotli.
|
||||
- This means the following options would *not* work,
|
||||
``` yml
|
||||
include:
|
||||
- '!foo.svg'
|
||||
- '!**/bar/*/*.svg'
|
||||
globOptions:
|
||||
basename: true
|
||||
```
|
||||
- basename would stay disabled, if explicitly disabled in `globOptions:`.
|
||||
- However, basename option applies to all patterns in `include:`
|
||||
|
||||
For more options, see [HTMLMinifier](https://github.com/kangax/html-minifier).
|
||||
|
||||
|
|
|
@ -28,6 +28,30 @@ const isMatch = (path = '', patterns = [], options = {}) => {
|
|||
return false
|
||||
}
|
||||
|
||||
const match = (paths = [], patterns = [], options = {}) => {
|
||||
let input = paths
|
||||
if (paths && patterns) {
|
||||
if (paths.length && patterns.length) {
|
||||
const output = []
|
||||
if (typeof patterns === 'string') patterns = [patterns]
|
||||
const exclude = patterns.filter((pattern) => pattern.startsWith('!'))
|
||||
const include = patterns.filter((pattern) => !pattern.startsWith('!'))
|
||||
if (exclude.length) input = micromatch(paths, exclude, options)
|
||||
if (include.length) {
|
||||
for (const pattern of include) {
|
||||
let { basename } = options
|
||||
basename = basename && !pattern.includes('/')
|
||||
const tmp = micromatch(input, pattern, { ...options, basename })
|
||||
if (tmp.length) output.push(...tmp)
|
||||
}
|
||||
return [...new Set(output)]
|
||||
}
|
||||
return input
|
||||
}
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
function logFn (original, minified, path, ext) {
|
||||
const saved = ((original.length - minified.length) / original.length * 100).toFixed(2)
|
||||
const log = this.log || console
|
||||
|
@ -106,11 +130,7 @@ function minifySvg () {
|
|||
const routeList = route.list()
|
||||
const { globOptions, include, verbose } = options
|
||||
|
||||
let includeString = include || ''
|
||||
if (include && Array.isArray(include)) includeString = include.join('')
|
||||
if (includeString && includeString.includes('/')) globOptions.basename = false
|
||||
|
||||
return Promise.all((micromatch(routeList, include, globOptions)).map((path) => {
|
||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const assetPath = route.get(path)
|
||||
let assetTxt = ''
|
||||
|
@ -141,11 +161,7 @@ function gzipFn () {
|
|||
let { level } = options
|
||||
if (typeof level !== 'number') level = zlib.constants.Z_BEST_COMPRESSION
|
||||
|
||||
let includeString = include || ''
|
||||
if (include && Array.isArray(include)) includeString = include.join('')
|
||||
if (includeString && includeString.includes('/')) globOptions.basename = false
|
||||
|
||||
return Promise.all((micromatch(routeList, include, globOptions)).map((path) => {
|
||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const assetPath = route.get(path)
|
||||
let assetTxt = ''
|
||||
|
@ -176,11 +192,7 @@ function brotliFn () {
|
|||
let { level } = options
|
||||
if (typeof level !== 'number') level = zlib.constants.BROTLI_MAX_QUALITY
|
||||
|
||||
let includeString = include || ''
|
||||
if (include && Array.isArray(include)) includeString = include.join('')
|
||||
if (includeString && includeString.includes('/')) globOptions.basename = false
|
||||
|
||||
return Promise.all((micromatch(routeList, include, globOptions)).map((path) => {
|
||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const assetPath = route.get(path)
|
||||
let assetTxt = ''
|
||||
|
|
|
@ -377,12 +377,12 @@ describe('svg', () => {
|
|||
|
||||
test('include - basename', async () => {
|
||||
hexo.config.minify.svg.include = 'bar.svg'
|
||||
const fooPath = 'foo/bar.svg'
|
||||
hexo.route.set(fooPath, input)
|
||||
const path = 'foo/bar.svg'
|
||||
hexo.route.set(path, input)
|
||||
await s()
|
||||
const { data } = await new Svgo(hexo.config.minify.svg).optimize(input)
|
||||
|
||||
const output = hexo.route.get(fooPath)
|
||||
const output = hexo.route.get(path)
|
||||
let result = ''
|
||||
output.on('data', (chunk) => (result += chunk))
|
||||
output.on('end', () => {
|
||||
|
@ -392,18 +392,99 @@ describe('svg', () => {
|
|||
|
||||
test('include - slash in pattern', async () => {
|
||||
hexo.config.minify.svg.include = '**/foo/*.svg'
|
||||
const fooPath = 'blog/site/example/foo/bar.svg'
|
||||
hexo.route.set(fooPath, input)
|
||||
const path = 'blog/site/example/foo/bar.svg'
|
||||
hexo.route.set(path, input)
|
||||
await s()
|
||||
const { data } = await new Svgo(hexo.config.minify.svg).optimize(input)
|
||||
|
||||
const output = hexo.route.get(fooPath)
|
||||
const output = hexo.route.get(path)
|
||||
let result = ''
|
||||
output.on('data', (chunk) => (result += chunk))
|
||||
output.on('end', () => {
|
||||
expect(result).toBe(data)
|
||||
})
|
||||
})
|
||||
|
||||
test('include - basename + slash', async () => {
|
||||
hexo.route.remove(path)
|
||||
|
||||
const paths = [
|
||||
'lorem/ipsum/dolor.svg',
|
||||
'gravida/sociis/erat/ante.svg',
|
||||
'aptent/elementum.svg',
|
||||
'felis/blandit/cursus.svg'
|
||||
]
|
||||
hexo.config.minify.svg.include = [
|
||||
'dolor.svg',
|
||||
'**/sociis/**/*.svg'
|
||||
]
|
||||
|
||||
paths.forEach((inpath) => {
|
||||
hexo.route.set(inpath, input)
|
||||
})
|
||||
await s()
|
||||
const { data } = await new Svgo(hexo.config.minify.svg).optimize(input)
|
||||
|
||||
const minPaths = paths.slice(0, 2)
|
||||
const unminPaths = paths.slice(2)
|
||||
|
||||
minPaths.forEach((inpath) => {
|
||||
const output = hexo.route.get(inpath)
|
||||
let result = ''
|
||||
output.on('data', (chunk) => (result += chunk))
|
||||
output.on('end', () => {
|
||||
expect(result).toBe(data)
|
||||
})
|
||||
})
|
||||
|
||||
unminPaths.forEach((inpath) => {
|
||||
const output = hexo.route.get(inpath)
|
||||
let result = ''
|
||||
output.on('data', (chunk) => (result += chunk))
|
||||
output.on('end', () => {
|
||||
expect(result).toBe(input)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('include - reverse pattern + basename disabled', async () => {
|
||||
hexo.route.remove(path)
|
||||
|
||||
const paths = [
|
||||
'lorem/ipsum/dolor.svg',
|
||||
'gravida/sociis/erat/ante.svg',
|
||||
'aptent/elementum.svg',
|
||||
'felis/blandit/cursus.svg'
|
||||
]
|
||||
hexo.config.minify.svg.include = [
|
||||
'!dolor.svg'
|
||||
]
|
||||
hexo.config.minify.svg.globOptions = {
|
||||
basename: false
|
||||
}
|
||||
|
||||
paths.forEach((inpath) => {
|
||||
hexo.route.set(inpath, input)
|
||||
})
|
||||
await s()
|
||||
const { data } = await new Svgo(hexo.config.minify.svg).optimize(input)
|
||||
|
||||
paths.forEach((inpath) => {
|
||||
const output = hexo.route.get(inpath)
|
||||
let result = ''
|
||||
output.on('data', (chunk) => (result += chunk))
|
||||
output.on('end', () => {
|
||||
expect(result).toBe(data)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('include - empty route', async () => {
|
||||
hexo.route.remove(path)
|
||||
|
||||
const result = await s()
|
||||
expect(result.length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('gzip', () => {
|
||||
|
@ -506,22 +587,22 @@ describe('gzip', () => {
|
|||
|
||||
test('include - basename', async () => {
|
||||
hexo.config.minify.gzip.include = 'bar.txt'
|
||||
const fooPath = 'foo/bar.txt'
|
||||
hexo.route.set(fooPath, input)
|
||||
const path = 'foo/bar.txt'
|
||||
hexo.route.set(path, input)
|
||||
await g()
|
||||
|
||||
const result = hexo.route.get(fooPath.concat('.gz'))
|
||||
const result = hexo.route.get(path.concat('.gz'))
|
||||
|
||||
expect(result).toBeDefined()
|
||||
})
|
||||
|
||||
test('include - slash in pattern', async () => {
|
||||
hexo.config.minify.gzip.include = '**/foo/*.txt'
|
||||
const fooPath = 'blog/site/example/foo/bar.txt'
|
||||
hexo.route.set(fooPath, input)
|
||||
const path = 'blog/site/example/foo/bar.txt'
|
||||
hexo.route.set(path, input)
|
||||
await g()
|
||||
|
||||
const result = hexo.route.get(fooPath.concat('.gz'))
|
||||
const result = hexo.route.get(path.concat('.gz'))
|
||||
|
||||
expect(result).toBeDefined()
|
||||
})
|
||||
|
@ -623,22 +704,22 @@ describe('brotli', () => {
|
|||
|
||||
test('include - basename', async () => {
|
||||
hexo.config.minify.brotli.include = 'bar.txt'
|
||||
const fooPath = 'foo/bar.txt'
|
||||
hexo.route.set(fooPath, input)
|
||||
const path = 'foo/bar.txt'
|
||||
hexo.route.set(path, input)
|
||||
await b()
|
||||
|
||||
const result = hexo.route.get(fooPath.concat('.br'))
|
||||
const result = hexo.route.get(path.concat('.br'))
|
||||
|
||||
expect(result).toBeDefined()
|
||||
})
|
||||
|
||||
test('include - slash in pattern', async () => {
|
||||
hexo.config.minify.brotli.include = '**/foo/*.txt'
|
||||
const fooPath = 'blog/site/example/foo/bar.txt'
|
||||
hexo.route.set(fooPath, input)
|
||||
const path = 'blog/site/example/foo/bar.txt'
|
||||
hexo.route.set(path, input)
|
||||
await b()
|
||||
|
||||
const result = hexo.route.get(fooPath.concat('.br'))
|
||||
const result = hexo.route.get(path.concat('.br'))
|
||||
|
||||
expect(result).toBeDefined()
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue