📦 添加虚拟环境和启动脚本

新增:
- backend/venv/ - Python 虚拟环境
- backend/start.sh - 启动脚本(使用虚拟环境)
- backend/requirements.txt - 依赖列表
- .gitignore - 忽略虚拟环境和缓存文件

说明:
- 每个项目使用独立虚拟环境
- 避免依赖冲突
- 启动脚本自动创建和激活虚拟环境
This commit is contained in:
2026-04-04 18:28:31 +08:00
parent 9ab279e1fe
commit 96f6318101
32058 changed files with 3949495 additions and 22 deletions

20
frontend/node_modules/terser-webpack-plugin/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

959
frontend/node_modules/terser-webpack-plugin/README.md generated vendored Normal file
View File

@@ -0,0 +1,959 @@
<div align="center">
<a href="https://github.com/webpack/webpack">
<img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
</div>
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![tests][tests]][tests-url]
[![cover][cover]][cover-url]
[![discussion][discussion]][discussion-url]
[![size][size]][size-url]
# terser-webpack-plugin
This plugin uses [terser](https://github.com/terser/terser) to minify/minimize your JavaScript.
## Getting Started
Webpack v5 comes with the latest `terser-webpack-plugin` out of the box.
If you are using Webpack v5 or above and wish to customize the options, you will still need to install `terser-webpack-plugin`.
Using Webpack v4, you have to install `terser-webpack-plugin` v4.
To begin, you'll need to install `terser-webpack-plugin`:
```console
npm install terser-webpack-plugin --save-dev
```
or
```console
yarn add -D terser-webpack-plugin
```
or
```console
pnpm add -D terser-webpack-plugin
```
Then add the plugin to your `webpack` configuration. For example:
**webpack.config.js**
```js
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
};
```
Finally, run `webpack` using the method you normally use (e.g., via CLI or an npm script).
## Note about source maps
**Works only with `source-map`, `inline-source-map`, `hidden-source-map` and `nosources-source-map` values for the [`devtool`](https://webpack.js.org/configuration/devtool/) option.**
Why?
- `eval` wraps modules in `eval("string")` and the minimizer does not handle strings.
- `cheap` has no column information and the minimizer generates only a single line, which leaves only a single mapping.
Using supported `devtool` values enable source map generation.
## Options
- **[`test`](#test)**
- **[`include`](#include)**
- **[`exclude`](#exclude)**
- **[`parallel`](#parallel)**
- **[`minify`](#minify)**
- **[`terserOptions`](#terseroptions)**
- **[`extractComments`](#extractcomments)**
### `test`
Type:
```ts
type test = string | RegExp | (string | RegExp)[];
```
Default: `/\.m?js(\?.*)?$/i`
Test to match files against.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
}),
],
},
};
```
### `include`
Type:
```ts
type include = string | RegExp | (string | RegExp)[];
```
Default: `undefined`
Files to include.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\/includes/,
}),
],
},
};
```
### `exclude`
Type:
```ts
type exclude = string | RegExp | (string | RegExp)[];
```
Default: `undefined`
Files to exclude.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
exclude: /\/excludes/,
}),
],
},
};
```
### `parallel`
Type:
```ts
type parallel = boolean | number;
```
Default: `true`
Use multi-process parallel running to improve the build speed.
Default number of concurrent runs: `os.cpus().length - 1` or `os.availableParallelism() - 1` (if this function is supported).
> **Note**
>
> Parallelization can speedup your build significantly and is therefore **highly recommended**.
> **Warning**
>
> If you use **Circle CI** or any other environment that doesn't provide the real available count of CPUs then you need to explicitly set up the number of CPUs to avoid `Error: Call retries were exceeded` (see [#143](https://github.com/webpack/terser-webpack-plugin/issues/143), [#202](https://github.com/webpack/terser-webpack-plugin/issues/202)).
#### `boolean`
Enable/disable multi-process parallel running.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
};
```
#### `number`
Enable multi-process parallel running and set number of concurrent runs.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
};
```
### `minify`
Type:
```ts
type minify = (
input: Record<string, string>,
sourceMap: import("@jridgewell/trace-mapping").SourceMapInput | undefined,
minifyOptions: {
module?: boolean | undefined;
ecma?: import("terser").ECMA | undefined;
},
extractComments:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| {
condition?:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| undefined;
filename?: string | ((fileData: any) => string) | undefined;
banner?:
| string
| boolean
| ((commentsFile: string) => string)
| undefined;
}
| undefined,
) => Promise<{
code: string;
map?: import("@jridgewell/trace-mapping").SourceMapInput | undefined;
errors?: (string | Error)[] | undefined;
warnings?: (string | Error)[] | undefined;
extractedComments?: string[] | undefined;
}>;
```
Default: `TerserPlugin.terserMinify`
Allows you to override the default minify function.
By default plugin uses [terser](https://github.com/terser/terser) package.
Useful for using and testing unpublished versions or forks.
> **Warning**
>
> **Always use `require` inside `minify` function when `parallel` option enabled**.
**webpack.config.js**
```js
// Can be async
const minify = (input, sourceMap, minimizerOptions, extractsComments) => {
// The `minimizerOptions` option contains option from the `terserOptions` option
// You can use `minimizerOptions.myCustomOption`
// Custom logic for extract comments
const { map, code } = require("uglify-module") // Or require('./path/to/uglify-module')
.minify(input, {
/* Your options for minification */
});
return { map, code, warnings: [], errors: [], extractedComments: [] };
};
// Used to regenerate `fullhash`/`chunkhash` between different implementation
// Example: you fix a bug in custom minimizer/custom function, but unfortunately webpack doesn't know about it, so you will get the same fullhash/chunkhash
// to avoid this you can provide version of your custom minimizer
// You don't need if you use only `contenthash`
minify.getMinimizerVersion = () => {
let packageJson;
try {
packageJson = require("uglify-module/package.json");
} catch (error) {
// Ignore
}
return packageJson && packageJson.version;
};
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
myCustomOption: true,
},
minify,
}),
],
},
};
```
### `terserOptions`
Type:
```ts
interface terserOptions {
compress?: boolean | CompressOptions;
ecma?: ECMA;
enclose?: boolean | string;
ie8?: boolean;
keep_classnames?: boolean | RegExp;
keep_fnames?: boolean | RegExp;
mangle?: boolean | MangleOptions;
module?: boolean;
nameCache?: object;
format?: FormatOptions;
/** @deprecated */
output?: FormatOptions;
parse?: ParseOptions;
safari10?: boolean;
sourceMap?: boolean | SourceMapOptions;
toplevel?: boolean;
}
```
Default: [default](https://github.com/terser/terser#minify-options)
Terser [options](https://github.com/terser/terser#minify-options).
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: undefined,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
// Deprecated
output: null,
format: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
}),
],
},
};
```
### `extractComments`
Type:
```ts
type extractComments =
| boolean
| string
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| {
condition?:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| undefined;
filename?: string | ((fileData: any) => string) | undefined;
banner?:
| string
| boolean
| ((commentsFile: string) => string)
| undefined;
};
```
Default: `true`
Whether comments shall be extracted to a separate file, (see [details](https://github.com/webpack/webpack/commit/71933e979e51c533b432658d5e37917f9e71595a)).
By default, extract only comments using `/^\**!|@preserve|@license|@cc_on/i` RegExp condition and remove remaining comments.
If the original file is named `foo.js`, then the comments will be stored to `foo.js.LICENSE.txt`.
The `terserOptions.format.comments` option specifies whether the comment will be preserved - i.e., it is possible to preserve some comments (e.g. annotations) while extracting others, or even preserve comments that have already been extracted.
#### `boolean`
Enable/disable extracting comments.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
};
```
#### `string`
Extract `all` or `some` (use the `/^\**!|@preserve|@license|@cc_on/i` RegExp) comments.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: "all",
}),
],
},
};
```
#### `RegExp`
All comments that match the given expression will be extracted to a separate file.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: /@extract/i,
}),
],
},
};
```
#### `function`
All comments that match the given expression will be extracted to a separate file.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: (astNode, comment) => {
if (/@extract/i.test(comment.value)) {
return true;
}
return false;
},
}),
],
},
};
```
#### `object`
Allows you to customize condition for extracting comments, and specify the extracted file name and banner.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: (fileData) =>
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
`${fileData.filename}.LICENSE.txt${fileData.query}`,
banner: (licenseFile) =>
`License information can be found in ${licenseFile}`,
},
}),
],
},
};
```
##### `condition`
Type:
```ts
type condition =
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| undefined;
```
The condition that determines which comments should be extracted.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: "some",
filename: (fileData) =>
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
`${fileData.filename}.LICENSE.txt${fileData.query}`,
banner: (licenseFile) =>
`License information can be found in ${licenseFile}`,
},
}),
],
},
};
```
##### `filename`
Type:
```ts
type filename = string | ((fileData: any) => string) | undefined;
```
Default: `[file].LICENSE.txt[query]`
Available placeholders: `[file]`, `[query]` and `[filebase]` (`[base]` for webpack 5).
The file where the extracted comments will be stored.
Default is to append the suffix `.LICENSE.txt` to the original filename.
> **Warning**
>
> We highly recommend using the `.txt` extension. Using `.js`/`.cjs`/`.mjs` extensions may conflict with existing assets, which leads to broken code.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: "extracted-comments.js",
banner: (licenseFile) =>
`License information can be found in ${licenseFile}`,
},
}),
],
},
};
```
##### `banner`
Type:
```ts
type banner = string | boolean | ((commentsFile: string) => string) | undefined;
```
Default: `/*! For license information please see ${commentsFile} */`
The banner text that points to the extracted file and will be added at the top of the original file.
It can be `false` (no banner), a `String`, or a `function<(string) -> String>` that will be called with the filename where the extracted comments have been stored.
The banner will be wrapped in a comment.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: true,
filename: (fileData) =>
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
`${fileData.filename}.LICENSE.txt${fileData.query}`,
banner: (commentsFile) =>
`My custom banner about license information ${commentsFile}`,
},
}),
],
},
};
```
## Examples
### Preserve Comments
Extract all legal comments (i.e. `/^\**!|@preserve|@license|@cc_on/i`) and preserve `/@license/i` comments.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: /@license/i,
},
},
extractComments: true,
}),
],
},
};
```
### Remove Comments
If you want to build without comments, use this config:
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
}),
],
},
};
```
### [`uglify-js`](https://github.com/mishoo/UglifyJS)
[`UglifyJS`](https://github.com/mishoo/UglifyJS) is a JavaScript parser, minifier, compressor and beautifier toolkit.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.uglifyJsMinify,
// `terserOptions` options will be passed to `uglify-js`
// Link to options - https://github.com/mishoo/UglifyJS#minify-options
terserOptions: {},
}),
],
},
};
```
### [`swc`](https://github.com/swc-project/swc)
[`swc`](https://github.com/swc-project/swc) is a super-fast compiler written in `Rust`, producing widely supported JavaScript from modern standards and TypeScript.
> **Warning**
>
> The `extractComments` option is not supported, and all comments will be removed by default. This will be fixed in future
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.swcMinify,
// `terserOptions` options will be passed to `swc` (`@swc/core`)
// Link to options - https://swc.rs/docs/config-js-minify
terserOptions: {},
}),
],
},
};
```
### [`esbuild`](https://github.com/evanw/esbuild)
[`esbuild`](https://github.com/evanw/esbuild) is an extremely fast JavaScript bundler and minifier.
> **Warning**
>
> The `extractComments` option is not supported, and all legal comments (i.e. copyright, licenses and etc) will be preserved.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.esbuildMinify,
// `terserOptions` options will be passed to `esbuild`
// Link to options - https://esbuild.github.io/api/#minify
// Note: the `minify` options is true by default (and override other `minify*` options), so if you want to disable the `minifyIdentifiers` option (or other `minify*` options) please use:
// terserOptions: {
// minify: false,
// minifyWhitespace: true,
// minifyIdentifiers: false,
// minifySyntax: true,
// },
terserOptions: {},
}),
],
},
};
```
### JSON
Uses `JSON.stringify()` to minify your JSON files during the build process.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
// Keeps original terser plugin to minify JS files
"...",
// Will minify JSON files (they can come from copy-webpack-plugin or when you are using asset modules)
new TerserPlugin({
test: /\.json$/,
minify: TerserPlugin.jsonMinify,
// We are supporting `space` and `replacer` options, you can set them below
terserOptions: {},
}),
],
},
};
```
### Custom Minify Function
Override the default minify function - use `uglify-js` for minification.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: (file, sourceMap) => {
// https://github.com/mishoo/UglifyJS2#minify-options
const uglifyJsOptions = {
/* your `uglify-js` package options */
};
if (sourceMap) {
uglifyJsOptions.sourceMap = {
content: sourceMap,
};
}
return require("uglify-js").minify(file, uglifyJsOptions);
},
}),
],
},
};
```
### Typescript
With default Terser minify function:
```ts
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: true,
},
}),
],
},
};
```
With built-in minify functions:
```ts
import { type JsMinifyOptions as SwcOptions } from "@swc/core";
import { type TransformOptions as EsbuildOptions } from "esbuild";
import { type MinifyOptions as TerserOptions } from "terser";
import { type MinifyOptions as UglifyJSOptions } from "uglify-js";
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin<SwcOptions>({
minify: TerserPlugin.swcMinify,
terserOptions: {
// `swc` options
},
}),
new TerserPlugin<UglifyJSOptions>({
minify: TerserPlugin.uglifyJsMinify,
terserOptions: {
// `uglif-js` options
},
}),
new TerserPlugin<EsbuildOptions>({
minify: TerserPlugin.esbuildMinify,
terserOptions: {
// `esbuild` options
},
}),
// Alternative usage:
new TerserPlugin<TerserOptions>({
minify: TerserPlugin.terserMinify,
terserOptions: {
// `terser` options
},
}),
],
},
};
```
## Contributing
We welcome all contributions!
If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.
[CONTRIBUTING](https://github.com/webpack/terser-webpack-plugin?tab=contributing-ov-file#contributing)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/terser-webpack-plugin.svg
[npm-url]: https://npmjs.com/package/terser-webpack-plugin
[node]: https://img.shields.io/node/v/terser-webpack-plugin.svg
[node-url]: https://nodejs.org
[tests]: https://github.com/webpack/terser-webpack-plugin/workflows/terser-webpack-plugin/badge.svg
[tests-url]: https://github.com/webpack/terser-webpack-plugin/actions
[cover]: https://codecov.io/gh/webpack/terser-webpack-plugin/branch/main/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack/terser-webpack-plugin
[discussion]: https://img.shields.io/github/discussions/webpack/webpack
[discussion-url]: https://github.com/webpack/webpack/discussions
[size]: https://packagephobia.now.sh/badge?p=terser-webpack-plugin
[size-url]: https://packagephobia.now.sh/result?p=terser-webpack-plugin

View File

@@ -0,0 +1,120 @@
{
"name": "terser-webpack-plugin",
"version": "5.4.0",
"description": "Terser plugin for webpack",
"keywords": [
"uglify",
"uglify-js",
"uglify-es",
"terser",
"webpack",
"webpack-plugin",
"minification",
"compress",
"compressor",
"min",
"minification",
"minifier",
"minify",
"optimize",
"optimizer"
],
"homepage": "https://github.com/webpack/terser-webpack-plugin",
"bugs": "https://github.com/webpack/terser-webpack-plugin/issues",
"repository": "webpack/terser-webpack-plugin",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"license": "MIT",
"author": "webpack Contrib Team",
"main": "dist/index.js",
"types": "types/index.d.ts",
"files": [
"dist",
"types"
],
"scripts": {
"clean": "del-cli dist types",
"prebuild": "npm run clean",
"build:serialize-javascript": "node ./scripts/copy-serialize-javascript.js",
"build:types": "tsc --declaration --emitDeclarationOnly --outDir types && prettier \"types/**/*.ts\" --write",
"build:code": "cross-env NODE_ENV=production babel src -d dist --copy-files",
"build": "npm-run-all -p \"build:**\"",
"commitlint": "commitlint --from=main",
"security": "npm audit --production",
"lint:serialize-javascript": "node ./scripts/copy-serialize-javascript.js --check",
"lint:prettier": "prettier --list-different .",
"lint:code": "eslint --cache .",
"lint:spelling": "cspell \"**/*.*\"",
"lint:types": "tsc --pretty --noEmit",
"lint": "npm-run-all -l -p \"lint:**\"",
"fix:code": "npm run lint:code -- --fix",
"fix:prettier": "npm run lint:prettier -- --write",
"fix": "npm-run-all -l fix:code fix:prettier",
"test:only": "cross-env NODE_ENV=test jest",
"test:watch": "npm run test:only -- --watch",
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
"pretest": "npm run lint",
"test": "npm run test:coverage",
"prepare": "husky install && npm run build",
"release": "standard-version"
},
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
"schema-utils": "^4.3.0",
"terser": "^5.31.1"
},
"devDependencies": {
"@babel/cli": "^7.24.7",
"@babel/core": "^7.24.7",
"@babel/preset-env": "^7.24.7",
"@commitlint/cli": "^17.7.1",
"@commitlint/config-conventional": "^17.7.0",
"@swc/core": "^1.3.102",
"@types/node": "^24.2.1",
"@types/serialize-javascript": "^5.0.2",
"@types/uglify-js": "^3.17.5",
"copy-webpack-plugin": "^9.0.1",
"cross-env": "^7.0.3",
"cspell": "^6.31.2",
"del": "^6.0.0",
"del-cli": "^3.0.1",
"esbuild": "^0.27.3",
"eslint": "^9.29.0",
"eslint-config-webpack": "^4.5.1",
"file-loader": "^6.2.0",
"husky": "^7.0.2",
"jest": "^27.5.1",
"lint-staged": "^13.2.3",
"memfs": "^3.4.13",
"npm-run-all": "^4.1.5",
"prettier": "^3.6.0",
"prettier-2": "npm:prettier@^2",
"serialize-javascript": "^7.0.4",
"standard-version": "^9.3.1",
"typescript": "^5.9.2",
"uglify-js": "^3.19.3",
"webpack": "^5.101.0",
"webpack-cli": "^4.10.0",
"worker-loader": "^3.0.8"
},
"peerDependencies": {
"webpack": "^5.1.0"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"uglify-js": {
"optional": true
},
"esbuild": {
"optional": true
}
},
"engines": {
"node": ">= 10.13.0"
}
}

View File

@@ -0,0 +1,329 @@
export = TerserPlugin;
/**
* @template [T=import("terser").MinifyOptions]
*/
declare class TerserPlugin<T = import("terser").MinifyOptions> {
/**
* @private
* @param {unknown} input Input to check
* @returns {boolean} Whether input is a source map
*/
private static isSourceMap;
/**
* @private
* @param {unknown} warning warning
* @param {string} file file
* @returns {Error} built warning
*/
private static buildWarning;
/**
* @private
* @param {Error | ErrorObject | string} error error
* @param {string} file file
* @param {TraceMap=} sourceMap source map
* @param {Compilation["requestShortener"]=} requestShortener request shortener
* @returns {Error} built error
*/
private static buildError;
/**
* @private
* @param {Parallel} parallel value of the `parallel` option
* @returns {number} number of cores for parallelism
*/
private static getAvailableNumberOfCores;
/**
* @private
* @param {NonNullable<NonNullable<Configuration["output"]>["environment"]>} environment environment
* @returns {number} ecma version
*/
private static getEcmaVersion;
/**
* @param {BasePluginOptions & DefinedDefaultMinimizerAndOptions<T>=} options options
*/
constructor(
options?:
| (BasePluginOptions & DefinedDefaultMinimizerAndOptions<T>)
| undefined,
);
/**
* @private
* @type {InternalPluginOptions<T>}
*/
private options;
/**
* @private
* @param {Compiler} compiler compiler
* @param {Compilation} compilation compilation
* @param {Record<string, import("webpack").sources.Source>} assets assets
* @param {{ availableNumberOfCores: number }} optimizeOptions optimize options
* @returns {Promise<void>}
*/
private optimize;
/**
* @param {Compiler} compiler compiler
* @returns {void}
*/
apply(compiler: Compiler): void;
}
declare namespace TerserPlugin {
export {
terserMinify,
uglifyJsMinify,
swcMinify,
esbuildMinify,
jsonMinify,
Schema,
Compiler,
Compilation,
Configuration,
Asset,
AssetInfo,
TemplatePath,
JestWorker,
RawSourceMap,
TraceMap,
Rule,
Rules,
EXPECTED_ANY,
ExtractCommentsFunction,
ExtractCommentsCondition,
ExtractCommentsFilename,
ExtractCommentsBanner,
ExtractCommentsObject,
ExtractCommentsOptions,
ErrorObject,
MinimizedResult,
Input,
CustomOptions,
InferDefaultType,
PredefinedOptions,
MinimizerOptions,
BasicMinimizerImplementation,
MinimizeFunctionHelpers,
MinimizerImplementation,
InternalOptions,
MinimizerWorker,
Parallel,
BasePluginOptions,
DefinedDefaultMinimizerAndOptions,
InternalPluginOptions,
};
}
import { terserMinify } from "./utils";
import { uglifyJsMinify } from "./utils";
import { swcMinify } from "./utils";
import { esbuildMinify } from "./utils";
import { jsonMinify } from "./utils";
type Schema = import("schema-utils/declarations/validate").Schema;
type Compiler = import("webpack").Compiler;
type Compilation = import("webpack").Compilation;
type Configuration = import("webpack").Configuration;
type Asset = import("webpack").Asset;
type AssetInfo = import("webpack").AssetInfo;
type TemplatePath = import("webpack").TemplatePath;
type JestWorker = import("jest-worker").Worker;
type RawSourceMap = import("@jridgewell/trace-mapping").EncodedSourceMap & {
sources: string[];
sourcesContent?: string[];
file: string;
};
type TraceMap = import("@jridgewell/trace-mapping").TraceMap;
type Rule = RegExp | string;
type Rules = Rule[] | Rule;
type EXPECTED_ANY = any;
type ExtractCommentsFunction = (
astNode: EXPECTED_ANY,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean;
type ExtractCommentsCondition =
| boolean
| "all"
| "some"
| RegExp
| ExtractCommentsFunction;
type ExtractCommentsFilename = TemplatePath;
type ExtractCommentsBanner =
| boolean
| string
| ((commentsFile: string) => string);
type ExtractCommentsObject = {
/**
* condition which comments need to be expected
*/
condition?: ExtractCommentsCondition | undefined;
/**
* filename for extracted comments
*/
filename?: ExtractCommentsFilename | undefined;
/**
* banner in filename for extracted comments
*/
banner?: ExtractCommentsBanner | undefined;
};
type ExtractCommentsOptions = ExtractCommentsCondition | ExtractCommentsObject;
type ErrorObject = {
/**
* message
*/
message: string;
/**
* line number
*/
line?: number | undefined;
/**
* column number
*/
column?: number | undefined;
/**
* error stack trace
*/
stack?: string | undefined;
};
type MinimizedResult = {
/**
* code
*/
code?: string | undefined;
/**
* source map
*/
map?: RawSourceMap | undefined;
/**
* errors
*/
errors?: (Error | string)[] | undefined;
/**
* warnings
*/
warnings?: (Error | string)[] | undefined;
/**
* extracted comments
*/
extractedComments?: string[] | undefined;
};
type Input = {
[file: string]: string;
};
type CustomOptions = {
[key: string]: EXPECTED_ANY;
};
type InferDefaultType<T> = T extends infer U ? U : CustomOptions;
type PredefinedOptions<T> = {
/**
* true when code is a EC module, otherwise false
*/
module?:
| (T extends {
module?: infer P;
}
? P
: boolean | string)
| undefined;
/**
* ecma version
*/
ecma?:
| (T extends {
ecma?: infer P;
}
? P
: number | string)
| undefined;
};
type MinimizerOptions<T> = PredefinedOptions<T> & InferDefaultType<T>;
type BasicMinimizerImplementation<T> = (
input: Input,
sourceMap: RawSourceMap | undefined,
minifyOptions: MinimizerOptions<T>,
extractComments: ExtractCommentsOptions | undefined,
) => Promise<MinimizedResult> | MinimizedResult;
type MinimizeFunctionHelpers = {
/**
* function that returns version of minimizer
*/
getMinimizerVersion?: (() => string | undefined) | undefined;
/**
* true when minimizer support worker threads, otherwise false
*/
supportsWorkerThreads?: (() => boolean | undefined) | undefined;
/**
* true when minimizer support worker, otherwise false
*/
supportsWorker?: (() => boolean | undefined) | undefined;
};
type MinimizerImplementation<T> = BasicMinimizerImplementation<T> &
MinimizeFunctionHelpers;
type InternalOptions<T> = {
/**
* name
*/
name: string;
/**
* input
*/
input: string;
/**
* input source map
*/
inputSourceMap: RawSourceMap | undefined;
/**
* extract comments option
*/
extractComments: ExtractCommentsOptions | undefined;
/**
* minimizer
*/
minimizer: {
implementation: MinimizerImplementation<T>;
options: MinimizerOptions<T>;
};
};
type MinimizerWorker<T> = JestWorker & {
transform: (options: string) => Promise<MinimizedResult>;
minify: (options: InternalOptions<T>) => Promise<MinimizedResult>;
};
type Parallel = undefined | boolean | number;
type BasePluginOptions = {
/**
* test rule
*/
test?: Rules | undefined;
/**
* include rile
*/
include?: Rules | undefined;
/**
* exclude rule
*/
exclude?: Rules | undefined;
/**
* extract comments options
*/
extractComments?: ExtractCommentsOptions | undefined;
/**
* parallel option
*/
parallel?: Parallel | undefined;
};
type DefinedDefaultMinimizerAndOptions<T> =
T extends import("terser").MinifyOptions
? {
minify?: MinimizerImplementation<T> | undefined;
terserOptions?: MinimizerOptions<T> | undefined;
}
: {
minify: MinimizerImplementation<T>;
terserOptions?: MinimizerOptions<T> | undefined;
};
type InternalPluginOptions<T> = BasePluginOptions & {
minimizer: {
implementation: MinimizerImplementation<T>;
options: MinimizerOptions<T>;
};
};

View File

@@ -0,0 +1,17 @@
export type MinimizedResult = import("./index.js").MinimizedResult;
export type CustomOptions = import("./index.js").CustomOptions;
/** @typedef {import("./index.js").MinimizedResult} MinimizedResult */
/** @typedef {import("./index.js").CustomOptions} CustomOptions */
/**
* @template T
* @param {import("./index.js").InternalOptions<T>} options options
* @returns {Promise<MinimizedResult>} minified result
*/
export function minify<T>(
options: import("./index.js").InternalOptions<T>,
): Promise<MinimizedResult>;
/**
* @param {string} options options
* @returns {Promise<MinimizedResult>} minified result
*/
export function transform(options: string): Promise<MinimizedResult>;

View File

@@ -0,0 +1,2 @@
declare function _exports(obj: any, options: any): any;
export = _exports;

View File

@@ -0,0 +1,140 @@
export type Task<T> = () => Promise<T>;
export type FunctionReturning<T> = () => T;
export type ExtractCommentsOptions =
import("./index.js").ExtractCommentsOptions;
export type ExtractCommentsFunction =
import("./index.js").ExtractCommentsFunction;
export type ExtractCommentsCondition =
import("./index.js").ExtractCommentsCondition;
export type Input = import("./index.js").Input;
export type MinimizedResult = import("./index.js").MinimizedResult;
export type CustomOptions = import("./index.js").CustomOptions;
export type RawSourceMap = import("./index.js").RawSourceMap;
export type PredefinedOptions<T> = import("./index.js").PredefinedOptions<T>;
export type ExtractedComments = string[];
/**
* @param {Input} input input
* @param {RawSourceMap=} sourceMap source map
* @param {CustomOptions=} minimizerOptions options
* @returns {Promise<MinimizedResult>} minimized result
*/
export function esbuildMinify(
input: Input,
sourceMap?: RawSourceMap | undefined,
minimizerOptions?: CustomOptions | undefined,
): Promise<MinimizedResult>;
export namespace esbuildMinify {
/**
* @returns {string | undefined} the minimizer version
*/
function getMinimizerVersion(): string | undefined;
/**
* @returns {boolean | undefined} true if worker thread is supported, false otherwise
*/
function supportsWorkerThreads(): boolean | undefined;
}
/**
* @param {Input} input input
* @param {RawSourceMap=} sourceMap source map
* @param {CustomOptions=} minimizerOptions options
* @returns {Promise<MinimizedResult>} minimized result
*/
export function jsonMinify(
input: Input,
sourceMap?: RawSourceMap | undefined,
minimizerOptions?: CustomOptions | undefined,
): Promise<MinimizedResult>;
export namespace jsonMinify {
function getMinimizerVersion(): string;
function supportsWorker(): boolean;
function supportsWorkerThreads(): boolean;
}
/**
* @template T
* @typedef {() => T} FunctionReturning
*/
/**
* @template T
* @param {FunctionReturning<T>} fn memorized function
* @returns {FunctionReturning<T>} new function
*/
export function memoize<T>(fn: FunctionReturning<T>): FunctionReturning<T>;
/**
* @param {Input} input input
* @param {RawSourceMap=} sourceMap source map
* @param {CustomOptions=} minimizerOptions options
* @returns {Promise<MinimizedResult>} minimized result
*/
export function swcMinify(
input: Input,
sourceMap?: RawSourceMap | undefined,
minimizerOptions?: CustomOptions | undefined,
): Promise<MinimizedResult>;
export namespace swcMinify {
/**
* @returns {string | undefined} the minimizer version
*/
function getMinimizerVersion(): string | undefined;
/**
* @returns {boolean | undefined} true if worker thread is supported, false otherwise
*/
function supportsWorkerThreads(): boolean | undefined;
}
/**
* @param {Input} input input
* @param {RawSourceMap=} sourceMap source map
* @param {CustomOptions=} minimizerOptions options
* @param {ExtractCommentsOptions=} extractComments extract comments option
* @returns {Promise<MinimizedResult>} minimized result
*/
export function terserMinify(
input: Input,
sourceMap?: RawSourceMap | undefined,
minimizerOptions?: CustomOptions | undefined,
extractComments?: ExtractCommentsOptions | undefined,
): Promise<MinimizedResult>;
export namespace terserMinify {
/**
* @returns {string | undefined} the minimizer version
*/
function getMinimizerVersion(): string | undefined;
/**
* @returns {boolean | undefined} true if worker thread is supported, false otherwise
*/
function supportsWorkerThreads(): boolean | undefined;
}
/**
* @template T
* @typedef {() => Promise<T>} Task
*/
/**
* Run tasks with limited concurrency.
* @template T
* @param {number} limit Limit of tasks that run at once.
* @param {Task<T>[]} tasks List of tasks to run.
* @returns {Promise<T[]>} A promise that fulfills to an array of the results
*/
export function throttleAll<T>(limit: number, tasks: Task<T>[]): Promise<T[]>;
/**
* @param {Input} input input
* @param {RawSourceMap=} sourceMap source map
* @param {CustomOptions=} minimizerOptions options
* @param {ExtractCommentsOptions=} extractComments extract comments option
* @returns {Promise<MinimizedResult>} minimized result
*/
export function uglifyJsMinify(
input: Input,
sourceMap?: RawSourceMap | undefined,
minimizerOptions?: CustomOptions | undefined,
extractComments?: ExtractCommentsOptions | undefined,
): Promise<MinimizedResult>;
export namespace uglifyJsMinify {
/**
* @returns {string | undefined} the minimizer version
*/
function getMinimizerVersion(): string | undefined;
/**
* @returns {boolean | undefined} true if worker thread is supported, false otherwise
*/
function supportsWorkerThreads(): boolean | undefined;
}