diff --git a/package.json b/package.json index 1b57c99971a7..594341a32046 100644 --- a/package.json +++ b/package.json @@ -145,6 +145,7 @@ "css-loader": "6.3.0", "debug": "^4.1.1", "esbuild": "0.12.28", + "esbuild-wasm": "0.12.28", "eslint": "7.32.0", "eslint-config-prettier": "8.3.0", "eslint-plugin-header": "3.1.1", diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index ff7517b77b30..54bf345fb49d 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -86,6 +86,7 @@ ts_library( include = [ "package.json", "builders.json", + "esbuild-check.js", "src/**/schema.json", "src/**/*.js", "src/**/*.html", @@ -143,6 +144,7 @@ ts_library( "@npm//critters", "@npm//css-loader", "@npm//esbuild", + "@npm//esbuild-wasm", "@npm//find-cache-dir", "@npm//glob", "@npm//https-proxy-agent", diff --git a/packages/angular_devkit/build_angular/esbuild-check.js b/packages/angular_devkit/build_angular/esbuild-check.js new file mode 100644 index 000000000000..10295ea96ba9 --- /dev/null +++ b/packages/angular_devkit/build_angular/esbuild-check.js @@ -0,0 +1,16 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +// If the platform does not support the native variant of esbuild, this will crash. +// This script can then be spawned by the CLI to determine if native usage is supported. +require('esbuild') + .formatMessages([], { kind: 'error ' }) + .then( + () => {}, + () => {}, + ); diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 9d76e00c9ad2..4662b7407684 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -32,7 +32,7 @@ "core-js": "3.18.0", "critters": "0.0.10", "css-loader": "6.3.0", - "esbuild": "0.12.28", + "esbuild-wasm": "0.12.28", "find-cache-dir": "3.3.2", "glob": "7.1.7", "https-proxy-agent": "5.0.0", @@ -72,6 +72,9 @@ "webpack-merge": "5.8.0", "webpack-subresource-integrity": "5.0.0" }, + "optionalDependencies": { + "esbuild": "0.12.28" + }, "peerDependencies": { "@angular/compiler-cli": "^13.0.0 || ^13.0.0-next", "@angular/localize": "^13.0.0 || ^13.0.0-next", diff --git a/packages/angular_devkit/build_angular/src/webpack/plugins/css-optimizer-plugin.ts b/packages/angular_devkit/build_angular/src/webpack/plugins/css-optimizer-plugin.ts index 1ab09bee505a..a43eb74a3e4f 100644 --- a/packages/angular_devkit/build_angular/src/webpack/plugins/css-optimizer-plugin.ts +++ b/packages/angular_devkit/build_angular/src/webpack/plugins/css-optimizer-plugin.ts @@ -6,9 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ -import { Message, formatMessages, transform } from 'esbuild'; +import type { Message, TransformResult } from 'esbuild'; import type { Compilation, Compiler, sources } from 'webpack'; import { addWarning } from '../../utils/webpack-diagnostics'; +import { EsbuildExecutor } from './esbuild-executor'; + /** * The name of the plugin provided to Webpack when tapping Webpack compiler hooks. */ @@ -26,6 +28,7 @@ export interface CssOptimizerPluginOptions { */ export class CssOptimizerPlugin { private targets: string[] | undefined; + private esbuild = new EsbuildExecutor(); constructor(options?: CssOptimizerPluginOptions) { if (options?.supportedBrowsers) { @@ -76,25 +79,13 @@ export class CssOptimizerPlugin { } const { source, map: inputMap } = styleAssetSource.sourceAndMap(); - let sourceMapLine; - if (inputMap) { - // esbuild will automatically remap the sourcemap if provided - sourceMapLine = `\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${Buffer.from( - JSON.stringify(inputMap), - ).toString('base64')} */`; - } - const input = typeof source === 'string' ? source : source.toString(); - const { code, warnings, map } = await transform( - sourceMapLine ? input + sourceMapLine : input, - { - loader: 'css', - legalComments: 'inline', - minify: true, - sourcemap: !!inputMap && 'external', - sourcefile: asset.name, - target: this.targets, - }, + + const { code, warnings, map } = await this.optimize( + input, + asset.name, + inputMap, + this.targets, ); await this.addWarnings(compilation, warnings); @@ -114,9 +105,43 @@ export class CssOptimizerPlugin { }); } + /** + * Optimizes a CSS asset using esbuild. + * + * @param input The CSS asset source content to optimize. + * @param name The name of the CSS asset. Used to generate source maps. + * @param inputMap Optionally specifies the CSS asset's original source map that will + * be merged with the intermediate optimized source map. + * @param target Optionally specifies the target browsers for the output code. + * @returns A promise resolving to the optimized CSS, source map, and any warnings. + */ + private optimize( + input: string, + name: string, + inputMap: object, + target: string[] | undefined, + ): Promise { + let sourceMapLine; + if (inputMap) { + // esbuild will automatically remap the sourcemap if provided + sourceMapLine = `\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${Buffer.from( + JSON.stringify(inputMap), + ).toString('base64')} */`; + } + + return this.esbuild.transform(sourceMapLine ? input + sourceMapLine : input, { + loader: 'css', + legalComments: 'inline', + minify: true, + sourcemap: !!inputMap && 'external', + sourcefile: name, + target, + }); + } + private async addWarnings(compilation: Compilation, warnings: Message[]) { if (warnings.length > 0) { - for (const warning of await formatMessages(warnings, { kind: 'warning' })) { + for (const warning of await this.esbuild.formatMessages(warnings, { kind: 'warning' })) { addWarning(compilation, warning); } } diff --git a/packages/angular_devkit/build_angular/src/webpack/plugins/esbuild-executor.ts b/packages/angular_devkit/build_angular/src/webpack/plugins/esbuild-executor.ts new file mode 100644 index 000000000000..68ab904d48d4 --- /dev/null +++ b/packages/angular_devkit/build_angular/src/webpack/plugins/esbuild-executor.ts @@ -0,0 +1,131 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import { spawnSync } from 'child_process'; +import type { + FormatMessagesOptions, + PartialMessage, + TransformOptions, + TransformResult, +} from 'esbuild'; +import * as path from 'path'; + +/** + * Provides the ability to execute esbuild regardless of the current platform's support + * for using the native variant of esbuild. The native variant will be preferred (assuming + * the `alwaysUseWasm` constructor option is `false) due to its inherent performance advantages. + * At first use of esbuild, a supportability test will be automatically performed and the + * WASM-variant will be used if needed by the platform. + */ +export class EsbuildExecutor + implements Pick +{ + private esbuildTransform: this['transform']; + private esbuildFormatMessages: this['formatMessages']; + private initialized = false; + + /** + * Constructs an instance of the `EsbuildExecutor` class. + * + * @param alwaysUseWasm If true, the WASM-variant will be preferred and no support test will be + * performed; if false (default), the native variant will be preferred. + */ + constructor(private alwaysUseWasm = false) { + this.esbuildTransform = this.esbuildFormatMessages = () => { + throw new Error('esbuild implementation missing'); + }; + } + + /** + * Determines whether the native variant of esbuild can be used on the current platform. + * + * @returns True, if the native variant of esbuild is support; False, if the WASM variant is required. + */ + static hasNativeSupport(): boolean { + // Try to use native variant to ensure it is functional for the platform. + // Spawning a separate esbuild check process is used to determine if the native + // variant is viable. If check fails, the WASM variant is initialized instead. + // Attempting to call one of the native esbuild functions is not a viable test + // currently since esbuild spawn errors are currently not propagated through the + // call stack for the esbuild function. If this limitation is removed in the future + // then the separate process spawn check can be removed in favor of a direct function + // call check. + try { + const { status, error } = spawnSync(process.execPath, [ + path.join(__dirname, '../../../esbuild-check.js'), + ]); + + return status === 0 && error === undefined; + } catch { + return false; + } + } + + /** + * Initializes the esbuild transform and format messages functions. + * + * @returns A promise that fulfills when esbuild has been loaded and available for use. + */ + private async ensureEsbuild(): Promise { + if (this.initialized) { + return; + } + + // If the WASM variant was preferred at class construction or native is not supported, use WASM + if (this.alwaysUseWasm || !EsbuildExecutor.hasNativeSupport()) { + await this.useWasm(); + this.initialized = true; + + return; + } + + try { + // Use the faster native variant if available. + const { transform, formatMessages } = await import('esbuild'); + + this.esbuildTransform = transform; + this.esbuildFormatMessages = formatMessages; + } catch { + // If the native variant is not installed then use the WASM-based variant + await this.useWasm(); + } + + this.initialized = true; + } + + /** + * Transitions an executor instance to use the WASM-variant of esbuild. + */ + private async useWasm(): Promise { + const { transform, formatMessages } = await import('esbuild-wasm'); + this.esbuildTransform = transform; + this.esbuildFormatMessages = formatMessages; + + // The ESBUILD_BINARY_PATH environment variable cannot exist when attempting to use the + // WASM variant. If it is then the binary located at the specified path will be used instead + // of the WASM variant. + delete process.env.ESBUILD_BINARY_PATH; + + this.alwaysUseWasm = true; + } + + async transform(input: string, options?: TransformOptions): Promise { + await this.ensureEsbuild(); + + return this.esbuildTransform(input, options); + } + + async formatMessages( + messages: PartialMessage[], + options: FormatMessagesOptions, + ): Promise { + await this.ensureEsbuild(); + + return this.esbuildFormatMessages(messages, options); + } +} diff --git a/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-plugin.ts b/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-plugin.ts index 0e7c4ba4ef59..fc665ca4611c 100644 --- a/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-plugin.ts +++ b/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-plugin.ts @@ -10,6 +10,7 @@ import Piscina from 'piscina'; import { ScriptTarget } from 'typescript'; import type { Compiler, sources } from 'webpack'; import { maxWorkers } from '../../utils/environment-options'; +import { EsbuildExecutor } from './esbuild-executor'; /** * The maximum number of Workers that will be created to execute optimize tasks. @@ -160,6 +161,10 @@ export class JavaScriptOptimizerPlugin { target, removeLicenses: this.options.removeLicenses, advanced: this.options.advanced, + // Perform a single native esbuild support check. + // This removes the need for each worker to perform the check which would + // otherwise require spawning a separate process per worker. + alwaysUseWasm: !EsbuildExecutor.hasNativeSupport(), }; // Sort scripts so larger scripts start first - worker pool uses a FIFO queue diff --git a/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-worker.ts b/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-worker.ts index 7d28e3924688..fd5dc266ba7e 100644 --- a/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-worker.ts +++ b/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-worker.ts @@ -7,8 +7,9 @@ */ import remapping from '@ampproject/remapping'; -import { TransformFailure, transform } from 'esbuild'; +import type { TransformFailure, TransformResult } from 'esbuild'; import { minify } from 'terser'; +import { EsbuildExecutor } from './esbuild-executor'; /** * A request to optimize JavaScript using the supplied options. @@ -18,61 +19,76 @@ interface OptimizeRequest { * The options to use when optimizing. */ options: { + /** + * Controls advanced optimizations. + * Currently these are only terser related: + * * terser compress passes are set to 2 + * * terser pure_getters option is enabled + */ advanced: boolean; + /** + * Specifies the string tokens that should be replaced with a defined value. + */ define?: Record; + /** + * Controls whether class, function, and variable names should be left intact + * throughout the output code. + */ keepNames: boolean; + /** + * Controls whether license text is removed from the output code. + * Within the CLI, this option is linked to the license extraction functionality. + */ removeLicenses: boolean; + /** + * Controls whether source maps should be generated. + */ sourcemap: boolean; + /** + * Specifies the target ECMAScript version for the output code. + */ target: 5 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020; + /** + * Controls whether esbuild should only use the WASM-variant instead of trying to + * use the native variant. Some platforms may not support the native-variant and + * this option allows one support test to be conducted prior to all the workers starting. + */ + alwaysUseWasm: boolean; }; /** * The JavaScript asset to optimize. */ asset: { + /** + * The name of the JavaScript asset (typically the filename). + */ name: string; + /** + * The source content of the JavaScript asset. + */ code: string; + /** + * The source map of the JavaScript asset, if available. + * This map is merged with all intermediate source maps during optimization. + */ map: object; }; } +/** + * The cached esbuild executor. + * This will automatically use the native or WASM version based on platform and availability + * with the native version given priority due to its superior performance. + */ +let esbuild: EsbuildExecutor | undefined; + +/** + * Handles optimization requests sent from the main thread via the `JavaScriptOptimizerPlugin`. + */ export default async function ({ asset, options }: OptimizeRequest) { // esbuild is used as a first pass - let esbuildResult; - try { - esbuildResult = await transform(asset.code, { - minifyIdentifiers: !options.keepNames, - minifySyntax: true, - // NOTE: Disabling whitespace ensures unused pure annotations are kept - minifyWhitespace: false, - pure: ['forwardRef'], - legalComments: options.removeLicenses ? 'none' : 'inline', - sourcefile: asset.name, - sourcemap: options.sourcemap && 'external', - define: options.define, - keepNames: options.keepNames, - target: `es${options.target}`, - }); - } catch (error) { - const failure = error as TransformFailure; - - // If esbuild fails with only ES5 support errors, fallback to just terser. - // This will only happen if ES5 is the output target and a global script contains ES2015+ syntax. - // In that case, the global script is technically already invalid for the target environment but - // this is and has been considered a configuration issue. Global scripts must be compatible with - // the target environment. - if ( - failure.errors?.every((error) => - error.text.includes('to the configured target environment ("es5") is not supported yet'), - ) - ) { - esbuildResult = { - code: asset.code, - }; - } else { - throw error; - } - } + const esbuildResult = await optimizeWithEsbuild(asset.code, asset.name, options); // terser is used as a second pass const terserResult = await optimizeWithTerser( @@ -106,6 +122,74 @@ export default async function ({ asset, options }: OptimizeRequest) { return { name: asset.name, code: terserResult.code, map: fullSourcemap }; } +/** + * Optimizes a JavaScript asset using esbuild. + * + * @param content The JavaScript asset source content to optimize. + * @param name The name of the JavaScript asset. Used to generate source maps. + * @param options The optimization request options to apply to the content. + * @returns A promise that resolves with the optimized code, source map, and any warnings. + */ +async function optimizeWithEsbuild( + content: string, + name: string, + options: OptimizeRequest['options'], +): Promise { + if (!esbuild) { + esbuild = new EsbuildExecutor(options.alwaysUseWasm); + } + + let result: TransformResult; + try { + result = await esbuild.transform(content, { + minifyIdentifiers: !options.keepNames, + minifySyntax: true, + // NOTE: Disabling whitespace ensures unused pure annotations are kept + minifyWhitespace: false, + pure: ['forwardRef'], + legalComments: options.removeLicenses ? 'none' : 'inline', + sourcefile: name, + sourcemap: options.sourcemap && 'external', + define: options.define, + keepNames: options.keepNames, + target: `es${options.target}`, + }); + } catch (error) { + const failure = error as TransformFailure; + + // If esbuild fails with only ES5 support errors, fallback to just terser. + // This will only happen if ES5 is the output target and a global script contains ES2015+ syntax. + // In that case, the global script is technically already invalid for the target environment but + // this is and has been considered a configuration issue. Global scripts must be compatible with + // the target environment. + if ( + failure.errors?.every((error) => + error.text.includes('to the configured target environment ("es5") is not supported yet'), + ) + ) { + result = { + code: content, + map: '', + warnings: [], + }; + } else { + throw error; + } + } + + return result; +} + +/** + * Optimizes a JavaScript asset using terser. + * + * @param name The name of the JavaScript asset. Used to generate source maps. + * @param code The JavaScript asset source content to optimize. + * @param sourcemaps If true, generate an output source map for the optimized code. + * @param target Specifies the target ECMAScript version for the output code. + * @param advanced Controls advanced optimizations. + * @returns A promise that resolves with the optimized code and source map. + */ async function optimizeWithTerser( name: string, code: string, diff --git a/tests/legacy-cli/e2e/tests/build/esbuild-unsupported.ts b/tests/legacy-cli/e2e/tests/build/esbuild-unsupported.ts new file mode 100644 index 000000000000..0a3681549d3d --- /dev/null +++ b/tests/legacy-cli/e2e/tests/build/esbuild-unsupported.ts @@ -0,0 +1,11 @@ +import { join } from 'path'; +import { execWithEnv } from '../../utils/process'; + +export default async function () { + // Set the esbuild native binary path to a non-existent file to simulate a spawn error. + // The build should still succeed by falling back to the WASM variant of esbuild. + await execWithEnv('ng', ['build'], { + ...process.env, + 'ESBUILD_BINARY_PATH': join(__dirname, 'esbuild-bin-no-exist-xyz'), + }); +} diff --git a/yarn.lock b/yarn.lock index 88c5bbf2b62a..7e14a6505543 100644 --- a/yarn.lock +++ b/yarn.lock @@ -115,8 +115,7 @@ "@angular/dev-infra-private@https://github.com/angular/dev-infra-private-builds.git#eb1caf2ab598f0b0f1ef9efd00218c6692e6b06f": version "0.0.0" - uid eb1caf2ab598f0b0f1ef9efd00218c6692e6b06f - resolved "https://github.com/angular/dev-infra-private-builds.git#eb1caf2ab598f0b0f1ef9efd00218c6692e6b06f" + resolved "https://github.com/angular/dev-infra-private-builds.git#f1e02ba26af835ba0b20b7ed1bdff55694500865" dependencies: "@actions/core" "^1.4.0" "@actions/github" "^5.0.0" @@ -129,7 +128,7 @@ "@bazel/protractor" "4.1.0" "@bazel/runfiles" "4.1.0" "@bazel/typescript" "4.1.0" - "@microsoft/api-extractor" "7.18.9" + "@microsoft/api-extractor" "7.18.7" "@octokit/auth-app" "^3.6.0" "@octokit/core" "^3.5.1" "@octokit/graphql" "^4.8.0" @@ -138,8 +137,6 @@ "@octokit/request-error" "^2.1.0" "@octokit/rest" "^18.7.0" "@octokit/types" "^6.16.6" - "@rollup/plugin-commonjs" "^20.0.0" - "@rollup/plugin-node-resolve" "^13.0.4" chalk "^4.1.0" clang-format "^1.4.0" cli-progress "^3.7.0" @@ -156,7 +153,9 @@ node-fetch "^2.6.1" prettier "^2.3.2" protractor "^7.0.0" - rollup "2.56.3" + rollup "^2.53.3" + rollup-plugin-commonjs "^10.1.0" + rollup-plugin-node-resolve "^5.2.0" rollup-plugin-sourcemaps "^0.6.3" selenium-webdriver "3.5.0" semver "^7.3.5" @@ -1307,24 +1306,24 @@ brfs "^1.4.0" unicode-trie "^0.3.0" -"@microsoft/api-extractor-model@7.13.7": - version "7.13.7" - resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.13.7.tgz#2ae0948cb7458b336694c458675717ef8a9dcc85" - integrity sha512-emwhcaSF/h3WdqBWps4UU0RtGOGzy53IsplxuoLwtCuMAx3namYvJSfUGa5ajGPBao4MCyRYGsMc3EZ6IdR8cQ== +"@microsoft/api-extractor-model@7.13.5": + version "7.13.5" + resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.13.5.tgz#7836a81ba47b9a654062ed0361e4eee69afae51e" + integrity sha512-il6AebNltYo5hEtqXZw4DMvrwBPn6+F58TxwqmsLY+U+sSJNxaYn2jYksArrjErXVPR3gUgRMqD6zsdIkg+WEQ== dependencies: "@microsoft/tsdoc" "0.13.2" "@microsoft/tsdoc-config" "~0.15.2" - "@rushstack/node-core-library" "3.40.2" + "@rushstack/node-core-library" "3.40.0" -"@microsoft/api-extractor@7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.18.9.tgz#82f50f8791bfacd5e3dd5d9400cdb6d69a499249" - integrity sha512-N+fbG+6SwA1i6EW3iGRp/nAT8vQpRSDvZ1DzBUr8xIS7tNfJ0C75ndPPziUT8EmalhLixRnIw6Ncmur8AFELRg== +"@microsoft/api-extractor@7.18.7": + version "7.18.7" + resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.18.7.tgz#851d2413a3c5d696f7cc914eb59de7a7882b2e8b" + integrity sha512-JhtV8LoyLuIecbgCPyZQg08G1kngIRWpai2UzwNil9mGVGYiDZVeeKx8c2phmlPcogmMDm4oQROxyuiYt5sJiw== dependencies: - "@microsoft/api-extractor-model" "7.13.7" + "@microsoft/api-extractor-model" "7.13.5" "@microsoft/tsdoc" "0.13.2" "@microsoft/tsdoc-config" "~0.15.2" - "@rushstack/node-core-library" "3.40.2" + "@rushstack/node-core-library" "3.40.0" "@rushstack/rig-package" "0.3.0" "@rushstack/ts-command-line" "4.9.0" colors "~1.2.1" @@ -1671,7 +1670,7 @@ dependencies: "@rollup/pluginutils" "^3.0.8" -"@rollup/plugin-node-resolve@^13.0.0", "@rollup/plugin-node-resolve@^13.0.4": +"@rollup/plugin-node-resolve@^13.0.0": version "13.0.4" resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz#b10222f4145a019740acb7738402130d848660c0" integrity sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w== @@ -1692,10 +1691,10 @@ estree-walker "^1.0.1" picomatch "^2.2.2" -"@rushstack/node-core-library@3.40.2": - version "3.40.2" - resolved "https://registry.yarnpkg.com/@rushstack/node-core-library/-/node-core-library-3.40.2.tgz#71d92180f14bafd212f720b2cfe8892e688159b6" - integrity sha512-wzcRucwnhOENTfx6hZ2M+CA1Zmp8Dr572mFFtjxmcQzBWTbNFRB1Mi1wLb7DLza+69OUBoSZcHUqydlwL+gvSA== +"@rushstack/node-core-library@3.40.0": + version "3.40.0" + resolved "https://registry.yarnpkg.com/@rushstack/node-core-library/-/node-core-library-3.40.0.tgz#2551915ea34e34ec2abb7172b9d7f4546144d9d4" + integrity sha512-P6uMPI7cqTdawLSPAG5BQrBu1MHlGRPqecp7ruIRgyukIEzkmh0QAnje4jAL/l1r3hw0qe4e+Dz5ZSnukT/Egg== dependencies: "@types/node" "10.17.13" colors "~1.2.1" @@ -2164,6 +2163,13 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== +"@types/resolve@0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" + integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== + dependencies: + "@types/node" "*" + "@types/resolve@1.17.1": version "1.17.1" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" @@ -4212,9 +4218,9 @@ ejs@^3.1.6: jake "^10.6.1" electron-to-chromium@^1.3.830: - version "1.3.843" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.843.tgz#671489bd2f59fd49b76adddc1aa02c88cd38a5c0" - integrity sha512-OWEwAbzaVd1Lk9MohVw8LxMXFlnYd9oYTYxfX8KS++kLLjDfbovLOcEEXwRhG612dqGQ6+44SZvim0GXuBRiKg== + version "1.3.840" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.840.tgz#3f2a1df97015d9b1db5d86a4c6bd4cdb920adcbb" + integrity sha512-yRoUmTLDJnkIJx23xLY7GbSvnmDCq++NSuxHDQ0jiyDJ9YZBUGJcrdUqm+ZwZFzMbCciVzfem2N2AWiHJcWlbw== emoji-regex@^8.0.0: version "8.0.0" @@ -4400,6 +4406,11 @@ es6-weak-map@^2.0.3: es6-iterator "^2.0.3" es6-symbol "^3.1.1" +esbuild-wasm@0.12.28: + version "0.12.28" + resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.12.28.tgz#4142a6bb1aeb1987c4b3596b247327d7bc6aa4a2" + integrity sha512-SiIIPHyPWaXRQ+IkAHeF5Pd9+n86mPqQG7mZAhGKn7Y6NfPqP1H+svVEG72pN8aoBZKxblB0ah210qQfhbQIfA== + esbuild@0.12.28, esbuild@^0.12.15: version "0.12.28" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.28.tgz#84da0d2a0d0dee181281545271e0d65cf6fab1ef" @@ -4625,6 +4636,11 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== +estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + estree-walker@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" @@ -5884,7 +5900,7 @@ is-promise@^2.1.0, is-promise@^2.2.2: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-reference@^1.2.1: +is-reference@^1.1.2, is-reference@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== @@ -6693,7 +6709,7 @@ lunr-mutable-indexes@2.3.2: resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== -magic-string@0.25.7, magic-string@^0.25.0, magic-string@^0.25.7: +magic-string@0.25.7, magic-string@^0.25.0, magic-string@^0.25.2, magic-string@^0.25.7: version "0.25.7" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== @@ -8850,7 +8866,7 @@ resolve-url-loader@4.0.0: postcss "^7.0.35" source-map "0.6.1" -resolve@1.20.0, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2: +resolve@1.20.0, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -8936,6 +8952,28 @@ rimraf@~2.6.2: dependencies: glob "^7.1.3" +rollup-plugin-commonjs@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz#417af3b54503878e084d127adf4d1caf8beb86fb" + integrity sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q== + dependencies: + estree-walker "^0.6.1" + is-reference "^1.1.2" + magic-string "^0.25.2" + resolve "^1.11.0" + rollup-pluginutils "^2.8.1" + +rollup-plugin-node-resolve@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz#730f93d10ed202473b1fb54a5997a7db8c6d8523" + integrity sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw== + dependencies: + "@types/resolve" "0.0.8" + builtin-modules "^3.1.0" + is-module "^1.0.0" + resolve "^1.11.1" + rollup-pluginutils "^2.8.1" + rollup-plugin-sourcemaps@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.6.3.tgz#bf93913ffe056e414419607f1d02780d7ece84ed" @@ -8944,7 +8982,14 @@ rollup-plugin-sourcemaps@^0.6.3: "@rollup/pluginutils" "^3.0.9" source-map-resolve "^0.6.0" -rollup@2.56.3, rollup@^2.45.1: +rollup-pluginutils@^2.8.1: + version "2.8.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" + integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== + dependencies: + estree-walker "^0.6.1" + +rollup@^2.45.1, rollup@^2.53.3: version "2.56.3" resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.56.3.tgz#b63edadd9851b0d618a6d0e6af8201955a77aeff" integrity sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg== @@ -9016,7 +9061,6 @@ sass@^1.32.8: "sauce-connect-proxy@https://saucelabs.com/downloads/sc-4.6.4-linux.tar.gz": version "0.0.0" - uid "992e2cb0d91e54b27a4f5bbd2049f3b774718115" resolved "https://saucelabs.com/downloads/sc-4.6.4-linux.tar.gz#992e2cb0d91e54b27a4f5bbd2049f3b774718115" saucelabs@^1.5.0: