mirror of
https://github.com/SamEyeBam/animate.git
synced 2026-03-23 06:52:05 +00:00
larry babby and threejs for glsl
This commit is contained in:
33
webGl/my-threejs-test/node_modules/htmlnano/docs/README.md
generated
vendored
Normal file
33
webGl/my-threejs-test/node_modules/htmlnano/docs/README.md
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# Website
|
||||
|
||||
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
|
||||
|
||||
## Installation
|
||||
|
||||
```console
|
||||
yarn install
|
||||
```
|
||||
|
||||
## Local Development
|
||||
|
||||
```console
|
||||
yarn start
|
||||
```
|
||||
|
||||
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
||||
|
||||
## Build
|
||||
|
||||
```console
|
||||
yarn build
|
||||
```
|
||||
|
||||
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
||||
|
||||
## Deployment
|
||||
|
||||
```console
|
||||
GIT_USER=<Your GitHub username> USE_SSH=true yarn deploy
|
||||
```
|
||||
|
||||
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
||||
3
webGl/my-threejs-test/node_modules/htmlnano/docs/babel.config.js
generated
vendored
Normal file
3
webGl/my-threejs-test/node_modules/htmlnano/docs/babel.config.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||
};
|
||||
22
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/010-introduction.md
generated
vendored
Normal file
22
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/010-introduction.md
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
slug: /
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
Modular HTML minifier, built on top of the [PostHTML](https://github.com/posthtml/posthtml).
|
||||
Inspired by [cssnano](http://cssnano.co/).
|
||||
|
||||
|
||||
## [Benchmark](https://github.com/maltsev/html-minifiers-benchmark/blob/master/README.md)
|
||||
[html-minifier-terser@5.1.1]: https://www.npmjs.com/package/html-minifier-terser
|
||||
[htmlnano@2.0.0]: https://www.npmjs.com/package/htmlnano
|
||||
|
||||
| Website | Source (KB) | [html-minifier-terser@5.1.1] | [htmlnano@2.0.0] |
|
||||
|---------|------------:|----------------:|-----------:|
|
||||
| [stackoverflow.blog](https://stackoverflow.blog/) | 95 | 87 | 82 |
|
||||
| [github.com](https://github.com/) | 210 | 183 | 171 |
|
||||
| [en.wikipedia.org](https://en.wikipedia.org/wiki/Main_Page) | 78 | 72 | 72 |
|
||||
| [npmjs.com](https://www.npmjs.com/features) | 41 | 38 | 36 |
|
||||
| **Avg. minify rate** | 0% | **9%** | **13%** |
|
||||
117
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/020-usage.md
generated
vendored
Normal file
117
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/020-usage.md
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
# Usage
|
||||
## Javascript
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
const options = {
|
||||
removeEmptyAttributes: false, // Disable the module "removeEmptyAttributes"
|
||||
collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
|
||||
};
|
||||
// posthtml, posthtml-render, and posthtml-parse options
|
||||
const postHtmlOptions = {
|
||||
sync: true, // https://github.com/posthtml/posthtml#usage
|
||||
lowerCaseTags: true, // https://github.com/posthtml/posthtml-parser#options
|
||||
quoteAllAttributes: false, // https://github.com/posthtml/posthtml-render#options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
// "preset" arg might be skipped (see "Presets" section below for more info)
|
||||
// "postHtmlOptions" arg might be skipped
|
||||
.process(html, options, preset, postHtmlOptions)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## PostHTML
|
||||
Just add `htmlnano` as a final plugin:
|
||||
```js
|
||||
const posthtml = require('posthtml');
|
||||
const options = {
|
||||
removeComments: false, // Disable the module "removeComments"
|
||||
collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
|
||||
};
|
||||
const posthtmlPlugins = [
|
||||
/* other PostHTML plugins */
|
||||
|
||||
require('htmlnano')(options)
|
||||
];
|
||||
|
||||
const posthtmlOptions = {
|
||||
// See PostHTML docs
|
||||
};
|
||||
|
||||
posthtml(posthtmlPlugins)
|
||||
.process(html, posthtmlOptions)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Webpack
|
||||
|
||||
```sh
|
||||
npm install html-minimizer-webpack-plugin --save-dev
|
||||
npm install htmlnano --save-dev
|
||||
```
|
||||
|
||||
```js
|
||||
// webpack.config.js
|
||||
const HtmlMinimizerWebpackPlugin = require('html-minimizer-webpack-plugin');
|
||||
const htmlnano = require('htmlnano');
|
||||
|
||||
module.exports = {
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
// For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
|
||||
// `...`,
|
||||
new HtmlMinimizerWebpackPlugin({
|
||||
// Add HtmlMinimizerWebpackPlugin's option here, see https://webpack.js.org/plugins/html-minimizer-webpack-plugin/#options
|
||||
// test: /\.html(\?.*)?$/i,
|
||||
|
||||
// Use htmlnano as HtmlMinimizerWebpackPlugin's minimizer
|
||||
minify: htmlnano.htmlMinimizerWebpackPluginMinify,
|
||||
minimizerOptions: {
|
||||
// Add htmlnano's option here
|
||||
removeComments: false, // Disable the module "removeComments"
|
||||
collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Gulp
|
||||
```bash
|
||||
npm i -D gulp-posthtml htmlnano
|
||||
```
|
||||
|
||||
```js
|
||||
const gulp = require('gulp');
|
||||
const posthtml = require('gulp-posthtml');
|
||||
const htmlnano = require('htmlnano');
|
||||
const options = {
|
||||
removeComments: false
|
||||
};
|
||||
|
||||
gulp.task('default', function() {
|
||||
return gulp
|
||||
.src('./index.html')
|
||||
.pipe(posthtml([
|
||||
// Add `htmlnano` as a final plugin
|
||||
htmlnano(options)
|
||||
]))
|
||||
.pipe(gulp.dest('./build'));
|
||||
});
|
||||
```
|
||||
21
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/030-config.md
generated
vendored
Normal file
21
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/030-config.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Config
|
||||
|
||||
There are two main ways to configure htmlnano:
|
||||
|
||||
## Passing options to `htmlnano` directly
|
||||
This is the way described above in the examples.
|
||||
|
||||
## Using configuration file
|
||||
Alternatively, you might create a configuration file (e.g., `htmlnanorc.json` or `htmlnanorc.js`) or save options to `package.json` with `htmlnano` key.
|
||||
`htmlnano` uses `cosmiconfig`, so refer to [its documentation](https://github.com/davidtheclark/cosmiconfig/blob/main/README.md) for a more detailed description.
|
||||
|
||||
If you want to specify a preset that way, use `preset` key:
|
||||
|
||||
```json
|
||||
{
|
||||
"preset": "max",
|
||||
}
|
||||
```
|
||||
|
||||
Configuration files have lower precedence than passing options to `htmlnano` directly.
|
||||
So if you use both ways, then the configuration file would be ignored.
|
||||
75
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/040-presets.md
generated
vendored
Normal file
75
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/040-presets.md
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# Presets
|
||||
|
||||
A preset is just an object with modules config.
|
||||
|
||||
Currently the following presets are available:
|
||||
- [safe](https://github.com/posthtml/htmlnano/blob/master/lib/presets/safe.mjs) — a default preset for minifying a regular HTML in a safe way (without breaking anything)
|
||||
- [ampSafe](https://github.com/posthtml/htmlnano/blob/master/lib/presets/ampSafe.mjs) - same as `safe` preset but for [AMP pages](https://www.ampproject.org/)
|
||||
- [max](https://github.com/posthtml/htmlnano/blob/master/lib/presets/max.mjs) - maximal minification (might break some pages)
|
||||
|
||||
|
||||
You can use them the following way:
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
const ampSafePreset = require('htmlnano').presets.ampSafe;
|
||||
const options = {
|
||||
// Your options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
.process(html, options, ampSafePreset)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
If you skip `preset` argument [`safe`](https://github.com/posthtml/htmlnano/blob/master/lib/presets/safe.mjs) preset would be used by default.
|
||||
|
||||
|
||||
If you'd like to define your very own config without any presets pass an empty object as a preset:
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
const options = {
|
||||
// Your options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
.process(html, options, {})
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
You might create also your own presets:
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
// Preset for minifying email templates
|
||||
const emailPreset = {
|
||||
mergeStyles: true,
|
||||
minifyCss: {
|
||||
safe: true
|
||||
},
|
||||
};
|
||||
|
||||
const options = {
|
||||
// Some specific options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
.process(html, options, emailPreset)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
Feel free [to submit a PR](https://github.com/posthtml/htmlnano/issues/new) with your preset if it might be useful for other developers as well.
|
||||
855
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/050-modules.md
generated
vendored
Normal file
855
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/050-modules.md
generated
vendored
Normal file
@@ -0,0 +1,855 @@
|
||||
# Modules
|
||||
|
||||
By default the modules should only perform safe transforms, see the module documentation below for details.
|
||||
You can disable modules by passing `false` as option, and enable them by passing `true`.
|
||||
|
||||
The order in which the modules are documented is also the order in which they are applied.
|
||||
|
||||
## Attributes
|
||||
|
||||
### normalizeAttributeValues
|
||||
|
||||
- Normalize casing of specific attribute values that are case-insensitive (like `form[method]`, `img[img]` and `input[type]`).
|
||||
- Apply [invalid value default](https://html.spec.whatwg.org/#invalid-value-default) attribute to invalid attribute values (like `<input type=foo>` to `<input type=text>`, which can then be minified to `<input>` by `removeRedundantAttributes` module).
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<form method="GET"></form>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<form method="get"></form>
|
||||
```
|
||||
|
||||
### removeEmptyAttributes
|
||||
Removes empty [safe-to-remove](https://github.com/posthtml/htmlnano/blob/master/lib/modules/removeEmptyAttributes.mjs) attributes.
|
||||
|
||||
#### Side effects
|
||||
This module could break your styles or JS if you use selectors with attributes:
|
||||
```CSS
|
||||
img[style=""] {
|
||||
margin: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<img src="foo.jpg" alt="" style="">
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<img src="foo.jpg" alt="">
|
||||
```
|
||||
|
||||
### collapseAttributeWhitespace
|
||||
Collapse redundant white spaces in list-like attributes (`class`, `rel`, `ping`).
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<a class=" content page " style=" display: block; " href=" https://example.com"></a>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<a class="content page" style="display: block;" href="https://example.com"></a>
|
||||
```
|
||||
|
||||
### removeRedundantAttributes
|
||||
Removes redundant attributes from tags if they contain default values:
|
||||
- `method="get"` from `<form>`
|
||||
- `type="text"` from `<input>`
|
||||
- `type="submit"` from `<button>`
|
||||
- `language="javascript"` and `type="text/javascript"` from `<script>`
|
||||
- `charset` from `<script>` if it's an external script
|
||||
- `media="all"` from `<style>` and `<link>`
|
||||
- `type="text/css"` from `<link rel="stylesheet">`
|
||||
|
||||
#### Options
|
||||
This module is disabled by default, change option to true to enable this module.
|
||||
|
||||
#### Side effects
|
||||
This module could break your styles or JS if you use selectors with attributes:
|
||||
```CSS
|
||||
form[method="get"] {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<form method="get">
|
||||
<input type="text">
|
||||
</form>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<form>
|
||||
<input>
|
||||
</form>
|
||||
```
|
||||
|
||||
### collapseBooleanAttributes
|
||||
|
||||
- Collapses boolean attributes (like `disabled`) to the minimized form.
|
||||
- Collapses empty string value attributes (like `href=""`) to the minimized form.
|
||||
- Collapses [missing value default](https://html.spec.whatwg.org/#missing-value-default) attributes that are empty strings (`audio[preload=auto]` and `video[preload=auto]`) to the minimized form.
|
||||
|
||||
#### Options
|
||||
If your document uses [AMP](https://www.ampproject.org/), set the `amphtml` flag
|
||||
to collapse additonal, AMP-specific boolean attributes:
|
||||
```Json
|
||||
"collapseBooleanAttributes": {
|
||||
"amphtml": true
|
||||
}
|
||||
```
|
||||
|
||||
#### Side effects
|
||||
This module could break your styles or JS if you use selectors with attributes:
|
||||
```CSS
|
||||
button[disabled="disabled"] {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<button disabled="disabled">click</button>
|
||||
<script defer=""></script>
|
||||
<a href=""></a>
|
||||
<video preload="auto"></video>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<button disabled>click</button>
|
||||
<script defer></script>
|
||||
<a href></a>
|
||||
<video preload></video>
|
||||
```
|
||||
|
||||
### deduplicateAttributeValues
|
||||
Remove duplicate values from list-like attributes (`class`, `rel`, `ping`).
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div class="sidebar left sidebar"></div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div class="sidebar left"></div>
|
||||
```
|
||||
|
||||
### minifyUrls
|
||||
Convert absolute URL to relative URL using [relateurl](https://www.npmjs.com/package/relateurl).
|
||||
|
||||
You have to install `relateurl`, `terser` and `srcset` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev relateurl terser srcset
|
||||
# if you prefer yarn
|
||||
# yarn add --dev relateurl terser srcset
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev relateurl terser srcset
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
The base URL to resolve against. Support `String` & `URL`.
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: 'https://example.com' // Valid configuration
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: new URL('https://example.com') // Valid configuration
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: false // The module will be disabled
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: true // Invalid configuration, the module will be disabled
|
||||
});
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
**Basic Usage**
|
||||
|
||||
Configuration:
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: 'https://example.com'
|
||||
});
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<a href="https://example.com/foo/bar/baz">bar</a>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<a href="foo/bar/baz">bar</a>
|
||||
```
|
||||
|
||||
**With sub-directory**
|
||||
|
||||
Configuration:
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: 'https://example.com/foo/baz/'
|
||||
});
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<a href="https://example.com/foo/bar">bar</a>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<a href="../bar">bar</a>
|
||||
```
|
||||
|
||||
|
||||
### sortAttributes
|
||||
Sort attributes inside elements.
|
||||
|
||||
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
||||
|
||||
#### Options
|
||||
|
||||
- `alphabetical`: Default option. Sort attributes in alphabetical order.
|
||||
- `frequency`: Sort attributes by frequency.
|
||||
|
||||
#### Example
|
||||
|
||||
**alphabetical**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<input type="text" class="form-control" name="testInput" autofocus="" autocomplete="off" id="testId">
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<input autocomplete="off" autofocus="" class="form-control" id="testId" name="testInput" type="text">
|
||||
```
|
||||
|
||||
**frequency**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<input type="text" class="form-control" name="testInput" id="testId">
|
||||
<a id="testId" href="#" class="testClass"></a>
|
||||
<img width="20" src="../images/image.png" height="40" alt="image" class="cls" id="id2">
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<input class="form-control" id="testId" type="text" name="testInput">
|
||||
<a class="testClass" id="testId" href="#"></a>
|
||||
<img class="cls" id="id2" width="20" src="../images/image.png" height="40" alt="image">
|
||||
```
|
||||
|
||||
|
||||
|
||||
### sortAttributesWithLists
|
||||
Sort values in list-like attributes (`class`, `rel`, `ping`).
|
||||
|
||||
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
||||
|
||||
#### Options
|
||||
|
||||
- `alphabetical`: Default option. Sort attribute values in alphabetical order.
|
||||
- `frequency`: Sort attribute values by frequency.
|
||||
|
||||
#### Example
|
||||
|
||||
**alphabetical**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<div class="foo baz bar">click</div>
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<div class="bar baz foo">click</div>
|
||||
```
|
||||
|
||||
**frequency**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<div class="foo baz bar"></div><div class="bar foo"></div>
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<div class="foo bar baz"></div><div class="foo bar"></div>
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
#### Options
|
||||
- `conservative` — collapses all redundant white spaces to 1 space (default)
|
||||
- `aggressive` — collapses all whitespaces that are redundant and safe to remove
|
||||
- `all` — collapses all redundant white spaces
|
||||
|
||||
#### Side effects
|
||||
|
||||
*all*
|
||||
`<i>hello</i> <i>world</i>` or `<i>hello</i><br><i>world</i>` after minification will be rendered as `helloworld`.
|
||||
To prevent that use either the default `conservative` option, or the `aggressive` option.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div>
|
||||
hello world!
|
||||
<a href="#">answer</a>
|
||||
<style>div { color: red; } </style>
|
||||
<main></main>
|
||||
</div>
|
||||
```
|
||||
|
||||
Minified (with `all`):
|
||||
```html
|
||||
<div>hello world!<a href="#">answer</a><style>div { color: red; } </style><main></main></div>
|
||||
```
|
||||
|
||||
Minified (with `aggressive`):
|
||||
```html
|
||||
<div> hello world! <a href="#">answer</a> <style>div { color: red; } </style><main></main></div>
|
||||
```
|
||||
|
||||
Minified (with `conservative`):
|
||||
```html
|
||||
<div> hello world! <a href="#">answer</a> <style>div { color: red; } </style> <main></main> </div>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## HTML Content
|
||||
|
||||
### collapseWhitespace
|
||||
Collapses redundant white spaces (including new lines). It doesn’t affect white spaces in the elements `<style>`, `<textarea>`, `<script>` and `<pre>`.
|
||||
|
||||
|
||||
### removeComments
|
||||
#### Options
|
||||
- `safe` – removes all HTML comments except the conditional comments and [`<!--noindex--><!--/noindex-->`](https://yandex.com/support/webmaster/controlling-robot/html.xml) (default)
|
||||
- `all` — removes all HTML comments
|
||||
- A `RegExp` — only HTML comments matching the given regexp will be removed.
|
||||
- A `Function` that returns boolean — removes HTML comments that can make the given callback function returns truthy value.
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```js
|
||||
{
|
||||
removeComments: 'all'
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div><!-- test --></div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<div></div>
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```js
|
||||
{
|
||||
removeComments: /<!--(\/)?noindex-->/
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div><!--noindex-->this text will not be indexed<!--/noindex-->Lorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<div>this text will not be indexedLorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```js
|
||||
{
|
||||
removeComments: (comments) => {
|
||||
if (comments.includes('noindex')) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div><!--noindex-->this text will not be indexed<!--/noindex-->Lorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<div>this text will not be indexedLorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
### removeOptionalTags
|
||||
Remove certain tags that can be omitted, see [HTML Standard - 13.1.2.4 Optional tags](https://html.spec.whatwg.org/multipage/syntax.html#optional-tags).
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<html><head><title>Title</title></head><body><p>Hi</p></body></html>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<title>Title</title><p>Hi</p>
|
||||
```
|
||||
|
||||
#### Notice
|
||||
Due to [the limitation of PostHTML](https://github.com/posthtml/htmlnano/issues/99), htmlnano can't remove only the start tag or the end tag of an element. Currently, htmlnano only supports removing the following optional tags, as htmlnano can remove their start tag and end tag at the same time:
|
||||
|
||||
- `html`
|
||||
- `head`
|
||||
- `body`
|
||||
- `colgroup`
|
||||
- `tbody`
|
||||
|
||||
### removeOptionalTags
|
||||
Remove certain tags that can be omitted, see [HTML Standard - 13.1.2.4 Optional tags](https://html.spec.whatwg.org/multipage/syntax.html#optional-tags).
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<html><head><title>Title</title></head><body><p>Hi</p></body></html>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<title>Title</title><p>Hi</p>
|
||||
```
|
||||
|
||||
#### Notice
|
||||
Due to [the limitation of PostHTML](https://github.com/posthtml/htmlnano/issues/99), htmlnano can't remove only the start tag or the end tag of an element. Currently, htmlnano only supports removing the following optional tags, as htmlnano can remove their start tag and end tag at the same time:
|
||||
|
||||
- `html`
|
||||
- `head`
|
||||
- `body`
|
||||
- `colgroup`
|
||||
- `tbody`
|
||||
|
||||
### removeAttributeQuotes
|
||||
Remove quotes around attributes when possible, see [HTML Standard - 12.1.2.3 Attributes - Unquoted attribute value syntax](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2).
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div class="foo" title="hello world"></div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div class=foo title="hello world"></div>
|
||||
```
|
||||
|
||||
#### Notice
|
||||
The feature is implemented by [posthtml-render's `quoteAllAttributes`](https://github.com/posthtml/posthtml-render#options), which is one of the PostHTML's option. So `removeAttributeQuotes` could be overriden by other PostHTML's plugins and PostHTML's configuration.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
posthtml([
|
||||
htmlnano({
|
||||
removeAttributeQuotes: true
|
||||
})
|
||||
]).process(html, {
|
||||
quoteAllAttributes: true
|
||||
})
|
||||
```
|
||||
|
||||
`removeAttributeQuotes` will not work because PostHTML's `quoteAllAttributes` takes the priority.
|
||||
|
||||
|
||||
## `<style>`, `<script>` and `<svg>` Tags
|
||||
### mergeStyles
|
||||
Merges multiple `<style>` with the same `media` and `type` into one tag.
|
||||
`<style scoped>...</style>` are skipped.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<style>h1 { color: red }</style>
|
||||
<style media="print">div { color: blue }</style>
|
||||
|
||||
<style type="text/css" media="print">a {}</style>
|
||||
<style>div { font-size: 20px }</style>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<style>h1 { color: red } div { font-size: 20px }</style>
|
||||
<style media="print">div { color: blue } a {}</style>
|
||||
```
|
||||
|
||||
|
||||
### mergeScripts
|
||||
Merge multiple `<script>` with the same attributes (`id, class, type, async, defer`) into one (last) tag.
|
||||
|
||||
#### Side effects
|
||||
It could break your code if the tags with different attributes share the same variable scope.
|
||||
See the example below.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<script>const foo = 'A:1';</script>
|
||||
<script class="test">foo = 'B:1';</script>
|
||||
<script type="text/javascript">foo = 'A:2';</script>
|
||||
<script defer>foo = 'C:1';</script>
|
||||
<script>foo = 'A:3';</script>
|
||||
<script defer="defer">foo = 'C:2';</script>
|
||||
<script class="test" type="text/javascript">foo = 'B:2';</script>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<script>const foo = 'A:1'; foo = 'A:2'; foo = 'A:3';</script>
|
||||
<script defer="defer">foo = 'C:1'; foo = 'C:2';</script>
|
||||
<script class="test" type="text/javascript">foo = 'B:1'; foo = 'B:2';</script>
|
||||
```
|
||||
|
||||
|
||||
### minifyCss
|
||||
Minifies CSS with [cssnano](http://cssnano.co/) inside `<style>` tags and `style` attributes.
|
||||
|
||||
You have to install `cssnano` and `postcss` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev cssnano postcss
|
||||
# if you prefer yarn
|
||||
# yarn add --dev cssnano postcss
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev cssnano postcss
|
||||
```
|
||||
|
||||
#### Options
|
||||
See [the documentation of cssnano](http://cssnano.co/docs/optimisations/) for all supported optimizations.
|
||||
By default CSS is minified with preset `default`, which shouldn't have any side-effects.
|
||||
|
||||
To use another preset or disabled some optimizations pass options to `minifyCss` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyCss: {
|
||||
preset: ['default', {
|
||||
discardComments: {
|
||||
removeAll: true,
|
||||
},
|
||||
}]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div>
|
||||
<style>
|
||||
h1 {
|
||||
margin: 10px 10px 10px 10px;
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div>
|
||||
<style>h1{margin:10px;color:red}</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
### minifyJs
|
||||
Minifies JS using [Terser](https://github.com/fabiosantoscode/terser) inside `<script>` tags.
|
||||
|
||||
You have to install `terser` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev terser
|
||||
# if you prefer yarn
|
||||
# yarn add --dev terser
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev terser
|
||||
```
|
||||
|
||||
#### Options
|
||||
See [the documentation of Terser](https://github.com/fabiosantoscode/terser#api-reference) for all supported options.
|
||||
Terser options can be passed directly to the `minifyJs` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyJs: {
|
||||
output: { quote_style: 1 },
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div>
|
||||
<script>
|
||||
/* comment */
|
||||
const foo = function () {
|
||||
|
||||
};
|
||||
</script>
|
||||
</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div>
|
||||
<script>const foo=function(){};</script>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
### minifyJson
|
||||
Minifies JSON inside `<script type="application/json"></script>`.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<script type="application/json">
|
||||
{
|
||||
"user": "me"
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<script type="application/json">{"user":"me"}</script>
|
||||
```
|
||||
|
||||
|
||||
### minifySvg
|
||||
Minifies SVG inside `<svg>` tags using [SVGO](https://github.com/svg/svgo/).
|
||||
|
||||
#### Options
|
||||
See [the documentation of SVGO](https://github.com/svg/svgo/blob/master/README.md) for all supported options.
|
||||
SVGO options can be passed directly to the `minifySvg` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifySvg: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
builtinPluginName: {
|
||||
optionName: 'optionValue'
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100%" height="100%" fill="red" />
|
||||
|
||||
<circle cx="150" cy="100" r="80" fill="green" />
|
||||
|
||||
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
|
||||
</svg>`
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<svg baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="red"/><circle cx="150" cy="100" r="80" fill="green"/><text x="150" y="125" font-size="60" text-anchor="middle" fill="#fff">SVG</text></svg>
|
||||
```
|
||||
|
||||
### removeUnusedCss
|
||||
|
||||
Removes unused CSS inside `<style>` tags with either [uncss](https://github.com/uncss/uncss)
|
||||
or [PurgeCSS](https://github.com/FullHuman/purgecss).
|
||||
|
||||
#### With uncss
|
||||
|
||||
You have to install `uncss` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev uncss
|
||||
# if you prefer yarn
|
||||
# yarn add --dev uncss
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev uncss
|
||||
```
|
||||
|
||||
You can also use a mainted fork [@novaatwarren/uncss](https://www.npmjs.com/package/@novaatwarren/uncss) instead.
|
||||
|
||||
|
||||
##### Options
|
||||
See [the documentation of uncss](https://github.com/uncss/uncss) for all supported options.
|
||||
|
||||
uncss options can be passed directly to the `removeUnusedCss` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
removeUnusedCss: {
|
||||
ignore: ['.do-not-remove']
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The following uncss options are ignored if passed to the module:
|
||||
|
||||
- `stylesheets`
|
||||
- `ignoreSheets`
|
||||
- `raw`
|
||||
|
||||
#### With PurgeCSS
|
||||
|
||||
Use PurgeCSS instead of uncss by adding `tool: 'purgeCSS'` to the options.
|
||||
|
||||
You have to install `purgecss` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev purgecss
|
||||
# if you prefer yarn
|
||||
# yarn add --dev purgecss
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev purgecss
|
||||
```
|
||||
|
||||
##### Options
|
||||
|
||||
See [the documentation of PurgeCSS](https://www.purgecss.com) for all supported options.
|
||||
|
||||
PurgeCSS options can be passed directly to the `removeUnusedCss` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
removeUnusedCss: {
|
||||
tool: 'purgeCSS',
|
||||
safelist: ['.do-not-remove']
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The following PurgeCSS options are ignored if passed to the module:
|
||||
|
||||
- `content`
|
||||
- `css`
|
||||
- `extractors`
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div class="b">
|
||||
<style>
|
||||
.a {
|
||||
margin: 10px 10px 10px 10px;
|
||||
}
|
||||
.b {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
Optimized:
|
||||
```html
|
||||
<div class="b">
|
||||
<style>
|
||||
.b {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
### custom
|
||||
It's also possible to pass custom modules in the minifier.
|
||||
As a function:
|
||||
```js
|
||||
const options = {
|
||||
custom: function (tree, options) {
|
||||
// Some minification
|
||||
return tree;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Or as a list of functions:
|
||||
```js
|
||||
const options = {
|
||||
custom: [
|
||||
function (tree, options) {
|
||||
// Some minification
|
||||
return tree;
|
||||
},
|
||||
|
||||
function (tree, options) {
|
||||
// Some other minification
|
||||
return tree;
|
||||
}
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
htmlnano's options are passed to your custom plugin by the second parameter `options`.
|
||||
16
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/060-contribute.md
generated
vendored
Normal file
16
webGl/my-threejs-test/node_modules/htmlnano/docs/docs/060-contribute.md
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Contribute
|
||||
|
||||
Since the minifier is modular, it's very easy to add new modules:
|
||||
|
||||
1. Create a ES6-file inside `lib/modules/` with a function that does some minification. For example you can check [`lib/modules/example.mjs`](https://github.com/posthtml/htmlnano/blob/master/lib/modules/example.mjs).
|
||||
|
||||
2. Add the module's name into one of those [presets](https://github.com/posthtml/htmlnano/tree/master/lib/presets). You can choose either `ampSafe`, `max`, or `safe`.
|
||||
|
||||
3. Create a JS-file inside `test/modules/` with some unit-tests.
|
||||
|
||||
4. Describe your module in the section "[Modules](https://github.com/posthtml/htmlnano/blob/master/README.md#modules)".
|
||||
|
||||
5. Send me a pull request.
|
||||
|
||||
Other types of contribution (bug fixes, documentation improves, etc) are also welcome!
|
||||
Would like to contribute, but don't have any ideas what to do? Check out [our issues](https://github.com/posthtml/htmlnano/labels/help%20wanted).
|
||||
65
webGl/my-threejs-test/node_modules/htmlnano/docs/docusaurus.config.js
generated
vendored
Normal file
65
webGl/my-threejs-test/node_modules/htmlnano/docs/docusaurus.config.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
const lightCodeTheme = require('prism-react-renderer/themes/github');
|
||||
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
|
||||
|
||||
/** @type {import('@docusaurus/types').DocusaurusConfig} */
|
||||
module.exports = {
|
||||
title: 'htmlnano',
|
||||
tagline: 'Modular HTML minifier',
|
||||
url: 'https://htmlnano.netlify.app',
|
||||
favicon: 'favicon.ico',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
organizationName: 'posthtml',
|
||||
projectName: 'htmlnano',
|
||||
trailingSlash: false,
|
||||
plugins: ['docusaurus-plugin-goatcounter'],
|
||||
themeConfig: {
|
||||
navbar: {
|
||||
title: 'htmlnano',
|
||||
items: [
|
||||
{
|
||||
type: 'docsVersionDropdown',
|
||||
position: 'right',
|
||||
dropdownActiveClassDisabled: true,
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/posthtml/htmlnano',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
prism: {
|
||||
theme: lightCodeTheme,
|
||||
darkTheme: darkCodeTheme,
|
||||
},
|
||||
goatcounter: {
|
||||
code: 'htmlnano',
|
||||
},
|
||||
},
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
sidebarPath: require.resolve('./sidebars.js'),
|
||||
routeBasePath: '/',
|
||||
editUrl: 'https://github.com/posthtml/htmlnano/edit/master/docs/',
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
const algoliaConfig = {
|
||||
appId: process.env.ALGOLIA_APP_ID,
|
||||
apiKey: process.env.ALGOLIA_API_KEY,
|
||||
indexName: 'htmlnano',
|
||||
contextualSearch: true,
|
||||
};
|
||||
|
||||
if (algoliaConfig.apiKey) {
|
||||
module.exports.themeConfig.algolia = algoliaConfig;
|
||||
}
|
||||
4
webGl/my-threejs-test/node_modules/htmlnano/docs/netlify.toml
generated
vendored
Normal file
4
webGl/my-threejs-test/node_modules/htmlnano/docs/netlify.toml
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[build]
|
||||
base = "docs/"
|
||||
publish = "build/"
|
||||
command = "npm run build"
|
||||
21612
webGl/my-threejs-test/node_modules/htmlnano/docs/package-lock.json
generated
vendored
Normal file
21612
webGl/my-threejs-test/node_modules/htmlnano/docs/package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
40
webGl/my-threejs-test/node_modules/htmlnano/docs/package.json
generated
vendored
Normal file
40
webGl/my-threejs-test/node_modules/htmlnano/docs/package.json
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "htmlnano-docs",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "2.2.0",
|
||||
"@docusaurus/preset-classic": "2.2.0",
|
||||
"@mdx-js/react": "^1.6.21",
|
||||
"@svgr/webpack": "^6.5.1",
|
||||
"clsx": "^1.1.1",
|
||||
"docusaurus-plugin-goatcounter": "^2.0.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"prism-react-renderer": "^1.2.1",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"url-loader": "^4.1.1"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
26
webGl/my-threejs-test/node_modules/htmlnano/docs/sidebars.js
generated
vendored
Normal file
26
webGl/my-threejs-test/node_modules/htmlnano/docs/sidebars.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Creating a sidebar enables you to:
|
||||
- create an ordered group of docs
|
||||
- render a sidebar for each doc of that group
|
||||
- provide next/previous navigation
|
||||
|
||||
The sidebars can be generated from the filesystem, or explicitly defined here.
|
||||
|
||||
Create as many sidebars as you want.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||
|
||||
// But you can create a sidebar manually
|
||||
/*
|
||||
tutorialSidebar: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Tutorial',
|
||||
items: ['hello'],
|
||||
},
|
||||
],
|
||||
*/
|
||||
};
|
||||
22
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/010-introduction.md
generated
vendored
Normal file
22
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/010-introduction.md
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
slug: /
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
Modular HTML minifier, built on top of the [PostHTML](https://github.com/posthtml/posthtml).
|
||||
Inspired by [cssnano](http://cssnano.co/).
|
||||
|
||||
|
||||
## [Benchmark](https://github.com/maltsev/html-minifiers-benchmark/blob/master/README.md)
|
||||
[html-minifier-terser@5.1.1]: https://www.npmjs.com/package/html-minifier-terser
|
||||
[htmlnano@1.1.1]: https://www.npmjs.com/package/htmlnano
|
||||
|
||||
| Website | Source (KB) | [html-minifier-terser@5.1.1] | [htmlnano@1.1.1] |
|
||||
|---------|------------:|----------------:|-----------:|
|
||||
| [stackoverflow.blog](https://stackoverflow.blog/) | 95 | 87 | 82 |
|
||||
| [github.com](https://github.com/) | 210 | 183 | 171 |
|
||||
| [en.wikipedia.org](https://en.wikipedia.org/wiki/Main_Page) | 78 | 72 | 72 |
|
||||
| [npmjs.com](https://www.npmjs.com/features) | 41 | 38 | 36 |
|
||||
| **Avg. minify rate** | 0% | **9%** | **13%** |
|
||||
77
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/020-usage.md
generated
vendored
Normal file
77
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/020-usage.md
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
# Usage
|
||||
|
||||
## Gulp
|
||||
```bash
|
||||
npm install --save-dev gulp-htmlnano
|
||||
```
|
||||
|
||||
```js
|
||||
const gulp = require('gulp');
|
||||
const htmlnano = require('gulp-htmlnano');
|
||||
const options = {
|
||||
removeComments: false
|
||||
};
|
||||
|
||||
gulp.task('default', function() {
|
||||
return gulp
|
||||
.src('./index.html')
|
||||
.pipe(htmlnano(options))
|
||||
.pipe(gulp.dest('./build'));
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Javascript
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
const options = {
|
||||
removeEmptyAttributes: false, // Disable the module "removeEmptyAttributes"
|
||||
collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
|
||||
};
|
||||
// posthtml, posthtml-render, and posthtml-parse options
|
||||
const postHtmlOptions = {
|
||||
sync: true, // https://github.com/posthtml/posthtml#usage
|
||||
lowerCaseTags: true, // https://github.com/posthtml/posthtml-parser#options
|
||||
quoteAllAttributes: false, // https://github.com/posthtml/posthtml-render#options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
// "preset" arg might be skipped (see "Presets" section below for more info)
|
||||
// "postHtmlOptions" arg might be skipped
|
||||
.process(html, options, preset, postHtmlOptions)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## PostHTML
|
||||
Just add `htmlnano` as a final plugin:
|
||||
```js
|
||||
const posthtml = require('posthtml');
|
||||
const options = {
|
||||
removeComments: false, // Disable the module "removeComments"
|
||||
collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
|
||||
};
|
||||
const posthtmlPlugins = [
|
||||
/* other PostHTML plugins */
|
||||
|
||||
require('htmlnano')(options)
|
||||
];
|
||||
|
||||
const posthtmlOptions = {
|
||||
// See PostHTML docs
|
||||
};
|
||||
|
||||
posthtml(posthtmlPlugins)
|
||||
.process(html, posthtmlOptions)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
21
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/030-config.md
generated
vendored
Normal file
21
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/030-config.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Config
|
||||
|
||||
There are two main ways to configure htmlnano:
|
||||
|
||||
## Passing options to `htmlnano` directly
|
||||
This is the way described above in the examples.
|
||||
|
||||
## Using configuration file
|
||||
Alternatively, you might create a configuration file (e.g., `htmlnanorc.json` or `htmlnanorc.js`) or save options to `package.json` with `htmlnano` key.
|
||||
`htmlnano` uses `cosmiconfig`, so refer to [its documentation](https://github.com/davidtheclark/cosmiconfig/blob/main/README.md) for a more detailed description.
|
||||
|
||||
If you want to specify a preset that way, use `preset` key:
|
||||
|
||||
```json
|
||||
{
|
||||
"preset": "max",
|
||||
}
|
||||
```
|
||||
|
||||
Configuration files have lower precedence than passing options to `htmlnano` directly.
|
||||
So if you use both ways, then the configuration file would be ignored.
|
||||
75
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/040-presets.md
generated
vendored
Normal file
75
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/040-presets.md
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# Presets
|
||||
|
||||
A preset is just an object with modules config.
|
||||
|
||||
Currently the following presets are available:
|
||||
- [safe](https://github.com/posthtml/htmlnano/blob/master/lib/presets/safe.mjs) — a default preset for minifying a regular HTML in a safe way (without breaking anything)
|
||||
- [ampSafe](https://github.com/posthtml/htmlnano/blob/master/lib/presets/ampSafe.mjs) - same as `safe` preset but for [AMP pages](https://www.ampproject.org/)
|
||||
- [max](https://github.com/posthtml/htmlnano/blob/master/lib/presets/max.mjs) - maximal minification (might break some pages)
|
||||
|
||||
|
||||
You can use them the following way:
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
const ampSafePreset = require('htmlnano').presets.ampSafe;
|
||||
const options = {
|
||||
// Your options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
.process(html, options, ampSafePreset)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
If you skip `preset` argument [`safe`](https://github.com/posthtml/htmlnano/blob/master/lib/presets/safe.mjs) preset would be used by default.
|
||||
|
||||
|
||||
If you'd like to define your very own config without any presets pass an empty object as a preset:
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
const options = {
|
||||
// Your options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
.process(html, options, {})
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
You might create also your own presets:
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
// Preset for minifying email templates
|
||||
const emailPreset = {
|
||||
mergeStyles: true,
|
||||
minifyCss: {
|
||||
safe: true
|
||||
},
|
||||
};
|
||||
|
||||
const options = {
|
||||
// Some specific options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
.process(html, options, emailPreset)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
Feel free [to submit a PR](https://github.com/posthtml/htmlnano/issues/new) with your preset if it might be useful for other developers as well.
|
||||
785
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/050-modules.md
generated
vendored
Normal file
785
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/050-modules.md
generated
vendored
Normal file
@@ -0,0 +1,785 @@
|
||||
# Modules
|
||||
|
||||
By default the modules should only perform safe transforms, see the module documentation below for details.
|
||||
You can disable modules by passing `false` as option, and enable them by passing `true`.
|
||||
|
||||
|
||||
### collapseAttributeWhitespace
|
||||
Collapse redundant white spaces in list-like attributes (`class`, `rel`, `ping`).
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<a class=" content page " style=" display: block; " href=" https://example.com"></a>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<a class="content page" style="display: block;" href="https://example.com"></a>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### collapseWhitespace
|
||||
Collapses redundant white spaces (including new lines). It doesn’t affect white spaces in the elements `<style>`, `<textarea>`, `<script>` and `<pre>`.
|
||||
|
||||
#### Options
|
||||
- `conservative` — collapses all redundant white spaces to 1 space (default)
|
||||
- `aggressive` — collapses all whitespaces that are redundant and safe to remove
|
||||
- `all` — collapses all redundant white spaces
|
||||
|
||||
#### Side effects
|
||||
|
||||
*all*
|
||||
`<i>hello</i> <i>world</i>` or `<i>hello</i><br><i>world</i>` after minification will be rendered as `helloworld`.
|
||||
To prevent that use either the default `conservative` option, or the `aggressive` option.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div>
|
||||
hello world!
|
||||
<a href="#">answer</a>
|
||||
<style>div { color: red; } </style>
|
||||
<main></main>
|
||||
</div>
|
||||
```
|
||||
|
||||
Minified (with `all`):
|
||||
```html
|
||||
<div>hello world!<a href="#">answer</a><style>div { color: red; } </style><main></main></div>
|
||||
```
|
||||
|
||||
Minified (with `aggressive`):
|
||||
```html
|
||||
<div> hello world! <a href="#">answer</a> <style>div { color: red; } </style><main></main></div>
|
||||
```
|
||||
|
||||
Minified (with `conservative`):
|
||||
```html
|
||||
<div> hello world! <a href="#">answer</a> <style>div { color: red; } </style> <main></main> </div>
|
||||
```
|
||||
|
||||
|
||||
### deduplicateAttributeValues
|
||||
Remove duplicate values from list-like attributes (`class`, `rel`, `ping`).
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div class="sidebar left sidebar"></div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div class="sidebar left"></div>
|
||||
```
|
||||
|
||||
|
||||
### removeComments
|
||||
#### Options
|
||||
- `safe` – removes all HTML comments except the conditional comments and [`<!--noindex--><!--/noindex-->`](https://yandex.com/support/webmaster/controlling-robot/html.xml) (default)
|
||||
- `all` — removes all HTML comments
|
||||
- A `RegExp` — only HTML comments matching the given regexp will be removed.
|
||||
- A `Function` that returns boolean — removes HTML comments that can make the given callback function returns truthy value.
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```js
|
||||
{
|
||||
removeComments: 'all'
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div><!-- test --></div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<div></div>
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```js
|
||||
{
|
||||
removeComments: /<!--(\/)?noindex-->/
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div><!--noindex-->this text will not be indexed<!--/noindex-->Lorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<div>this text will not be indexedLorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```js
|
||||
{
|
||||
removeComments: (comments) => {
|
||||
if (comments.includes('noindex')) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div><!--noindex-->this text will not be indexed<!--/noindex-->Lorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<div>this text will not be indexedLorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
|
||||
### removeEmptyAttributes
|
||||
Removes empty [safe-to-remove](https://github.com/posthtml/htmlnano/blob/master/lib/modules/removeEmptyAttributes.mjs) attributes.
|
||||
|
||||
#### Side effects
|
||||
This module could break your styles or JS if you use selectors with attributes:
|
||||
```CSS
|
||||
img[style=""] {
|
||||
margin: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<img src="foo.jpg" alt="" style="">
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<img src="foo.jpg" alt="">
|
||||
```
|
||||
|
||||
### removeAttributeQuotes
|
||||
Remove quotes around attributes when possible, see [HTML Standard - 12.1.2.3 Attributes - Unquoted attribute value syntax](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2).
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div class="foo" title="hello world"></div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div class=foo title="hello world"></div>
|
||||
```
|
||||
|
||||
#### Notice
|
||||
The feature is implemented by [posthtml-render's `quoteAllAttributes`](https://github.com/posthtml/posthtml-render#options), which is one of the PostHTML's option. So `removeAttributeQuotes` could be overriden by other PostHTML's plugins and PostHTML's configuration.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
posthtml([
|
||||
htmlnano({
|
||||
removeAttributeQuotes: true
|
||||
})
|
||||
]).process(html, {
|
||||
quoteAllAttributes: true
|
||||
})
|
||||
```
|
||||
|
||||
`removeAttributeQuotes` will not work because PostHTML's `quoteAllAttributes` takes the priority.
|
||||
|
||||
### removeUnusedCss
|
||||
|
||||
Removes unused CSS inside `<style>` tags with either [uncss](https://github.com/uncss/uncss)
|
||||
or [PurgeCSS](https://github.com/FullHuman/purgecss).
|
||||
|
||||
#### With uncss
|
||||
|
||||
##### Options
|
||||
See [the documentation of uncss](https://github.com/uncss/uncss) for all supported options.
|
||||
|
||||
uncss options can be passed directly to the `removeUnusedCss` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
removeUnusedCss: {
|
||||
ignore: ['.do-not-remove']
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The following uncss options are ignored if passed to the module:
|
||||
|
||||
- `stylesheets`
|
||||
- `ignoreSheets`
|
||||
- `raw`
|
||||
|
||||
#### With PurgeCSS
|
||||
|
||||
Use PurgeCSS instead of uncss by adding `tool: 'purgeCSS'` to the options.
|
||||
|
||||
##### Options
|
||||
|
||||
See [the documentation of PurgeCSS](https://www.purgecss.com) for all supported options.
|
||||
|
||||
PurgeCSS options can be passed directly to the `removeUnusedCss` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
removeUnusedCss: {
|
||||
tool: 'purgeCSS',
|
||||
safelist: ['.do-not-remove']
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The following PurgeCSS options are ignored if passed to the module:
|
||||
|
||||
- `content`
|
||||
- `css`
|
||||
- `extractors`
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div class="b">
|
||||
<style>
|
||||
.a {
|
||||
margin: 10px 10px 10px 10px;
|
||||
}
|
||||
.b {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
Optimized:
|
||||
```html
|
||||
<div class="b">
|
||||
<style>
|
||||
.b {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
### minifyCss
|
||||
Minifies CSS with [cssnano](http://cssnano.co/) inside `<style>` tags and `style` attributes.
|
||||
|
||||
#### Options
|
||||
See [the documentation of cssnano](http://cssnano.co/optimisations/) for all supported optimizations.
|
||||
By default CSS is minified with preset `default`, which shouldn't have any side-effects.
|
||||
|
||||
To use another preset or disabled some optimizations pass options to `minifyCss` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyCss: {
|
||||
preset: ['default', {
|
||||
discardComments: {
|
||||
removeAll: true,
|
||||
},
|
||||
}]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div>
|
||||
<style>
|
||||
h1 {
|
||||
margin: 10px 10px 10px 10px;
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div>
|
||||
<style>h1{margin:10px;color:red}</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
### minifyJs
|
||||
Minifies JS using [Terser](https://github.com/fabiosantoscode/terser) inside `<script>` tags.
|
||||
|
||||
#### Options
|
||||
See [the documentation of Terser](https://github.com/fabiosantoscode/terser#api-reference) for all supported options.
|
||||
Terser options can be passed directly to the `minifyJs` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyJs: {
|
||||
output: { quote_style: 1 },
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div>
|
||||
<script>
|
||||
/* comment */
|
||||
const foo = function () {
|
||||
|
||||
};
|
||||
</script>
|
||||
</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div>
|
||||
<script>const foo=function(){};</script>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
### minifyJson
|
||||
Minifies JSON inside `<script type="application/json"></script>`.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<script type="application/json">
|
||||
{
|
||||
"user": "me"
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<script type="application/json">{"user":"me"}</script>
|
||||
```
|
||||
|
||||
|
||||
### minifySvg
|
||||
Minifies SVG inside `<svg>` tags using [SVGO](https://github.com/svg/svgo/).
|
||||
|
||||
#### Options
|
||||
See [the documentation of SVGO](https://github.com/svg/svgo/blob/master/README.md) for all supported options.
|
||||
SVGO options can be passed directly to the `minifySvg` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifySvg: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
builtinPluginName: {
|
||||
optionName: 'optionValue'
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100%" height="100%" fill="red" />
|
||||
|
||||
<circle cx="150" cy="100" r="80" fill="green" />
|
||||
|
||||
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
|
||||
</svg>`
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<svg baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="red"/><circle cx="150" cy="100" r="80" fill="green"/><text x="150" y="125" font-size="60" text-anchor="middle" fill="#fff">SVG</text></svg>
|
||||
```
|
||||
|
||||
### minifyConditionalComments
|
||||
|
||||
Minify content inside conditional comments.
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<!--[if lte IE 7]>
|
||||
<style type="text/css">
|
||||
.title {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<!--[if lte IE 7]><style>.title{color:red}</style><![endif]-->
|
||||
```
|
||||
|
||||
### removeRedundantAttributes
|
||||
Removes redundant attributes from tags if they contain default values:
|
||||
- `method="get"` from `<form>`
|
||||
- `type="text"` from `<input>`
|
||||
- `type="submit"` from `<button>`
|
||||
- `language="javascript"` and `type="text/javascript"` from `<script>`
|
||||
- `charset` from `<script>` if it's an external script
|
||||
- `media="all"` from `<style>` and `<link>`
|
||||
- `type="text/css"` from `<link rel="stylesheet">`
|
||||
|
||||
#### Options
|
||||
This module is disabled by default, change option to true to enable this module.
|
||||
|
||||
#### Side effects
|
||||
This module could break your styles or JS if you use selectors with attributes:
|
||||
```CSS
|
||||
form[method="get"] {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<form method="get">
|
||||
<input type="text">
|
||||
</form>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<form>
|
||||
<input>
|
||||
</form>
|
||||
```
|
||||
|
||||
|
||||
### collapseBooleanAttributes
|
||||
Collapses boolean attributes (like `disabled`) to the minimized form.
|
||||
|
||||
#### Options
|
||||
If your document uses [AMP](https://www.ampproject.org/), set the `amphtml` flag
|
||||
to collapse additonal, AMP-specific boolean attributes:
|
||||
```Json
|
||||
"collapseBooleanAttributes": {
|
||||
"amphtml": true
|
||||
}
|
||||
```
|
||||
|
||||
#### Side effects
|
||||
This module could break your styles or JS if you use selectors with attributes:
|
||||
```CSS
|
||||
button[disabled="disabled"] {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<button disabled="disabled">click</button>
|
||||
<script defer=""></script>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<button disabled>click</button>
|
||||
<script defer></script>
|
||||
```
|
||||
|
||||
|
||||
### mergeStyles
|
||||
Merges multiple `<style>` with the same `media` and `type` into one tag.
|
||||
`<style scoped>...</style>` are skipped.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<style>h1 { color: red }</style>
|
||||
<style media="print">div { color: blue }</style>
|
||||
|
||||
<style type="text/css" media="print">a {}</style>
|
||||
<style>div { font-size: 20px }</style>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<style>h1 { color: red } div { font-size: 20px }</style>
|
||||
<style media="print">div { color: blue } a {}</style>
|
||||
```
|
||||
|
||||
|
||||
### mergeScripts
|
||||
Merge multiple `<script>` with the same attributes (`id, class, type, async, defer`) into one (last) tag.
|
||||
|
||||
#### Side effects
|
||||
It could break your code if the tags with different attributes share the same variable scope.
|
||||
See the example below.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<script>const foo = 'A:1';</script>
|
||||
<script class="test">foo = 'B:1';</script>
|
||||
<script type="text/javascript">foo = 'A:2';</script>
|
||||
<script defer>foo = 'C:1';</script>
|
||||
<script>foo = 'A:3';</script>
|
||||
<script defer="defer">foo = 'C:2';</script>
|
||||
<script class="test" type="text/javascript">foo = 'B:2';</script>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<script>const foo = 'A:1'; foo = 'A:2'; foo = 'A:3';</script>
|
||||
<script defer="defer">foo = 'C:1'; foo = 'C:2';</script>
|
||||
<script class="test" type="text/javascript">foo = 'B:1'; foo = 'B:2';</script>
|
||||
```
|
||||
|
||||
|
||||
### custom
|
||||
It's also possible to pass custom modules in the minifier.
|
||||
As a function:
|
||||
```js
|
||||
const options = {
|
||||
custom: function (tree, options) {
|
||||
// Some minification
|
||||
return tree;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Or as a list of functions:
|
||||
```js
|
||||
const options = {
|
||||
custom: [
|
||||
function (tree, options) {
|
||||
// Some minification
|
||||
return tree;
|
||||
},
|
||||
|
||||
function (tree, options) {
|
||||
// Some other minification
|
||||
return tree;
|
||||
}
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
`options` is an object with all options that were passed to the plugin.
|
||||
|
||||
### sortAttributesWithLists
|
||||
Sort values in list-like attributes (`class`, `rel`, `ping`).
|
||||
|
||||
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
||||
|
||||
#### Options
|
||||
|
||||
- `alphabetical`: Default option. Sort attribute values in alphabetical order.
|
||||
- `frequency`: Sort attribute values by frequency.
|
||||
|
||||
#### Example
|
||||
|
||||
**alphabetical**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<div class="foo baz bar">click</div>
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<div class="bar baz foo">click</div>
|
||||
```
|
||||
|
||||
**frequency**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<div class="foo baz bar"></div><div class="bar foo"></div>
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<div class="foo bar baz"></div><div class="foo bar"></div>
|
||||
```
|
||||
|
||||
### sortAttributes
|
||||
Sort attributes inside elements.
|
||||
|
||||
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
||||
|
||||
#### Options
|
||||
|
||||
- `alphabetical`: Default option. Sort attributes in alphabetical order.
|
||||
- `frequency`: Sort attributes by frequency.
|
||||
|
||||
#### Example
|
||||
|
||||
**alphabetical**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<input type="text" class="form-control" name="testInput" autofocus="" autocomplete="off" id="testId">
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<input autocomplete="off" autofocus="" class="form-control" id="testId" name="testInput" type="text">
|
||||
```
|
||||
|
||||
**frequency**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<input type="text" class="form-control" name="testInput" id="testId">
|
||||
<a id="testId" href="#" class="testClass"></a>
|
||||
<img width="20" src="../images/image.png" height="40" alt="image" class="cls" id="id2">
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<input class="form-control" id="testId" type="text" name="testInput">
|
||||
<a class="testClass" id="testId" href="#"></a>
|
||||
<img class="cls" id="id2" width="20" src="../images/image.png" height="40" alt="image">
|
||||
```
|
||||
|
||||
### minifyUrls
|
||||
Convert absolute URL to relative URL using [relateurl](https://www.npmjs.com/package/relateurl).
|
||||
|
||||
#### Options
|
||||
|
||||
The base URL to resolve against. Support `String` & `URL`.
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: 'https://example.com' // Valid configuration
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: new URL('https://example.com') // Valid configuration
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: false // The module will be disabled
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: true // Invalid configuration, the module will be disabled
|
||||
});
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
**Basic Usage**
|
||||
|
||||
Configuration:
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: 'https://example.com'
|
||||
});
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<a href="https://example.com/foo/bar/baz">bar</a>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<a href="foo/bar/baz">bar</a>
|
||||
```
|
||||
|
||||
**With sub-directory**
|
||||
|
||||
Configuration:
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: 'https://example.com/foo/baz/'
|
||||
});
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<a href="https://example.com/foo/bar">bar</a>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<a href="../bar">bar</a>
|
||||
```
|
||||
|
||||
### removeOptionalTags
|
||||
Remove certain tags that can be omitted, see [HTML Standard - 13.1.2.4 Optional tags](https://html.spec.whatwg.org/multipage/syntax.html#optional-tags).
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<html><head><title>Title</title></head><body><p>Hi</p></body></html>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<title>Title</title><p>Hi</p>
|
||||
```
|
||||
|
||||
#### Notice
|
||||
Due to [the limitation of PostHTML](https://github.com/posthtml/htmlnano/issues/99), htmlnano can't remove only the start tag or the end tag of an element. Currently, htmlnano only supports removing the following optional tags, as htmlnano can remove their start tag and end tag at the same time:
|
||||
|
||||
- `html`
|
||||
- `head`
|
||||
- `body`
|
||||
- `colgroup`
|
||||
- `tbody`
|
||||
|
||||
### normalizeAttributeValues
|
||||
|
||||
Normalize casing of attribute values.
|
||||
|
||||
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<form method="GET"></form>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<form method="get"></form>
|
||||
```
|
||||
16
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/060-contribute.md
generated
vendored
Normal file
16
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-1.1.1/060-contribute.md
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Contribute
|
||||
|
||||
Since the minifier is modular, it's very easy to add new modules:
|
||||
|
||||
1. Create a ES6-file inside `lib/modules/` with a function that does some minification. For example you can check [`lib/modules/example.mjs`](https://github.com/posthtml/htmlnano/blob/master/lib/modules/example.mjs).
|
||||
|
||||
2. Add the module's name into one of those [presets](https://github.com/posthtml/htmlnano/tree/master/lib/presets). You can choose either `ampSafe`, `max`, or `safe`.
|
||||
|
||||
3. Create a JS-file inside `test/modules/` with some unit-tests.
|
||||
|
||||
4. Describe your module in the section "[Modules](https://github.com/posthtml/htmlnano/blob/master/README.md#modules)".
|
||||
|
||||
5. Send me a pull request.
|
||||
|
||||
Other types of contribution (bug fixes, documentation improves, etc) are also welcome!
|
||||
Would like to contribute, but don't have any ideas what to do? Check out [our issues](https://github.com/posthtml/htmlnano/labels/help%20wanted).
|
||||
22
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/010-introduction.md
generated
vendored
Normal file
22
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/010-introduction.md
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
slug: /
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
Modular HTML minifier, built on top of the [PostHTML](https://github.com/posthtml/posthtml).
|
||||
Inspired by [cssnano](http://cssnano.co/).
|
||||
|
||||
|
||||
## [Benchmark](https://github.com/maltsev/html-minifiers-benchmark/blob/master/README.md)
|
||||
[html-minifier-terser@5.1.1]: https://www.npmjs.com/package/html-minifier-terser
|
||||
[htmlnano@2.0.0]: https://www.npmjs.com/package/htmlnano
|
||||
|
||||
| Website | Source (KB) | [html-minifier-terser@5.1.1] | [htmlnano@2.0.0] |
|
||||
|---------|------------:|----------------:|-----------:|
|
||||
| [stackoverflow.blog](https://stackoverflow.blog/) | 95 | 87 | 82 |
|
||||
| [github.com](https://github.com/) | 210 | 183 | 171 |
|
||||
| [en.wikipedia.org](https://en.wikipedia.org/wiki/Main_Page) | 78 | 72 | 72 |
|
||||
| [npmjs.com](https://www.npmjs.com/features) | 41 | 38 | 36 |
|
||||
| **Avg. minify rate** | 0% | **9%** | **13%** |
|
||||
77
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/020-usage.md
generated
vendored
Normal file
77
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/020-usage.md
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
# Usage
|
||||
|
||||
## Gulp
|
||||
```bash
|
||||
npm install --save-dev gulp-htmlnano
|
||||
```
|
||||
|
||||
```js
|
||||
const gulp = require('gulp');
|
||||
const htmlnano = require('gulp-htmlnano');
|
||||
const options = {
|
||||
removeComments: false
|
||||
};
|
||||
|
||||
gulp.task('default', function() {
|
||||
return gulp
|
||||
.src('./index.html')
|
||||
.pipe(htmlnano(options))
|
||||
.pipe(gulp.dest('./build'));
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Javascript
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
const options = {
|
||||
removeEmptyAttributes: false, // Disable the module "removeEmptyAttributes"
|
||||
collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
|
||||
};
|
||||
// posthtml, posthtml-render, and posthtml-parse options
|
||||
const postHtmlOptions = {
|
||||
sync: true, // https://github.com/posthtml/posthtml#usage
|
||||
lowerCaseTags: true, // https://github.com/posthtml/posthtml-parser#options
|
||||
quoteAllAttributes: false, // https://github.com/posthtml/posthtml-render#options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
// "preset" arg might be skipped (see "Presets" section below for more info)
|
||||
// "postHtmlOptions" arg might be skipped
|
||||
.process(html, options, preset, postHtmlOptions)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## PostHTML
|
||||
Just add `htmlnano` as a final plugin:
|
||||
```js
|
||||
const posthtml = require('posthtml');
|
||||
const options = {
|
||||
removeComments: false, // Disable the module "removeComments"
|
||||
collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
|
||||
};
|
||||
const posthtmlPlugins = [
|
||||
/* other PostHTML plugins */
|
||||
|
||||
require('htmlnano')(options)
|
||||
];
|
||||
|
||||
const posthtmlOptions = {
|
||||
// See PostHTML docs
|
||||
};
|
||||
|
||||
posthtml(posthtmlPlugins)
|
||||
.process(html, posthtmlOptions)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
21
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/030-config.md
generated
vendored
Normal file
21
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/030-config.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Config
|
||||
|
||||
There are two main ways to configure htmlnano:
|
||||
|
||||
## Passing options to `htmlnano` directly
|
||||
This is the way described above in the examples.
|
||||
|
||||
## Using configuration file
|
||||
Alternatively, you might create a configuration file (e.g., `htmlnanorc.json` or `htmlnanorc.js`) or save options to `package.json` with `htmlnano` key.
|
||||
`htmlnano` uses `cosmiconfig`, so refer to [its documentation](https://github.com/davidtheclark/cosmiconfig/blob/main/README.md) for a more detailed description.
|
||||
|
||||
If you want to specify a preset that way, use `preset` key:
|
||||
|
||||
```json
|
||||
{
|
||||
"preset": "max",
|
||||
}
|
||||
```
|
||||
|
||||
Configuration files have lower precedence than passing options to `htmlnano` directly.
|
||||
So if you use both ways, then the configuration file would be ignored.
|
||||
75
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/040-presets.md
generated
vendored
Normal file
75
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/040-presets.md
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# Presets
|
||||
|
||||
A preset is just an object with modules config.
|
||||
|
||||
Currently the following presets are available:
|
||||
- [safe](https://github.com/posthtml/htmlnano/blob/master/lib/presets/safe.mjs) — a default preset for minifying a regular HTML in a safe way (without breaking anything)
|
||||
- [ampSafe](https://github.com/posthtml/htmlnano/blob/master/lib/presets/ampSafe.mjs) - same as `safe` preset but for [AMP pages](https://www.ampproject.org/)
|
||||
- [max](https://github.com/posthtml/htmlnano/blob/master/lib/presets/max.mjs) - maximal minification (might break some pages)
|
||||
|
||||
|
||||
You can use them the following way:
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
const ampSafePreset = require('htmlnano').presets.ampSafe;
|
||||
const options = {
|
||||
// Your options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
.process(html, options, ampSafePreset)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
If you skip `preset` argument [`safe`](https://github.com/posthtml/htmlnano/blob/master/lib/presets/safe.mjs) preset would be used by default.
|
||||
|
||||
|
||||
If you'd like to define your very own config without any presets pass an empty object as a preset:
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
const options = {
|
||||
// Your options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
.process(html, options, {})
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
You might create also your own presets:
|
||||
```js
|
||||
const htmlnano = require('htmlnano');
|
||||
// Preset for minifying email templates
|
||||
const emailPreset = {
|
||||
mergeStyles: true,
|
||||
minifyCss: {
|
||||
safe: true
|
||||
},
|
||||
};
|
||||
|
||||
const options = {
|
||||
// Some specific options
|
||||
};
|
||||
|
||||
htmlnano
|
||||
.process(html, options, emailPreset)
|
||||
.then(function (result) {
|
||||
// result.html is minified
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
```
|
||||
|
||||
Feel free [to submit a PR](https://github.com/posthtml/htmlnano/issues/new) with your preset if it might be useful for other developers as well.
|
||||
838
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/050-modules.md
generated
vendored
Normal file
838
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/050-modules.md
generated
vendored
Normal file
@@ -0,0 +1,838 @@
|
||||
# Modules
|
||||
|
||||
By default the modules should only perform safe transforms, see the module documentation below for details.
|
||||
You can disable modules by passing `false` as option, and enable them by passing `true`.
|
||||
|
||||
|
||||
### collapseAttributeWhitespace
|
||||
Collapse redundant white spaces in list-like attributes (`class`, `rel`, `ping`).
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<a class=" content page " style=" display: block; " href=" https://example.com"></a>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<a class="content page" style="display: block;" href="https://example.com"></a>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### collapseWhitespace
|
||||
Collapses redundant white spaces (including new lines). It doesn’t affect white spaces in the elements `<style>`, `<textarea>`, `<script>` and `<pre>`.
|
||||
|
||||
#### Options
|
||||
- `conservative` — collapses all redundant white spaces to 1 space (default)
|
||||
- `aggressive` — collapses all whitespaces that are redundant and safe to remove
|
||||
- `all` — collapses all redundant white spaces
|
||||
|
||||
#### Side effects
|
||||
|
||||
*all*
|
||||
`<i>hello</i> <i>world</i>` or `<i>hello</i><br><i>world</i>` after minification will be rendered as `helloworld`.
|
||||
To prevent that use either the default `conservative` option, or the `aggressive` option.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div>
|
||||
hello world!
|
||||
<a href="#">answer</a>
|
||||
<style>div { color: red; } </style>
|
||||
<main></main>
|
||||
</div>
|
||||
```
|
||||
|
||||
Minified (with `all`):
|
||||
```html
|
||||
<div>hello world!<a href="#">answer</a><style>div { color: red; } </style><main></main></div>
|
||||
```
|
||||
|
||||
Minified (with `aggressive`):
|
||||
```html
|
||||
<div> hello world! <a href="#">answer</a> <style>div { color: red; } </style><main></main></div>
|
||||
```
|
||||
|
||||
Minified (with `conservative`):
|
||||
```html
|
||||
<div> hello world! <a href="#">answer</a> <style>div { color: red; } </style> <main></main> </div>
|
||||
```
|
||||
|
||||
|
||||
### deduplicateAttributeValues
|
||||
Remove duplicate values from list-like attributes (`class`, `rel`, `ping`).
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div class="sidebar left sidebar"></div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div class="sidebar left"></div>
|
||||
```
|
||||
|
||||
|
||||
### removeComments
|
||||
#### Options
|
||||
- `safe` – removes all HTML comments except the conditional comments and [`<!--noindex--><!--/noindex-->`](https://yandex.com/support/webmaster/controlling-robot/html.xml) (default)
|
||||
- `all` — removes all HTML comments
|
||||
- A `RegExp` — only HTML comments matching the given regexp will be removed.
|
||||
- A `Function` that returns boolean — removes HTML comments that can make the given callback function returns truthy value.
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```js
|
||||
{
|
||||
removeComments: 'all'
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div><!-- test --></div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<div></div>
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```js
|
||||
{
|
||||
removeComments: /<!--(\/)?noindex-->/
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div><!--noindex-->this text will not be indexed<!--/noindex-->Lorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<div>this text will not be indexedLorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```js
|
||||
{
|
||||
removeComments: (comments) => {
|
||||
if (comments.includes('noindex')) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div><!--noindex-->this text will not be indexed<!--/noindex-->Lorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<div>this text will not be indexedLorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
||||
```
|
||||
|
||||
|
||||
### removeEmptyAttributes
|
||||
Removes empty [safe-to-remove](https://github.com/posthtml/htmlnano/blob/master/lib/modules/removeEmptyAttributes.mjs) attributes.
|
||||
|
||||
#### Side effects
|
||||
This module could break your styles or JS if you use selectors with attributes:
|
||||
```CSS
|
||||
img[style=""] {
|
||||
margin: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<img src="foo.jpg" alt="" style="">
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<img src="foo.jpg" alt="">
|
||||
```
|
||||
|
||||
### removeAttributeQuotes
|
||||
Remove quotes around attributes when possible, see [HTML Standard - 12.1.2.3 Attributes - Unquoted attribute value syntax](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2).
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div class="foo" title="hello world"></div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div class=foo title="hello world"></div>
|
||||
```
|
||||
|
||||
#### Notice
|
||||
The feature is implemented by [posthtml-render's `quoteAllAttributes`](https://github.com/posthtml/posthtml-render#options), which is one of the PostHTML's option. So `removeAttributeQuotes` could be overriden by other PostHTML's plugins and PostHTML's configuration.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
posthtml([
|
||||
htmlnano({
|
||||
removeAttributeQuotes: true
|
||||
})
|
||||
]).process(html, {
|
||||
quoteAllAttributes: true
|
||||
})
|
||||
```
|
||||
|
||||
`removeAttributeQuotes` will not work because PostHTML's `quoteAllAttributes` takes the priority.
|
||||
|
||||
### removeUnusedCss
|
||||
|
||||
Removes unused CSS inside `<style>` tags with either [uncss](https://github.com/uncss/uncss)
|
||||
or [PurgeCSS](https://github.com/FullHuman/purgecss).
|
||||
|
||||
#### With uncss
|
||||
|
||||
You have to install `uncss` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev uncss
|
||||
# if you prefer yarn
|
||||
# yarn add --dev uncss
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev uncss
|
||||
```
|
||||
|
||||
You can also use a mainted fork [@novaatwarren/uncss](https://www.npmjs.com/package/@novaatwarren/uncss) instead.
|
||||
|
||||
|
||||
##### Options
|
||||
See [the documentation of uncss](https://github.com/uncss/uncss) for all supported options.
|
||||
|
||||
uncss options can be passed directly to the `removeUnusedCss` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
removeUnusedCss: {
|
||||
ignore: ['.do-not-remove']
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The following uncss options are ignored if passed to the module:
|
||||
|
||||
- `stylesheets`
|
||||
- `ignoreSheets`
|
||||
- `raw`
|
||||
|
||||
#### With PurgeCSS
|
||||
|
||||
Use PurgeCSS instead of uncss by adding `tool: 'purgeCSS'` to the options.
|
||||
|
||||
You have to install `purgecss` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev purgecss
|
||||
# if you prefer yarn
|
||||
# yarn add --dev purgecss
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev purgecss
|
||||
```
|
||||
|
||||
##### Options
|
||||
|
||||
See [the documentation of PurgeCSS](https://www.purgecss.com) for all supported options.
|
||||
|
||||
PurgeCSS options can be passed directly to the `removeUnusedCss` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
removeUnusedCss: {
|
||||
tool: 'purgeCSS',
|
||||
safelist: ['.do-not-remove']
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The following PurgeCSS options are ignored if passed to the module:
|
||||
|
||||
- `content`
|
||||
- `css`
|
||||
- `extractors`
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div class="b">
|
||||
<style>
|
||||
.a {
|
||||
margin: 10px 10px 10px 10px;
|
||||
}
|
||||
.b {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
Optimized:
|
||||
```html
|
||||
<div class="b">
|
||||
<style>
|
||||
.b {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
### minifyCss
|
||||
Minifies CSS with [cssnano](http://cssnano.co/) inside `<style>` tags and `style` attributes.
|
||||
|
||||
You have to install `cssnano` and `postcss` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev cssnano postcss
|
||||
# if you prefer yarn
|
||||
# yarn add --dev cssnano postcss
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev cssnano postcss
|
||||
```
|
||||
|
||||
#### Options
|
||||
See [the documentation of cssnano](http://cssnano.co/docs/optimisations/) for all supported optimizations.
|
||||
By default CSS is minified with preset `default`, which shouldn't have any side-effects.
|
||||
|
||||
To use another preset or disabled some optimizations pass options to `minifyCss` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyCss: {
|
||||
preset: ['default', {
|
||||
discardComments: {
|
||||
removeAll: true,
|
||||
},
|
||||
}]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div>
|
||||
<style>
|
||||
h1 {
|
||||
margin: 10px 10px 10px 10px;
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div>
|
||||
<style>h1{margin:10px;color:red}</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
### minifyJs
|
||||
Minifies JS using [Terser](https://github.com/fabiosantoscode/terser) inside `<script>` tags.
|
||||
|
||||
You have to install `terser` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev terser
|
||||
# if you prefer yarn
|
||||
# yarn add --dev terser
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev terser
|
||||
```
|
||||
|
||||
#### Options
|
||||
See [the documentation of Terser](https://github.com/fabiosantoscode/terser#api-reference) for all supported options.
|
||||
Terser options can be passed directly to the `minifyJs` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyJs: {
|
||||
output: { quote_style: 1 },
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<div>
|
||||
<script>
|
||||
/* comment */
|
||||
const foo = function () {
|
||||
|
||||
};
|
||||
</script>
|
||||
</div>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<div>
|
||||
<script>const foo=function(){};</script>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
### minifyJson
|
||||
Minifies JSON inside `<script type="application/json"></script>`.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<script type="application/json">
|
||||
{
|
||||
"user": "me"
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<script type="application/json">{"user":"me"}</script>
|
||||
```
|
||||
|
||||
|
||||
### minifySvg
|
||||
Minifies SVG inside `<svg>` tags using [SVGO](https://github.com/svg/svgo/).
|
||||
|
||||
#### Options
|
||||
See [the documentation of SVGO](https://github.com/svg/svgo/blob/master/README.md) for all supported options.
|
||||
SVGO options can be passed directly to the `minifySvg` module:
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifySvg: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
builtinPluginName: {
|
||||
optionName: 'optionValue'
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100%" height="100%" fill="red" />
|
||||
|
||||
<circle cx="150" cy="100" r="80" fill="green" />
|
||||
|
||||
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
|
||||
</svg>`
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<svg baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="red"/><circle cx="150" cy="100" r="80" fill="green"/><text x="150" y="125" font-size="60" text-anchor="middle" fill="#fff">SVG</text></svg>
|
||||
```
|
||||
|
||||
### minifyConditionalComments
|
||||
|
||||
Minify content inside conditional comments.
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<!--[if lte IE 7]>
|
||||
<style type="text/css">
|
||||
.title {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<!--[if lte IE 7]><style>.title{color:red}</style><![endif]-->
|
||||
```
|
||||
|
||||
### removeRedundantAttributes
|
||||
Removes redundant attributes from tags if they contain default values:
|
||||
- `method="get"` from `<form>`
|
||||
- `type="text"` from `<input>`
|
||||
- `type="submit"` from `<button>`
|
||||
- `language="javascript"` and `type="text/javascript"` from `<script>`
|
||||
- `charset` from `<script>` if it's an external script
|
||||
- `media="all"` from `<style>` and `<link>`
|
||||
- `type="text/css"` from `<link rel="stylesheet">`
|
||||
|
||||
#### Options
|
||||
This module is disabled by default, change option to true to enable this module.
|
||||
|
||||
#### Side effects
|
||||
This module could break your styles or JS if you use selectors with attributes:
|
||||
```CSS
|
||||
form[method="get"] {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<form method="get">
|
||||
<input type="text">
|
||||
</form>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<form>
|
||||
<input>
|
||||
</form>
|
||||
```
|
||||
|
||||
|
||||
### collapseBooleanAttributes
|
||||
Collapses boolean attributes (like `disabled`) to the minimized form.
|
||||
|
||||
#### Options
|
||||
If your document uses [AMP](https://www.ampproject.org/), set the `amphtml` flag
|
||||
to collapse additonal, AMP-specific boolean attributes:
|
||||
```Json
|
||||
"collapseBooleanAttributes": {
|
||||
"amphtml": true
|
||||
}
|
||||
```
|
||||
|
||||
#### Side effects
|
||||
This module could break your styles or JS if you use selectors with attributes:
|
||||
```CSS
|
||||
button[disabled="disabled"] {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<button disabled="disabled">click</button>
|
||||
<script defer=""></script>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<button disabled>click</button>
|
||||
<script defer></script>
|
||||
```
|
||||
|
||||
|
||||
### mergeStyles
|
||||
Merges multiple `<style>` with the same `media` and `type` into one tag.
|
||||
`<style scoped>...</style>` are skipped.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<style>h1 { color: red }</style>
|
||||
<style media="print">div { color: blue }</style>
|
||||
|
||||
<style type="text/css" media="print">a {}</style>
|
||||
<style>div { font-size: 20px }</style>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<style>h1 { color: red } div { font-size: 20px }</style>
|
||||
<style media="print">div { color: blue } a {}</style>
|
||||
```
|
||||
|
||||
|
||||
### mergeScripts
|
||||
Merge multiple `<script>` with the same attributes (`id, class, type, async, defer`) into one (last) tag.
|
||||
|
||||
#### Side effects
|
||||
It could break your code if the tags with different attributes share the same variable scope.
|
||||
See the example below.
|
||||
|
||||
#### Example
|
||||
Source:
|
||||
```html
|
||||
<script>const foo = 'A:1';</script>
|
||||
<script class="test">foo = 'B:1';</script>
|
||||
<script type="text/javascript">foo = 'A:2';</script>
|
||||
<script defer>foo = 'C:1';</script>
|
||||
<script>foo = 'A:3';</script>
|
||||
<script defer="defer">foo = 'C:2';</script>
|
||||
<script class="test" type="text/javascript">foo = 'B:2';</script>
|
||||
```
|
||||
|
||||
Minified:
|
||||
```html
|
||||
<script>const foo = 'A:1'; foo = 'A:2'; foo = 'A:3';</script>
|
||||
<script defer="defer">foo = 'C:1'; foo = 'C:2';</script>
|
||||
<script class="test" type="text/javascript">foo = 'B:1'; foo = 'B:2';</script>
|
||||
```
|
||||
|
||||
|
||||
### custom
|
||||
It's also possible to pass custom modules in the minifier.
|
||||
As a function:
|
||||
```js
|
||||
const options = {
|
||||
custom: function (tree, options) {
|
||||
// Some minification
|
||||
return tree;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Or as a list of functions:
|
||||
```js
|
||||
const options = {
|
||||
custom: [
|
||||
function (tree, options) {
|
||||
// Some minification
|
||||
return tree;
|
||||
},
|
||||
|
||||
function (tree, options) {
|
||||
// Some other minification
|
||||
return tree;
|
||||
}
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
`options` is an object with all options that were passed to the plugin.
|
||||
|
||||
### sortAttributesWithLists
|
||||
Sort values in list-like attributes (`class`, `rel`, `ping`).
|
||||
|
||||
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
||||
|
||||
#### Options
|
||||
|
||||
- `alphabetical`: Default option. Sort attribute values in alphabetical order.
|
||||
- `frequency`: Sort attribute values by frequency.
|
||||
|
||||
#### Example
|
||||
|
||||
**alphabetical**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<div class="foo baz bar">click</div>
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<div class="bar baz foo">click</div>
|
||||
```
|
||||
|
||||
**frequency**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<div class="foo baz bar"></div><div class="bar foo"></div>
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<div class="foo bar baz"></div><div class="foo bar"></div>
|
||||
```
|
||||
|
||||
### sortAttributes
|
||||
Sort attributes inside elements.
|
||||
|
||||
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
||||
|
||||
#### Options
|
||||
|
||||
- `alphabetical`: Default option. Sort attributes in alphabetical order.
|
||||
- `frequency`: Sort attributes by frequency.
|
||||
|
||||
#### Example
|
||||
|
||||
**alphabetical**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<input type="text" class="form-control" name="testInput" autofocus="" autocomplete="off" id="testId">
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<input autocomplete="off" autofocus="" class="form-control" id="testId" name="testInput" type="text">
|
||||
```
|
||||
|
||||
**frequency**
|
||||
|
||||
Source:
|
||||
```html
|
||||
<input type="text" class="form-control" name="testInput" id="testId">
|
||||
<a id="testId" href="#" class="testClass"></a>
|
||||
<img width="20" src="../images/image.png" height="40" alt="image" class="cls" id="id2">
|
||||
```
|
||||
|
||||
Processed:
|
||||
```html
|
||||
<input class="form-control" id="testId" type="text" name="testInput">
|
||||
<a class="testClass" id="testId" href="#"></a>
|
||||
<img class="cls" id="id2" width="20" src="../images/image.png" height="40" alt="image">
|
||||
```
|
||||
|
||||
### minifyUrls
|
||||
Convert absolute URL to relative URL using [relateurl](https://www.npmjs.com/package/relateurl).
|
||||
|
||||
You have to install `relateurl`, `terser` and `srcset` in order to use this feature:
|
||||
|
||||
```bash
|
||||
npm install --save-dev relateurl terser srcset
|
||||
# if you prefer yarn
|
||||
# yarn add --dev relateurl terser srcset
|
||||
# if you prefer pnpm
|
||||
# pnpm install --save-dev relateurl terser srcset
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
The base URL to resolve against. Support `String` & `URL`.
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: 'https://example.com' // Valid configuration
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: new URL('https://example.com') // Valid configuration
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: false // The module will be disabled
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: true // Invalid configuration, the module will be disabled
|
||||
});
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
**Basic Usage**
|
||||
|
||||
Configuration:
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: 'https://example.com'
|
||||
});
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<a href="https://example.com/foo/bar/baz">bar</a>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<a href="foo/bar/baz">bar</a>
|
||||
```
|
||||
|
||||
**With sub-directory**
|
||||
|
||||
Configuration:
|
||||
|
||||
```js
|
||||
htmlnano.process(html, {
|
||||
minifyUrls: 'https://example.com/foo/baz/'
|
||||
});
|
||||
```
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<a href="https://example.com/foo/bar">bar</a>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<a href="../bar">bar</a>
|
||||
```
|
||||
|
||||
### removeOptionalTags
|
||||
Remove certain tags that can be omitted, see [HTML Standard - 13.1.2.4 Optional tags](https://html.spec.whatwg.org/multipage/syntax.html#optional-tags).
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<html><head><title>Title</title></head><body><p>Hi</p></body></html>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<title>Title</title><p>Hi</p>
|
||||
```
|
||||
|
||||
#### Notice
|
||||
Due to [the limitation of PostHTML](https://github.com/posthtml/htmlnano/issues/99), htmlnano can't remove only the start tag or the end tag of an element. Currently, htmlnano only supports removing the following optional tags, as htmlnano can remove their start tag and end tag at the same time:
|
||||
|
||||
- `html`
|
||||
- `head`
|
||||
- `body`
|
||||
- `colgroup`
|
||||
- `tbody`
|
||||
|
||||
### normalizeAttributeValues
|
||||
|
||||
Normalize casing of attribute values.
|
||||
|
||||
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
||||
|
||||
#### Example
|
||||
|
||||
Source:
|
||||
|
||||
```html
|
||||
<form method="GET"></form>
|
||||
```
|
||||
|
||||
Minified:
|
||||
|
||||
```html
|
||||
<form method="get"></form>
|
||||
```
|
||||
16
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/060-contribute.md
generated
vendored
Normal file
16
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_docs/version-2.0.0/060-contribute.md
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Contribute
|
||||
|
||||
Since the minifier is modular, it's very easy to add new modules:
|
||||
|
||||
1. Create a ES6-file inside `lib/modules/` with a function that does some minification. For example you can check [`lib/modules/example.mjs`](https://github.com/posthtml/htmlnano/blob/master/lib/modules/example.mjs).
|
||||
|
||||
2. Add the module's name into one of those [presets](https://github.com/posthtml/htmlnano/tree/master/lib/presets). You can choose either `ampSafe`, `max`, or `safe`.
|
||||
|
||||
3. Create a JS-file inside `test/modules/` with some unit-tests.
|
||||
|
||||
4. Describe your module in the section "[Modules](https://github.com/posthtml/htmlnano/blob/master/README.md#modules)".
|
||||
|
||||
5. Send me a pull request.
|
||||
|
||||
Other types of contribution (bug fixes, documentation improves, etc) are also welcome!
|
||||
Would like to contribute, but don't have any ideas what to do? Check out [our issues](https://github.com/posthtml/htmlnano/labels/help%20wanted).
|
||||
8
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_sidebars/version-1.1.1-sidebars.json
generated
vendored
Normal file
8
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_sidebars/version-1.1.1-sidebars.json
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"version-1.1.1/tutorialSidebar": [
|
||||
{
|
||||
"type": "autogenerated",
|
||||
"dirName": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
8
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_sidebars/version-2.0.0-sidebars.json
generated
vendored
Normal file
8
webGl/my-threejs-test/node_modules/htmlnano/docs/versioned_sidebars/version-2.0.0-sidebars.json
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"version-2.0.0/tutorialSidebar": [
|
||||
{
|
||||
"type": "autogenerated",
|
||||
"dirName": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
4
webGl/my-threejs-test/node_modules/htmlnano/docs/versions.json
generated
vendored
Normal file
4
webGl/my-threejs-test/node_modules/htmlnano/docs/versions.json
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[
|
||||
"2.0.0",
|
||||
"1.1.1"
|
||||
]
|
||||
Reference in New Issue
Block a user