diff --git a/docs/README.md b/docs/README.md index 8a614876..49a4dd4e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -154,6 +154,15 @@ Provide the following configuration in your `.vscode/settings.json` (or global) } ``` +Alternatively, you can provide the schema store via a `$schema` property. + +```json +{ + "$schema": "https://cdn.jsdelivr.net/npm/tsup/schema.json" +} +``` + +> INFO: The `$schema` property will only work when applied within `tsup.config.json` files. ### Multiple entrypoints @@ -344,7 +353,7 @@ tsup src/index.ts --env.NODE_ENV production ### Building CLI app -When an entry file like `src/cli.ts` contains hashbang like `#!/bin/env node` tsup will automatically make the output file executable, so you don't have to run `chmod +x dist/cli.js`. +When an entry file like `src/cli.ts` contains hashbang like `#!/bin/env node` tsup will automatically make the outout file executable, so you don't have to run `chmod +x dist/cli.js`. ### Watch mode @@ -409,16 +418,6 @@ You can also minify the output, resulting into lower bundle sizes by using the ` tsup src/index.ts --minify ``` -To use [Terser](https://github.com/terser/terser) instead of esbuild for minification, pass terser as argument value - -```bash -tsup src/index.ts --minify terser -``` - -> NOTE: You must have terser installed. Install it with `npm install -D terser` - -In `tsup.config.js`, you can pass `terserOptions` which will be passed to `terser.minify` as it is. - ### Custom loader Esbuild loader list: diff --git a/schema.json b/schema.json index 88d0387e..badc24b4 100644 --- a/schema.json +++ b/schema.json @@ -114,6 +114,349 @@ "keepNames": { "type": "boolean" }, + "terserOptions": { + "type":"object", + "markdownDescription": "Use [Terser](https://terser.org/) instead of esbuild for minification. > You must have terser installed. Install it with `npm install -D terser`", + "properties": { + "compress":{ + "type": ["boolean", "object"], + "properties": { + "arguments": { + "type": "boolean", + "default": false, + "markdownDescription":"Replace `arguments[index]` with function parameter name whenever possible." + }, + "arrows": { + "type": "boolean", + "default": true, + "markdownDescription": "Class and object literal methods are converted will also be converted to arrow expressions if the resultant code is shorter: `m(){return x}` becomes `m:()=>x`. To do this to regular ES5 functions which don't use `this` or `arguments`, see `unsafe_arrows`." + }, + "booleans_as_integers": { + "type": "boolean", + "default": false, + "markdownDescription": "Turn booleans into `0` and `1`, also makes comparisons with booleans use `==` and `!=` instead of `===` and `!==`." + }, + "booleans": { + "type": "boolean", + "default": true, + "markdownDescription": "Various optimizations for boolean context, for example `!!a ? b : c → a ? b : c`" + }, + "collapse_vars": { + "type": "boolean", + "default": true, + "markdownDescription": "Collapse single-use non-constant variables, side effects permitting" + }, + "comparisons": { + "type": "boolean", + "default": true, + "markdownDescription":"Apply certain optimizations to binary nodes, e.g. `!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc." + }, + "computed_props": { + "type": "boolean", + "default": true, + "markdownDescription": "Transforms constant computed properties into regular ones: `{[\"computed\"]: 1}` is converted to `{computed: 1}`." + }, + "conditionals": { + "type": "boolean", + "default": true, + "markdownDescription":"Apply optimizations for `if`-s and conditional expressions." + }, + "dead_code": { + "type": "boolean", + "default": true, + "markdownDescription": "Remove unreachable code." + }, + "defaults": { + "type": "boolean", + "default": true, + "markdownDescription": "Remove redundant or non-standard directives." + }, + "directives": { + "type": "boolean", + "default": true, + "markdownDescription":"Remove redundant or non-standard directives" + }, + "drop_console": { + "type": "boolean", + "default": true, + "markdownDescription":"Pass `true` to discard calls to console.* functions. If you wish to drop a specific function call such as `console.info` and/or retain side effects from function arguments after dropping the function call then use `pure_funcs` instead." + }, + "drop_debugger": { + "type": "boolean", + "default": true, + "markdownDescription": "Remove `debugger;` statements" + }, + "ecma": { + "type": "number", + "default": 5, + "enum": [5, 2015, 2016, 2017, 2018, 2019, 2020], + "markdownDescription": "Pass `2015` or greater to enable compress options that will transform ES5 code into smaller ES6+ equivalent forms." + }, + "evaluate": { + "type": "boolean", + "markdownDescription": "Attempt to evaluate constant expressions" + }, + "expression": { + "type": "boolean", + "default": false, + "markdownDescription": "Pass `true` to preserve completion values from terminal statements without `return`, e.g. in bookmarklets." + }, + "global_defs": { + "type": "object", + "markdownDescription": "See [conditional compilation](https://terser.org/docs/api-reference#conditional-compilation)" + }, + "hoist_funs": { + "type": "boolean", + "default": false, + "markdownDescription": "Hoist function declarations" + }, + "hoist_props": { + "type": "boolean", + "default": true, + "markdownDescription": "Hoist properties from constant object and array literals into regular variables subject to a set of constraints. For example: `var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`.\n\n> **Note**: `hoist_props` works best with `mangle` enabled, the `compress` option `passes` set to `2` or higher, and the `compress` option `toplevel` enabled." + }, + "hoist_vars": { + "type": "boolean", + "default": false, + "markdownDescription": "Hoist `var` declarations (this is `false` by default because it seems to increase the size of the output in general)" + }, + "ie8": { + "type": "boolean", + "default": false, + "markdownDescription": "Set to `true` to support IE8." + }, + "if_return": { + "type": "boolean", + "markdownDescription": "Hoist `var` declarations (this is `false` by default because it seems to increase the size of the output in general)" + }, + "inline": { + "type": ["boolean", "number"], + "enum": [false, 0, 1, 2, 3, true], + "markdownDescription": "Hoist `var` declarations (this is `false` by default because it seems to increase the size of the output in general)" + }, + "join_vars": { + "type": "boolean", + "markdownDescription": "Hoist `var` declarations (this is `false` by default because it seems to increase the size of the output in general)" + }, + "keep_classnames": { + "default": false, + "markdownDescription": "Pass `true` to prevent the compressor from discarding class names. Pass a regular expression to only keep class names matching that regex.", + "type": ["boolean", "string"] + }, + "keep_fargs": { + "default": true, + "type": "boolean", + "markdownDescription": "Prevents the compressor from discarding unused function arguments. You need this for code which relies on `Function.length`." + }, + "keep_fnames": { + "type": ["boolean", "string"], + "default": false, + "markdownDescription": "Pass `true` to prevent the compressor from discarding function names. Pass a regular expression to only keep function names matching that regex. Useful for code relying on Function.prototype.name" + }, + "keep_infinity": { + "type": "boolean", + "default": false, + "markdownDescription": "Pass `true` to prevent `Infinity` from being compressed into 1/0, which may cause performance issues on Chrome." + }, + "loops": { + "type": "boolean", + "default": false, + "markdownDescription": "Optimizations for `do`, `while` and `for` loops when we can statically determine the condition." + }, + "module": { + "type": "boolean", + "default": false, + "markdownDescription": "Pass `true` when compressing an ES6 module. Strict mode is implied and the `toplevel` option as well." + }, + "negate_iife": { + "type": "boolean", + "default": true, + "markdownDescription": "negate \"Immediately-Called Function Expressions\" where the return value is discarded, to avoid the parens that the code generator would insert." + }, + "passes": { + "type": "number", + "default": 1, + "markdownDescription": "The maximum number of times to run compress. In some cases more than one pass leads to further compressed code. Keep in mind more passes will take more time." + }, + "properties": { + "type": "boolean", + "default": true, + "markdownDescription": "Rewrite property access using the dot notation, for example `foo[\"bar\"]` → `foo.bar`" + }, + "pure_funcs": { + "type": "array", + "default": null, + "markdownDescription": "You can pass an array of names and Terser will assume that those functions do not produce side effects.\n\n**DANGER**:\n\nWill not check if the name is redefined in scope. An example case here, for instance `var q = Math.floor(a/b)`. If variable `q` is not used elsewhere, Terser will drop it, but will still keep the `Math.floor(a/b)`, not knowing what it does. You can pass `pure_funcs: [ 'Math.floor' ]` to let it know that this function won't produce any side effect, in which case the whole statement would get discarded. The current implementation adds some overhead (compression will be slower).", + "items": { + "type": "string" + } + }, + "pure_getters": { + "type": ["boolean", "string"], + "default": false, + "markdownDescription": "If you pass `true` for this, Terser will assume that object property access (e.g. `foo.bar` or `foo[\"bar\"]`) doesn't have any side effects. Specify `\"strict\"` to treat `foo.bar` as side-effect-free only when `foo` is certain to not throw, i.e. not `null` or `undefined`." + }, + "reduce_funcs": { + "type": "boolean", + "default": false, + "markdownDescription": "(legacy option, safely ignored for backwards compatibility)." + }, + "reduce_vars": { + "type": "boolean", + "default": true, + "markdownDescription": "Improve optimization on variables assigned with and used as constant values." + }, + "sequences": { + "type": ["boolean", "number"], + "default": true, + "markdownDescription": "Join consecutive simple statements using the comma operator. May be set to a positive integer to specify the maximum number of consecutive comma sequences that will be generated. If this option is set to `true` then the default `sequences` limit is `200`. Set option to `false` or `0` to disable. The smallest `sequences` length is `2`. A `sequences` value of `1` is grandfathered to be equivalent to `true` and as such means `200`. On rare occasions the default sequences limit leads to very slow compress times in which case a value of `20` or less is recommended." + }, + "side_effects": { + "type": "boolean", + "default": true, + "markdownDescription": "Remove expressions which have no side effects and whose results aren't used." + }, + "switches": { + "type": "boolean", + "default": true, + "markdownDescription": "de-duplicate and remove unreachable `switch` branches" + }, + "toplevel": { + "type": "boolean", + "default": false, + "markdownDescription": "drop unreferenced functions (`\"funcs\"`) and/or variables (`\"vars\"`) in the top level scope (`false` by default, `true` to drop both unreferenced functions and variables)" + }, + "top_retain": { + "type":["array", "string"], + "default": null, + "markdownDescription": "Prevent specific toplevel functions and variables from `unused` removal (can be array, comma-separated, RegExp or function. Implies `toplevel`)" + }, + "typeofs": { + "type": "boolean", + "default": true, + "markdownDescription": "Transforms `typeof foo == \"undefined\"` into `foo === void 0`. Note: recommend to set this value to `false` for IE10 and earlier versions due to known issues." + }, + "unsafe": { + "type": "boolean", + "default": false, + "markdownDescription": "Apply \"unsafe\" transformations" + }, + "unsafe_arrows": { + "type": "boolean", + "default": false, + "markdownDescription": "Convert ES5 style anonymous function expressions to arrow functions if the function body does not reference `this`.\n\n> **Note**: it is not always safe to perform this conversion if code relies on the the function having a `prototype`, which arrow functions lack. This transform requires that the `ecma` compress option is set to `2015` or greater." + }, + "unsafe_comps": { + "type": "boolean", + "default": false, + "markdownDescription": "Reverse `<` and `<=` to `>` and `>=` to allow improved compression. This might be unsafe when an at least one of two operands is an object with computed values due the use of methods like `get`, or `valueOf`. This could cause change in execution order after operands in the comparison are switching. Compression only works if both `comparisons` and `unsafe_comps` are both set to true." + }, + "unsafe_Function": { + "type": "boolean", + "default": false, + "markdownDescription": "Compress and mangle `Function(args, code)` when both `args` and `code` are string literals." + }, + "unsafe_math": { + "type": "boolean", + "default": true, + "markdownDescription": "Optimize numerical expressions like `2 * x * 3` into `6 * x`, which may give imprecise floating point results." + }, + "unsafe_symbols": { + "type": "boolean", + "default": true, + "markdownDescription": "Removes keys from native Symbol declarations, e.g `Symbol(\"kDog\")` becomes `Symbol()`." + }, + "unsafe_methods": { + "type": "boolean", + "default": true, + "markdownDescription": "Converts `{ m: function(){} }` to `{ m(){} }`. `ecma` must be set to `6` or greater to enable this transform. If `unsafe_methods` is a RegExp then key/value pairs with keys matching the RegExp will be converted to concise methods.\n\n> **Note**: if enabled there is a risk of getting a \"`` is not a constructor\" TypeError should any code try to `new` the former function." + }, + "unsafe_proto": { + "type": "boolean", + "default": true, + "markdownDescription": "optimize expressions like `Array.prototype.slice.call(a)` into `[].slice.call(a)`" + }, + "unsafe_regexp": { + "type": "boolean", + "default": true, + "markdownDescription": "Enable substitutions of variables with `RegExp` values the same way as if they are constants." + }, + "unsafe_undefined": { + "type": "boolean", + "default": true, + "markdownDescription": "substitute `void 0` if there is a variable named `undefined` in scope (variable name will be mangled, typically reduced to a single character)" + }, + "unused": { + "type": "boolean", + "default": true, + "markdownDescription": "drop unreferenced functions and variables (simple direct variable assignments do not count as references unless set to `\"keep_assign\"`)" + } + } + }, + "ecma": { + "type": "number", + "default": 5, + "enum": [5, 2015, 2016, 2017, 2018, 2019, 2020], + "markdownDescription": "Pass `2015` or greater to enable compress options that will transform ES5 code into smaller ES6+ equivalent forms." + }, + "enclose":{ + "type": ["boolean", "string"] + }, + "ie8":{ + "type": "boolean" + }, + "keep_classnames":{ + "type": ["boolean", "string"] + }, + "keep_fnames":{ + "type": "boolean" + }, + "mangle":{ + "type": ["boolean", "object"] + }, + "module":{ + "type": "boolean" + }, + "nameCache":{ + "type": "object" + }, + "format":{ + "type": "object" + }, + "parse":{ + "type": "object" + }, + "safari10":{ + "type": "boolean" + }, + "sourceMap":{ + "type": ["boolean", "object"], + "properties": { + "content":{ + "type": "string" + }, + "includeSources":{ + "type": "boolean" + } , + "filename":{ + "type": "string" + }, + "root":{ + "type": "string" + }, + "asObject":{ + "type": "boolean" + }, + "url": { + "type": "string" + } + } + }, + "toplevel":{ + "type": "boolean" + } + } + }, "watch": { "oneOf": [ {