mirror of https://github.com/curbengh/hexo-yam
Compare commits
75 Commits
Author | SHA1 | Date |
---|---|---|
|
4bd000bfee | |
|
5fb3349dec | |
|
80b2325cbf | |
|
812ff614fc | |
|
702eb2fa0c | |
|
a2c810cfb5 | |
|
30c33c0ad3 | |
|
1c9d91b524 | |
|
c18f4c8476 | |
|
e33fd0ed5d | |
|
73db847fd4 | |
|
7639547408 | |
|
f7df26377a | |
|
1b04f7c8f1 | |
|
18a5d8108b | |
|
7f2033e553 | |
|
e9584b2e0b | |
|
e99e110d39 | |
|
a5f19dbe79 | |
|
c3ed0c68c7 | |
|
f92017f688 | |
|
0abd90c78a | |
|
426da85620 | |
|
bfb886abac | |
|
d99caafe90 | |
|
3cc6f5e79e | |
|
56af48f632 | |
|
0bee9ada0e | |
|
1af8c52cdb | |
|
81ceea413d | |
|
8e937ead21 | |
|
7809098034 | |
|
dffeb0cfc7 | |
|
bfcd93edb7 | |
|
2992e8d8e7 | |
|
cf7e8f675c | |
|
3523b0fd98 | |
|
df3b0513e7 | |
|
dbed65ffeb | |
|
c964cfcf80 | |
|
793bcd81c4 | |
|
f65e7e7a22 | |
|
d9e6228960 | |
|
6c6060f28c | |
|
79f4f24f8e | |
|
b0575e6fdc | |
|
a6f434ff8d | |
|
a6e2ea0879 | |
|
9c8a228e09 | |
|
4b4d3cb342 | |
|
8258359f6b | |
|
c6c7d3743a | |
|
777ffabd2b | |
|
5453fc9ee0 | |
|
c3b899556a | |
|
866ba28c3c | |
|
b54324c154 | |
|
077055ed0b | |
|
d54ed360be | |
|
1ae4d77071 | |
|
0f73e6ed98 | |
|
79f15acb79 | |
|
2ae5520a60 | |
|
ef46c3c6d9 | |
|
4648fa32f1 | |
|
197836b82b | |
|
d757c1b5c7 | |
|
0623de5252 | |
|
fbb2c71e87 | |
|
b3d09fec7a | |
|
3edbe68008 | |
|
1833ffa76e | |
|
63eee78e01 | |
|
7e81770894 | |
|
288a4e3232 |
|
@ -6,19 +6,17 @@ jobs:
|
|||
linter:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- name: Use Node.js 14.x
|
||||
uses: actions/setup-node@v2.4.1
|
||||
with:
|
||||
node-version: '14.x'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Bun
|
||||
uses: oven-sh/setup-bun@v1
|
||||
- name: Cache NPM dependencies
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-npm-cache
|
||||
restore-keys: |
|
||||
${{ runner.os }}-npm-cache
|
||||
- name: Install Dependencies
|
||||
run: npm install
|
||||
run: bun install
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
run: bun run lint
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
name: Semgrep
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- .github/workflows/semgrep.yml
|
||||
schedule:
|
||||
# Weekly
|
||||
- cron: "0 0 * * 0"
|
||||
jobs:
|
||||
semgrep:
|
||||
name: Scan
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
if: (github.actor != 'dependabot[bot]')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: semgrep ci
|
|
@ -2,21 +2,34 @@ name: Snyk
|
|||
|
||||
on:
|
||||
schedule:
|
||||
# Every day
|
||||
- cron: '0 0 * * *'
|
||||
# Weekly
|
||||
- cron: "0 0 * * 0"
|
||||
pull_request:
|
||||
branches:
|
||||
- "dependabot/github_actions/github/codeql-action**"
|
||||
|
||||
jobs:
|
||||
security:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- name: Use Node.js 14.x
|
||||
uses: actions/setup-node@v2.4.1
|
||||
with:
|
||||
node-version: '14.x'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Bun
|
||||
uses: oven-sh/setup-bun@v1
|
||||
- name: Install Dependencies
|
||||
run: npm install
|
||||
run: bun install
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
uses: snyk/actions/node@master
|
||||
continue-on-error: true # To make sure that SARIF upload gets called
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
command: test
|
||||
args: --sarif-file-output=snyk.sarif
|
||||
- name: Upload result to GitHub Code Scanning
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: snyk.sarif
|
||||
- name: Monitor for vulnerabilities
|
||||
uses: snyk/actions/node@master
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
|
|
|
@ -8,22 +8,36 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
node-version: ['12', '14', '16', '17']
|
||||
node-version: ["18", "20", "22"]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.4.1
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Cache NPM dependencies
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-npm-cache
|
||||
restore-keys: ${{ runner.os }}-npm-cache
|
||||
- name: Install Dependencies
|
||||
run: npm install
|
||||
- name: Determine zstd binary version
|
||||
shell: bash
|
||||
run: |
|
||||
case "$RUNNER_OS" in
|
||||
"Linux")
|
||||
echo "PLATFORM=linux-x64-gnu" >> "$GITHUB_ENV" ;;
|
||||
"Windows")
|
||||
echo "PLATFORM=win32-x64-msvc" >> "$GITHUB_ENV" ;;
|
||||
"macOS")
|
||||
echo "PLATFORM=darwin-arm64" >> "$GITHUB_ENV" ;;
|
||||
esac
|
||||
- name: Install zstd binary
|
||||
shell: bash
|
||||
run: npm install "@mongodb-js/zstd-$PLATFORM"
|
||||
- name: Test
|
||||
run: npm run test
|
||||
env:
|
||||
|
@ -33,26 +47,30 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node-version: ['14.x']
|
||||
node-version: ["20.x"]
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.4.1
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install Bun
|
||||
uses: oven-sh/setup-bun@v1
|
||||
- name: Cache NPM dependencies
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-npm-cache
|
||||
restore-keys: ${{ runner.os }}-npm-cache
|
||||
- name: Install Dependencies
|
||||
run: npm install
|
||||
run: bun install
|
||||
- name: Coverage
|
||||
run: npm run test
|
||||
env:
|
||||
CI: true
|
||||
- name: Upload coverage report to Codecov
|
||||
uses: codecov/codecov-action@v2.1.0
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
|
|
@ -4,3 +4,4 @@ package-lock.json
|
|||
tmp/
|
||||
*.log
|
||||
coverage/
|
||||
bun.lockb
|
||||
|
|
6
.snyk
6
.snyk
|
@ -2,8 +2,4 @@
|
|||
version: v1.12.0
|
||||
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
|
||||
ignore:
|
||||
SNYK-JS-LODASH-450202:
|
||||
- '*':
|
||||
reason: Patch/update unavailable. Introduced through Snyk.
|
||||
expires: '2019-12-31T00:00:00.000Z'
|
||||
patch: {}
|
||||
patch:
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018-2019 curbengh, 2016-2018 rozbo
|
||||
Copyright (c) 2018-2024 curbengh, 2016-2018 rozbo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
277
README.md
277
README.md
|
@ -1,68 +1,40 @@
|
|||
# hexo-yam
|
||||
|
||||
[](https://www.npmjs.com/package/hexo-yam)
|
||||
[](https://github.com/curbengh/hexo-yam/actions?query=workflow%3ATester)
|
||||
[](https://github.com/curbengh/hexo-yam/actions?query=workflow%3ATester)
|
||||
[](https://codecov.io/gh/curbengh/hexo-yam)
|
||||
[](https://libraries.io/npm/hexo-yam)
|
||||
[](https://snyk.io/test/npm/hexo-yam)
|
||||
[](https://lgtm.com/projects/g/curbengh/hexo-yam/alerts/)
|
||||
[](https://lgtm.com/projects/g/curbengh/hexo-yam/context:javascript)
|
||||
|
||||
Yet Another Minifier for Hexo. Minify and compress HTML, JS, CSS, SVG, XML and JSON. [Other files](https://github.com/curbengh/hexo-yam/blob/ba77db0094a7c07ea9f70f010bfc15541d4105ca/index.js#L64) are also compressed. Support gzip and [brotli](https://en.wikipedia.org/wiki/Brotli) [compressions](https://en.wikipedia.org/wiki/HTTP_compression).
|
||||
[](https://snyk.io/test/github/curbengh/hexo-yam)
|
||||
|
||||
Yet Another Minifier for Hexo. Minify HTML, JS, CSS, SVG, XML and JSON. Compress static [web assets](https://github.com/curbengh/hexo-yam/blob/ba77db0094a7c07ea9f70f010bfc15541d4105ca/index.js#L64) using gzip, brotli and zstd.
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Version 5](#version-5)
|
||||
- [Installation](#installation)
|
||||
- [Options](#options)
|
||||
- [HTML](#html)
|
||||
- [CSS](#css)
|
||||
- [JS](#js)
|
||||
- [SVG](#svg)
|
||||
- [Gzip](#gzip)
|
||||
- [Brotli](#brotli)
|
||||
- [XML](#xml)
|
||||
- [JSON](#json)
|
||||
- [Gzip](#gzip)
|
||||
- [Brotli](#brotli)
|
||||
- [Zstd](#zstd)
|
||||
- [Globbing](#globbing)
|
||||
- [HTTP Compression](#http-compression)
|
||||
|
||||
## Version 6
|
||||
In v6, `svg.plugins:` option should be the following syntax:
|
||||
|
||||
``` diff
|
||||
minify:
|
||||
svg:
|
||||
plugins:
|
||||
# v6
|
||||
+ removeComments: false
|
||||
+ cleanupIDs: false
|
||||
+ builtinPluginName:
|
||||
+ optionName: 'optionValue'
|
||||
|
||||
# v5
|
||||
- - name: 'removeComments'
|
||||
- active: false
|
||||
- - name: 'cleanupIDs'
|
||||
- active: false
|
||||
|
||||
# v4
|
||||
- - removeComments: false
|
||||
- - cleanupIDs: false
|
||||
```
|
||||
|
||||
The option only overrides svgo's default plugins, other options are not supported.
|
||||
|
||||
## Installation
|
||||
``` bash
|
||||
$ npm install hexo-yam --save
|
||||
|
||||
```bash
|
||||
$ npm install --save hexo-yam
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
``` yaml
|
||||
```yaml
|
||||
minify:
|
||||
enable: true
|
||||
previewServer: true
|
||||
html:
|
||||
css:
|
||||
js:
|
||||
|
@ -74,6 +46,7 @@ minify:
|
|||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `true`.
|
||||
- **previewServer** - Disable the plugin when running `hexo server`. Defaults to `true`.
|
||||
- **html** - See [HTML](#html) section
|
||||
- **css** - See [CSS](#css) section
|
||||
- **js** - See [JS](#js) section
|
||||
|
@ -85,12 +58,13 @@ minify:
|
|||
|
||||
## HTML
|
||||
|
||||
``` yaml
|
||||
```yaml
|
||||
minify:
|
||||
html:
|
||||
enable: true
|
||||
exclude:
|
||||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `true`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`. Set lower value to set higher priority and vice versa.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
|
@ -101,13 +75,14 @@ For more options, see [HTMLMinifier](https://github.com/kangax/html-minifier).
|
|||
|
||||
## CSS
|
||||
|
||||
``` yaml
|
||||
```yaml
|
||||
minify:
|
||||
css:
|
||||
enable: true
|
||||
exclude:
|
||||
- '*.min.css'
|
||||
- "*.min.css"
|
||||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `true`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
|
@ -119,13 +94,14 @@ For more options, see [clean-css](https://github.com/jakubpawlowicz/clean-css).
|
|||
|
||||
## JS
|
||||
|
||||
``` yaml
|
||||
```yaml
|
||||
minify:
|
||||
js:
|
||||
enable: true
|
||||
exclude:
|
||||
- '*.min.js'
|
||||
- "*.min.js"
|
||||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `true`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
|
@ -140,14 +116,15 @@ For more options, see [Terser](https://github.com/terser-js/terser).
|
|||
|
||||
## SVG
|
||||
|
||||
``` yaml
|
||||
```yaml
|
||||
minify:
|
||||
svg:
|
||||
enable: true
|
||||
include:
|
||||
- '*.svg'
|
||||
- '!*.min.svg'
|
||||
- "*.svg"
|
||||
- "!*.min.svg"
|
||||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `true`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
|
@ -155,82 +132,29 @@ minify:
|
|||
- Exclude `*.min.svg` by default.
|
||||
- **plugins** - Plugin options.
|
||||
- Examples:
|
||||
``` yaml
|
||||
```yaml
|
||||
plugins:
|
||||
# Retain comments
|
||||
removeComments: false
|
||||
# Do not remove unused ID attributes
|
||||
cleanupIDs: false
|
||||
cleanupIds: false
|
||||
```
|
||||
- For more options, see [svgo](https://github.com/svg/svgo).
|
||||
- **globOptions** - See [globbing](#globbing) section.
|
||||
|
||||
## Gzip
|
||||
|
||||
``` yaml
|
||||
minify:
|
||||
gzip:
|
||||
enable: true
|
||||
include:
|
||||
- '*.html'
|
||||
- '*.css'
|
||||
- '*.js'
|
||||
- '*.txt'
|
||||
- '*.ttf'
|
||||
- '*.atom'
|
||||
- '*.stl'
|
||||
- '*.xml'
|
||||
- '*.svg'
|
||||
- '*.eot'
|
||||
- '*.json'
|
||||
```
|
||||
- **enable** - Enable the plugin. Defaults to `true`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
||||
- Support one-liner, `include: ['*.html','*.css','*.js']`.
|
||||
- Must include asterisk and single quotes. `.html` is invalid. `'*.html'` is valid.
|
||||
- **globOptions** - See [globbing](#globbing) section.
|
||||
- **level** - Compression level; lower value may results in faster compression but slightly larger (compressed) file. Range `1-9`. Defaults to `9`, or the value of [`zlib.constants.Z_BEST_COMPRESSION`](https://nodejs.org/docs/latest-v12.x/api/zlib.html#zlib_zlib_constants)
|
||||
|
||||
## Brotli
|
||||
|
||||
``` yaml
|
||||
minify:
|
||||
brotli:
|
||||
enable: true
|
||||
include:
|
||||
- '*.html'
|
||||
- '*.css'
|
||||
- '*.js'
|
||||
- '*.txt'
|
||||
- '*.ttf'
|
||||
- '*.atom'
|
||||
- '*.stl'
|
||||
- '*.xml'
|
||||
- '*.svg'
|
||||
- '*.eot'
|
||||
- '*.json'
|
||||
```
|
||||
- **enable** - Enable the plugin. Defaults to `true`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
||||
- **globOptions** - See [globbing](#globbing) section.
|
||||
- **level** - Compression level. Range `1-11`. Defaults to `11`, or the value of [`zlib.constants.BROTLI_MAX_QUALITY`](https://nodejs.org/docs/latest-v12.x/api/zlib.html#zlib_brotli_constants)
|
||||
|
||||
## XML
|
||||
|
||||
Remove whitespaces in xml.
|
||||
|
||||
``` yaml
|
||||
```yaml
|
||||
minify:
|
||||
xml:
|
||||
enable: false
|
||||
include:
|
||||
- '*.xml'
|
||||
- '!*.min.xml'
|
||||
- "*.xml"
|
||||
- "!*.min.xml"
|
||||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `false`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
|
@ -245,14 +169,15 @@ For more options, see [minify-xml](https://github.com/kristian/minify-xml#option
|
|||
|
||||
Remove whitespaces in json.
|
||||
|
||||
``` yaml
|
||||
```yaml
|
||||
minify:
|
||||
json:
|
||||
enable: false
|
||||
include:
|
||||
- '*.json'
|
||||
- '!*.min.json'
|
||||
- "*.json"
|
||||
- "!*.min.json"
|
||||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `false`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
|
@ -260,6 +185,101 @@ minify:
|
|||
- Exclude `*.min.json` by default.
|
||||
- **globOptions** - See [globbing](#globbing) section.
|
||||
|
||||
## Gzip
|
||||
|
||||
```yaml
|
||||
minify:
|
||||
gzip:
|
||||
enable: true
|
||||
include:
|
||||
- "*.html"
|
||||
- "*.css"
|
||||
- "*.js"
|
||||
- "*.txt"
|
||||
- "*.ttf"
|
||||
- "*.atom"
|
||||
- "*.stl"
|
||||
- "*.xml"
|
||||
- "*.svg"
|
||||
- "*.eot"
|
||||
- "*.json"
|
||||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `true`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
||||
- Support one-liner, `include: ['*.html','*.css','*.js']`.
|
||||
- Must include asterisk and single quotes. `.html` is invalid. `'*.html'` is valid.
|
||||
- **globOptions** - See [globbing](#globbing) section.
|
||||
- **level** - Compression level; lower value may results in faster compression but slightly larger (compressed) file. Range `1-9`. Defaults to `9`, or the value of [`zlib.constants.Z_BEST_COMPRESSION`](https://nodejs.org/docs/latest-v12.x/api/zlib.html#zlib_zlib_constants)
|
||||
|
||||
## Brotli
|
||||
|
||||
```yaml
|
||||
minify:
|
||||
brotli:
|
||||
enable: true
|
||||
include:
|
||||
- "*.html"
|
||||
- "*.css"
|
||||
- "*.js"
|
||||
- "*.txt"
|
||||
- "*.ttf"
|
||||
- "*.atom"
|
||||
- "*.stl"
|
||||
- "*.xml"
|
||||
- "*.svg"
|
||||
- "*.eot"
|
||||
- "*.json"
|
||||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `true`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
||||
- **globOptions** - See [globbing](#globbing) section.
|
||||
- **level** - Compression level. Range `1-11`. Defaults to `11`, or the value of [`zlib.constants.BROTLI_MAX_QUALITY`](https://nodejs.org/docs/latest-v12.x/api/zlib.html#zlib_brotli_constants)
|
||||
|
||||
## Zstd
|
||||
|
||||
```yaml
|
||||
minify:
|
||||
zstd:
|
||||
enable: false
|
||||
include:
|
||||
- "*.html"
|
||||
- "*.css"
|
||||
- "*.js"
|
||||
- "*.txt"
|
||||
- "*.ttf"
|
||||
- "*.atom"
|
||||
- "*.stl"
|
||||
- "*.xml"
|
||||
- "*.svg"
|
||||
- "*.eot"
|
||||
- "*.json"
|
||||
```
|
||||
|
||||
- **enable** - Enable the plugin. Defaults to `false`.
|
||||
- **priority** - Plugin's priority. Defaults to `10`.
|
||||
- **verbose** - Verbose output. Defaults to `false`.
|
||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
||||
- **globOptions** - See [globbing](#globbing) section.
|
||||
- **level** - Compression level. Range `1-22`. Defaults to `3`, or the value of [`DEFAULT_LEVEL`](https://github.com/mongodb-js/zstd/blob/a3a08c61c9045411c8275e248498dbc583457fb5/src/lib.rs#L9)
|
||||
|
||||
### Cannot find module '@mongodb-js/zstd-linux-x64-gnu'
|
||||
|
||||
`npm install --save @mongodb-js/zstd-linux-x64-gnu`
|
||||
|
||||
- @mongodb-js/zstd-darwin-arm64 (Apple Silicon)
|
||||
- @mongodb-js/zstd-darwin-x64 (Intel Mac)
|
||||
- @mongodb-js/zstd-linux-arm64-gnu
|
||||
- @mongodb-js/zstd-linux-arm64-musl (Alpine)
|
||||
- @mongodb-js/zstd-linux-x64-gnu
|
||||
- @mongodb-js/zstd-linux-x64-musl (Alpine)
|
||||
- @mongodb-js/zstd-win32-x64-msvc
|
||||
|
||||
## Globbing
|
||||
|
||||
Use "globOptions" to customise how glob patterns match files. Refer to [micromatch](https://github.com/micromatch/micromatch#options) for available options.
|
||||
|
@ -268,51 +288,32 @@ Use "globOptions" to customise how glob patterns match files. Refer to [micromat
|
|||
- basename is disabled depending on each pattern.
|
||||
- This means the following options would work,
|
||||
|
||||
``` yml
|
||||
```yml
|
||||
exclude:
|
||||
- '*foo.html' # basename is enabled
|
||||
- '**/bar/*/*.html' # basename is automatically disabled
|
||||
- '*baz.css' # basename is enabled
|
||||
- "*foo.html" # basename is enabled
|
||||
- "**/bar/*/*.html" # basename is automatically disabled
|
||||
- "*baz.css" # basename is enabled
|
||||
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,
|
||||
- This means the following options would _not_ work,
|
||||
|
||||
``` yml
|
||||
```yml
|
||||
include:
|
||||
- '!foo.svg'
|
||||
- '!**/bar/*/*.svg'
|
||||
- "!foo.svg"
|
||||
- "!**/bar/*/*.svg"
|
||||
globOptions:
|
||||
basename: true
|
||||
```
|
||||
|
||||
- basename will stay disabled, if explicitly disabled in "globOptions".
|
||||
|
||||
|
||||
## HTTP Compression
|
||||
|
||||
While most modern web browsers [support Brotli](https://www.caniuse.com/#feat=brotli), you also need to consider whether the web/app server, hosting platform, reverse proxy or CDN (whichever relevant to you) support it.
|
||||
|
||||
As of Sep 2020, GitHub Pages and GitLab Pages *do not* support brotli yet. You can generate `.br` files, but they won't serve those files.
|
||||
|
||||
Name | Brotli support
|
||||
--- | ---
|
||||
GitHub Pages | [In consideration](https://github.community/t5/GitHub-Pages/Support-for-pre-compressed-assets-and-brotli-compression/m-p/22055)
|
||||
GitLab Pages | Yes
|
||||
Netlify | Yes
|
||||
Hexo Server | [In progress](https://github.com/hexojs/hexo-server/pull/100)
|
||||
|
||||
If you have access to the web server config, you should disable on-the-fly compression for static files (that are already compressed by this plugin),
|
||||
|
||||
- [nginx](https://github.com/google/ngx_brotli): Make sure both filter and static modules are enabled. This way pre-compressed `.br` files will be served while dynamic content can be compressed on-the-fly. Protip: `brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;` to prevent compressing media files (which are already compressed anyway).
|
||||
- [Apache](https://httpd.apache.org/docs/2.4/en/mod/mod_brotli.html): See 'Serving pre-compressed content' section of [mod_brotli](https://httpd.apache.org/docs/2.4/en/mod/mod_brotli.html).
|
||||
- [Caddy](https://caddyserver.com/features): [0.9.4+](https://caddyserver.com/blog/caddy-0_9_4-released) by default support pre-compressed `.gz` `.br` files and on-the-fly gzip compress dynamic files. v2 requires [manual configuration](https://mdleom.com/blog/2020/11/12/caddy2-pre-compressed/), serving them automatically to be supported [in future](https://github.com/caddyserver/caddy/issues/2665).
|
||||
- [express](https://github.com/expressjs/express)/[connect](https://github.com/senchalabs/connect): Use [pre-compressed-assets](https://github.com/domadams/pre-compressed-assets). You still can continue to use [compression](https://github.com/expressjs/compression)/[shrink-ray-current](https://github.com/Alorel/shrink-ray) for dynamic files.
|
||||
|
||||
## Credits
|
||||
|
||||
All credits go to the following work:
|
||||
|
||||
- [hexo-neat](https://github.com/rozbo/hexo-neat) by rozbo
|
||||
- gzip feature is inspired by [hexo-generator-optimize](https://github.com/JackyRen/hexo-generator-optimize)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
[install]
|
||||
optional = false
|
||||
|
||||
[install.lockfile]
|
||||
save = false
|
14
index.js
14
index.js
|
@ -2,7 +2,8 @@
|
|||
'use strict'
|
||||
|
||||
hexo.config.minify = Object.assign({
|
||||
enable: true
|
||||
enable: true,
|
||||
previewServer: true
|
||||
}, hexo.config.minify)
|
||||
|
||||
hexo.config.minify.html = Object.assign({
|
||||
|
@ -68,6 +69,14 @@ hexo.config.minify.brotli = Object.assign({
|
|||
globOptions: { basename: true }
|
||||
}, hexo.config.minify.brotli)
|
||||
|
||||
hexo.config.minify.zstd = Object.assign({
|
||||
enable: false,
|
||||
priority: 10,
|
||||
verbose: false,
|
||||
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
||||
globOptions: { basename: true }
|
||||
}, hexo.config.minify.zstd)
|
||||
|
||||
hexo.config.minify.xml = Object.assign({
|
||||
enable: false,
|
||||
priority: 10,
|
||||
|
@ -85,7 +94,7 @@ hexo.config.minify.json = Object.assign({
|
|||
globOptions: { basename: true }
|
||||
}, hexo.config.minify.json)
|
||||
|
||||
if (hexo.config.minify.enable === true) {
|
||||
if (hexo.config.minify.enable === true && !(hexo.config.minify.previewServer === true && ['s', 'server'].includes(hexo.env.cmd))) {
|
||||
const filter = require('./lib/filter')
|
||||
hexo.extend.filter.register('after_render:html', filter.minifyHtml, hexo.config.minify.html.priority)
|
||||
hexo.extend.filter.register('after_render:css', filter.minifyCss, hexo.config.minify.css.priority)
|
||||
|
@ -93,6 +102,7 @@ if (hexo.config.minify.enable === true) {
|
|||
hexo.extend.filter.register('after_generate', filter.minifySvg, hexo.config.minify.svg.priority)
|
||||
hexo.extend.filter.register('after_generate', filter.gzipFn, hexo.config.minify.gzip.priority)
|
||||
hexo.extend.filter.register('after_generate', filter.brotliFn, hexo.config.minify.brotli.priority)
|
||||
hexo.extend.filter.register('after_generate', filter.zstdFn, hexo.config.minify.zstd.priority)
|
||||
hexo.extend.filter.register('after_generate', filter.minifyXml, hexo.config.minify.xml.priority)
|
||||
hexo.extend.filter.register('after_generate', filter.minifyJson, hexo.config.minify.json.priority)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
const { minify: htmlMinify } = require('html-minifier')
|
||||
const { minify: htmlMinify } = require('html-minifier-terser')
|
||||
const CleanCSS = require('clean-css')
|
||||
const { minify: terserMinify } = require('terser')
|
||||
const { optimize: svgOptimize } = require('svgo')
|
||||
|
@ -10,6 +10,7 @@ const gzip = promisify(zlib.gzip)
|
|||
const br = promisify(zlib.brotliCompress)
|
||||
const { minify: compressXml } = require('minify-xml')
|
||||
const micromatch = require('micromatch')
|
||||
const { compress: zstd } = require('@mongodb-js/zstd')
|
||||
|
||||
const isMatch = (path = '', patterns = [], options = {}) => {
|
||||
if (path && patterns) {
|
||||
|
@ -59,7 +60,7 @@ function logFn (original, minified, path, ext) {
|
|||
log.log(`${ext}: ${path} [${saved}% saved]`)
|
||||
}
|
||||
|
||||
function minifyHtml (str, data) {
|
||||
async function minifyHtml (str, data) {
|
||||
const hexo = this
|
||||
const options = hexo.config.minify.html
|
||||
if (options.enable === false || !str) return
|
||||
|
@ -71,7 +72,7 @@ function minifyHtml (str, data) {
|
|||
if (isMatch(path, exclude, globOptions)) return str
|
||||
|
||||
try {
|
||||
const result = htmlMinify(str, options)
|
||||
const result = await htmlMinify(str, options)
|
||||
if (verbose) logFn.call(this, str, result, path, 'html')
|
||||
|
||||
return result
|
||||
|
@ -152,12 +153,12 @@ function minifySvg () {
|
|||
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
||||
assetPath.on('end', async () => {
|
||||
if (assetTxt.length) {
|
||||
const { data, error } = svgOptimize(assetTxt, { ...options, plugins })
|
||||
if (data) {
|
||||
try {
|
||||
const { data } = svgOptimize(assetTxt, { ...options, plugins })
|
||||
if (verbose) logFn.call(this, assetTxt, data, path, 'svg')
|
||||
resolve(route.set(path, data))
|
||||
} else if (error) {
|
||||
reject(new Error(`Path: ${path}\n${error}`))
|
||||
} catch (err) {
|
||||
reject(new Error(`Path: ${path}\n${err}`))
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
|
@ -230,6 +231,39 @@ function brotliFn () {
|
|||
}))
|
||||
}
|
||||
|
||||
function zstdFn () {
|
||||
const hexo = this
|
||||
const options = hexo.config.minify.zstd
|
||||
if (options.enable === false) return
|
||||
|
||||
const { route } = hexo
|
||||
const routeList = route.list()
|
||||
const { globOptions, include, verbose } = options
|
||||
let { level } = options
|
||||
if (typeof level !== 'number') level = undefined
|
||||
|
||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const assetPath = route.get(path)
|
||||
let assetTxt = ''
|
||||
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
||||
assetPath.on('end', async () => {
|
||||
if (assetTxt.length) {
|
||||
try {
|
||||
const input = Buffer.from(assetTxt, 'utf-8')
|
||||
const result = await zstd(input, level)
|
||||
if (verbose) logFn.call(this, assetTxt, result, path, 'zstd')
|
||||
resolve(route.set(path + '.zst', result))
|
||||
} catch (err) {
|
||||
reject(new Error(`Path: ${path}\n${err}`))
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
function minifyXml () {
|
||||
const hexo = this
|
||||
const options = hexo.config.minify.xml
|
||||
|
@ -297,6 +331,7 @@ module.exports = {
|
|||
minifySvg,
|
||||
gzipFn,
|
||||
brotliFn,
|
||||
zstdFn,
|
||||
minifyXml,
|
||||
minifyJson
|
||||
}
|
||||
|
|
29
package.json
29
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "hexo-yam",
|
||||
"description": "Yet Another Minifier. Minify and compress html, js, css, svg, xml and json",
|
||||
"version": "6.0.0",
|
||||
"version": "9.0.0",
|
||||
"readme": "README.md",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
|
@ -16,36 +16,35 @@
|
|||
"test": "jest"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.13.0"
|
||||
"node": ">= 18.12.0"
|
||||
},
|
||||
"author": "curben",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/curbengh/hexo-yam",
|
||||
"repository": "curbengh/hexo-yam",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/curbengh/hexo-yam.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"clean-css": "^5.1.2",
|
||||
"html-minifier": "^4.0.0",
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"micromatch": "^4.0.2",
|
||||
"minify-xml": "^3.2.0",
|
||||
"svgo": "^2.4.0",
|
||||
"terser": "^5.3.0"
|
||||
"svgo": "^3.0.0",
|
||||
"terser": "^5.3.0",
|
||||
"@mongodb-js/zstd": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"hexo": "^5.1.1",
|
||||
"jest": "^27.2.5",
|
||||
"standard": "^16.0.1"
|
||||
"hexo": "^7.1.0",
|
||||
"jest": "^29.1.2",
|
||||
"standard": "^17.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"html",
|
||||
"js",
|
||||
"css",
|
||||
"svg",
|
||||
"xml",
|
||||
"json",
|
||||
"minify",
|
||||
"compress",
|
||||
"gzip",
|
||||
"brotli",
|
||||
"zstd",
|
||||
"hexo-yam",
|
||||
"hexo"
|
||||
],
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
'use strict'
|
||||
|
||||
const Hexo = require('hexo')
|
||||
const { minify: htmlMinify } = require('html-minifier')
|
||||
const { minify: htmlMinify } = require('html-minifier-terser')
|
||||
|
||||
describe('html', () => {
|
||||
const hexo = new Hexo(__dirname)
|
||||
|
@ -26,105 +26,107 @@ describe('html', () => {
|
|||
globOptions: { basename: true }
|
||||
}
|
||||
}
|
||||
const expected = htmlMinify(input, defaultCfg.html)
|
||||
let expected = ''
|
||||
|
||||
beforeAll(async () => {
|
||||
expected = await htmlMinify(input, defaultCfg.html)
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
hexo.config.minify = JSON.parse(JSON.stringify(defaultCfg))
|
||||
})
|
||||
|
||||
test('default', () => {
|
||||
const result = h(input, { path })
|
||||
test('default', async () => {
|
||||
const result = await h(input, { path })
|
||||
|
||||
expect(result).toBe(expected)
|
||||
})
|
||||
|
||||
test('disable', () => {
|
||||
test('disable', async () => {
|
||||
hexo.config.minify.html.enable = false
|
||||
|
||||
const result = h(input, { path })
|
||||
const result = await h(input, { path })
|
||||
|
||||
expect(result).toBeUndefined()
|
||||
})
|
||||
|
||||
test('empty file', () => {
|
||||
const result = h('', { path })
|
||||
test('empty file', async () => {
|
||||
const result = await h('', { path })
|
||||
|
||||
expect(result).toBeUndefined()
|
||||
})
|
||||
|
||||
test('option', () => {
|
||||
test('option', async () => {
|
||||
const customOpt = { removeEmptyAttributes: false }
|
||||
hexo.config.minify.html = customOpt
|
||||
|
||||
const result = h(input, { path })
|
||||
const expected = htmlMinify(input, customOpt)
|
||||
const result = await h(input, { path })
|
||||
const expected = await htmlMinify(input, customOpt)
|
||||
|
||||
expect(result).toBe(input)
|
||||
expect(result).toBe(expected)
|
||||
})
|
||||
|
||||
test('option - verbose', () => {
|
||||
test('option - verbose', async () => {
|
||||
hexo.config.minify.html.verbose = true
|
||||
hexo.log.log = jest.fn()
|
||||
h(input, { path })
|
||||
await h(input, { path })
|
||||
|
||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`html: ${path}`)
|
||||
})
|
||||
|
||||
test('exclude', () => {
|
||||
test('exclude', async () => {
|
||||
const exclude = '*.min.html'
|
||||
hexo.config.minify.html.exclude = exclude
|
||||
|
||||
const result = h(input, { path: 'foo/bar.min.html' })
|
||||
const result = await h(input, { path: 'foo/bar.min.html' })
|
||||
|
||||
expect(result).toBe(input)
|
||||
})
|
||||
|
||||
test('exclude - slash in pattern', () => {
|
||||
test('exclude - slash in pattern', async () => {
|
||||
const exclude = '**/lectus/**/*.html'
|
||||
hexo.config.minify.html.exclude = exclude
|
||||
|
||||
const result = h(input, { path: 'eleifend/lectus/nullam/dapibus/netus.html' })
|
||||
const result = await h(input, { path: 'eleifend/lectus/nullam/dapibus/netus.html' })
|
||||
|
||||
expect(result).toBe(input)
|
||||
})
|
||||
|
||||
test('exclude - basename is true + slash', () => {
|
||||
test('exclude - basename is true + slash', async () => {
|
||||
const exclude = ['**/lectus/**/*.html', 'bar.html']
|
||||
const globOptions = { basename: true }
|
||||
hexo.config.minify.html.exclude = exclude
|
||||
hexo.config.minify.html.globOptions = globOptions
|
||||
|
||||
const result = h(input, { path: 'foo/bar.html' })
|
||||
const result = await h(input, { path: 'foo/bar.html' })
|
||||
|
||||
expect(result).toBe(input)
|
||||
})
|
||||
|
||||
test('exclude - basename is false + slash', () => {
|
||||
test('exclude - basename is false + slash', async () => {
|
||||
const exclude = ['**/lectus/**/*.html', 'bar.html']
|
||||
const globOptions = { basename: false }
|
||||
hexo.config.minify.html.exclude = exclude
|
||||
hexo.config.minify.html.globOptions = globOptions
|
||||
|
||||
const result = h(input, { path: 'foo/bar.html' })
|
||||
const result = await h(input, { path: 'foo/bar.html' })
|
||||
|
||||
expect(result).toBe(expected)
|
||||
})
|
||||
|
||||
test('null', () => {
|
||||
test('null', async () => {
|
||||
hexo.config.minify.html.exclude = null
|
||||
hexo.config.minify.html.globOptions = null
|
||||
|
||||
const result = h(input, { path: null })
|
||||
const result = await h(input, { path: null })
|
||||
|
||||
expect(result).toBe(expected)
|
||||
})
|
||||
|
||||
test('invalid string', () => {
|
||||
test('invalid string', async () => {
|
||||
const invalid = '<html><>?:"{}|_+</html>'
|
||||
|
||||
expect(() => {
|
||||
h(invalid, { path })
|
||||
}).toThrow(`Path: ${path}\nError: Parse Error`)
|
||||
await expect(h(invalid, { path })).rejects.toThrow('Parse Error: <>?:"{}|_+</html>')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -71,7 +71,7 @@ describe('svg', () => {
|
|||
|
||||
test('option', async () => {
|
||||
const customOpt = {
|
||||
cleanupIDs: false
|
||||
cleanupIds: false
|
||||
}
|
||||
hexo.config.minify.svg.plugins = customOpt
|
||||
plugins = [{
|
||||
|
@ -117,10 +117,14 @@ describe('svg', () => {
|
|||
const input = '{}'
|
||||
hexo.route.set(path, input)
|
||||
|
||||
const { error } = svgOptimize(input, { plugins })
|
||||
|
||||
expect(error).toBeDefined()
|
||||
await expect(s()).rejects.toThrow(`Path: ${path}\n${error}`)
|
||||
let expected
|
||||
try {
|
||||
svgOptimize(input, { plugins })
|
||||
} catch (err) {
|
||||
expected = err
|
||||
}
|
||||
expect(expected).toBeDefined()
|
||||
await expect(s()).rejects.toThrow(`Path: ${path}\n${expected}`)
|
||||
})
|
||||
|
||||
test('include - exclude *.min.svg by default', async () => {
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
/* eslint-env jest */
|
||||
'use strict'
|
||||
|
||||
const Hexo = require('hexo')
|
||||
const { compress: zstd, decompress: unzstd } = require('@mongodb-js/zstd')
|
||||
|
||||
describe('zstd', () => {
|
||||
const hexo = new Hexo(__dirname)
|
||||
const z = require('../lib/filter').zstdFn.bind(hexo)
|
||||
const path = 'foo.txt'
|
||||
const input = 'Lorem ipsum dolor sit amet consectetur adipiscing elit fusce'
|
||||
const inputBuf = Buffer.from(input, 'utf8')
|
||||
|
||||
beforeEach(() => {
|
||||
hexo.config.minify = {
|
||||
zstd: {
|
||||
enable: true,
|
||||
verbose: false,
|
||||
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
||||
globOptions: { basename: true }
|
||||
}
|
||||
}
|
||||
hexo.route.set(path, input)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
const routeList = hexo.route.list()
|
||||
routeList.forEach((path) => hexo.route.remove(path))
|
||||
})
|
||||
|
||||
test('default', async () => {
|
||||
await z()
|
||||
|
||||
const output = hexo.route.get(path.concat('.zst'))
|
||||
const buf = []
|
||||
output.on('data', (chunk) => (buf.push(chunk)))
|
||||
output.on('end', async () => {
|
||||
const result = Buffer.concat(buf)
|
||||
const expected = await zstd(inputBuf)
|
||||
const resultUnzst = await unzstd(result)
|
||||
const expectedUnzst = await unzstd(expected)
|
||||
|
||||
expect(result.equals(expected)).toBe(true)
|
||||
expect(resultUnzst.toString()).toBe(input)
|
||||
expect(expectedUnzst.toString()).toBe(input)
|
||||
})
|
||||
})
|
||||
|
||||
test('disable', async () => {
|
||||
hexo.config.minify.zstd.enable = false
|
||||
const result = await z()
|
||||
|
||||
expect(result).toBeUndefined()
|
||||
})
|
||||
|
||||
test('empty file', async () => {
|
||||
hexo.route.set(path, '')
|
||||
|
||||
const routeList = hexo.route.list()
|
||||
expect(routeList).not.toContain(path.concat('.zst'))
|
||||
|
||||
const result = await z()
|
||||
expect(result).toBeDefined()
|
||||
expect(result[0]).toBeUndefined()
|
||||
})
|
||||
|
||||
test('option', async () => {
|
||||
const level = 1
|
||||
hexo.config.minify.zstd.level = level
|
||||
await z()
|
||||
|
||||
const output = hexo.route.get(path.concat('.zst'))
|
||||
const buf = []
|
||||
output.on('data', (chunk) => (buf.push(chunk)))
|
||||
output.on('end', async () => {
|
||||
const result = Buffer.concat(buf)
|
||||
const expected = await zstd(inputBuf, level)
|
||||
|
||||
expect(result.equals(expected)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
test('option - verbose', async () => {
|
||||
hexo.config.minify.zstd.verbose = true
|
||||
hexo.log.log = jest.fn()
|
||||
await z()
|
||||
|
||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`zstd: ${path}`)
|
||||
})
|
||||
|
||||
test('option - level is string', async () => {
|
||||
const level = 'foo'
|
||||
hexo.config.minify.zstd.level = level
|
||||
await z()
|
||||
|
||||
const output = hexo.route.get(path.concat('.zst'))
|
||||
const buf = []
|
||||
output.on('data', (chunk) => (buf.push(chunk)))
|
||||
output.on('end', async () => {
|
||||
const result = Buffer.concat(buf)
|
||||
const expected = await zstd(inputBuf, undefined)
|
||||
|
||||
expect(result.equals(expected)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
test('include - exclude non-text file by default', async () => {
|
||||
const path = 'foo.jpg'
|
||||
hexo.route.set(path, input)
|
||||
await z()
|
||||
|
||||
const result = hexo.route.get(path.concat('.zst'))
|
||||
|
||||
expect(result).toBeUndefined()
|
||||
})
|
||||
|
||||
test('include - basename', async () => {
|
||||
hexo.config.minify.zstd.include = 'bar.txt'
|
||||
const path = 'foo/bar.txt'
|
||||
hexo.route.set(path, input)
|
||||
await z()
|
||||
|
||||
const result = hexo.route.get(path.concat('.zst'))
|
||||
|
||||
expect(result).toBeDefined()
|
||||
})
|
||||
|
||||
test('include - slash in pattern', async () => {
|
||||
hexo.config.minify.zstd.include = '**/lectus/**/*.txt'
|
||||
const path = 'eleifend/lectus/nullam/dapibus/netus.txt'
|
||||
hexo.route.set(path, input)
|
||||
await z()
|
||||
|
||||
const result = hexo.route.get(path.concat('.zst'))
|
||||
|
||||
expect(result).toBeDefined()
|
||||
})
|
||||
|
||||
test('include - basename + slash + basename enabled', async () => {
|
||||
hexo.route.remove(path)
|
||||
|
||||
const paths = [
|
||||
'lorem/ipsum/dolor.html',
|
||||
'gravida/sociis/erat/ante.css',
|
||||
'aptent/elementum.js',
|
||||
'felis/blandit/cursus.svg'
|
||||
]
|
||||
hexo.config.minify.zstd.include = [
|
||||
'*.html',
|
||||
'**/sociis/**/*.css'
|
||||
]
|
||||
|
||||
paths.forEach((inpath) => {
|
||||
hexo.route.set(inpath, input)
|
||||
})
|
||||
await z()
|
||||
|
||||
const routeList = hexo.route.list()
|
||||
const expected = [
|
||||
'lorem/ipsum/dolor.html.zst',
|
||||
'gravida/sociis/erat/ante.css.zst'
|
||||
]
|
||||
const notExpected = [
|
||||
'aptent/elementum.js.zst',
|
||||
'felis/blandit/cursus.svg.zst'
|
||||
]
|
||||
|
||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
||||
expect(routeList).toEqual(expect.not.arrayContaining(notExpected))
|
||||
})
|
||||
|
||||
test('include - basename + slash + basename disabled', async () => {
|
||||
hexo.route.remove(path)
|
||||
|
||||
const paths = [
|
||||
'lorem/ipsum/dolor.html',
|
||||
'gravida/sociis/erat/ante.css',
|
||||
'aptent/elementum.js',
|
||||
'felis/blandit/cursus.svg'
|
||||
]
|
||||
hexo.config.minify.zstd.include = [
|
||||
'*.html',
|
||||
'**/sociis/**/*.css'
|
||||
]
|
||||
hexo.config.minify.zstd.globOptions = {
|
||||
basename: false
|
||||
}
|
||||
|
||||
paths.forEach((inpath) => {
|
||||
hexo.route.set(inpath, input)
|
||||
})
|
||||
await z()
|
||||
|
||||
const routeList = hexo.route.list()
|
||||
const expected = [
|
||||
'gravida/sociis/erat/ante.css.zst'
|
||||
]
|
||||
const notExpected = [
|
||||
'lorem/ipsum/dolor.html.zst',
|
||||
'aptent/elementum.js.zst',
|
||||
'felis/blandit/cursus.svg.zst'
|
||||
]
|
||||
|
||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
||||
expect(routeList).toEqual(expect.not.arrayContaining(notExpected))
|
||||
})
|
||||
|
||||
test('include - reverse pattern + basename disabled', async () => {
|
||||
hexo.route.remove(path)
|
||||
|
||||
const paths = [
|
||||
'lorem/ipsum/dolor.html',
|
||||
'gravida/sociis/erat/ante.css',
|
||||
'aptent/elementum.js',
|
||||
'felis/blandit/cursus.svg'
|
||||
]
|
||||
hexo.config.minify.zstd.include = [
|
||||
'!dolor.html'
|
||||
]
|
||||
hexo.config.minify.zstd.globOptions = {
|
||||
basename: false
|
||||
}
|
||||
|
||||
paths.forEach((inpath) => {
|
||||
hexo.route.set(inpath, input)
|
||||
})
|
||||
await z()
|
||||
|
||||
const routeList = hexo.route.list()
|
||||
const expected = paths.map((path) => path.concat('.zst'))
|
||||
|
||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
||||
})
|
||||
|
||||
test('blns', async () => {
|
||||
const blns = require('./fixtures/blns.json')
|
||||
|
||||
for (const nStr of blns) {
|
||||
hexo.route.remove(path)
|
||||
|
||||
hexo.route.set(path, nStr)
|
||||
|
||||
await z()
|
||||
|
||||
const output = hexo.route.get(path.concat('.zst'))
|
||||
const buf = []
|
||||
output.on('data', (chunk) => (buf.push(chunk)))
|
||||
output.on('end', async () => {
|
||||
const result = Buffer.concat(buf)
|
||||
const resultUnzst = await unzstd(result)
|
||||
|
||||
expect(resultUnzst.toString()).toBe(nStr)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue