vscode: add experimental esbuild support (#34010)

Co-authored-by: Beatrix <68532117+abeatrix@users.noreply.github.com>
This commit is contained in:
TJ Kandala 2022-06-09 22:42:45 -04:00 committed by GitHub
parent c15f33c565
commit bf6fadfed9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 360 additions and 102 deletions

1
.vscode/launch.json vendored
View File

@ -33,6 +33,7 @@
"--extensionDevelopmentKind=web",
"--disable-web-security",
],
"sourceMaps": true,
"outFiles": ["${workspaceRoot}/client/vscode/dist/webworker/*.js"],
},
{

View File

@ -4,7 +4,9 @@ import * as esbuild from 'esbuild'
import { EditorFeature, featuresArr } from 'monaco-editor-webpack-plugin/out/features'
import { EditorLanguage, languagesArr } from 'monaco-editor-webpack-plugin/out/languages'
import { MONACO_LANGUAGES_AND_FEATURES, ROOT_PATH } from '@sourcegraph/build-config'
import { MONACO_LANGUAGES_AND_FEATURES } from '@sourcegraph/build-config'
import { ROOT_PATH } from '../paths'
const monacoModulePath = (modulePath: string): string =>
require.resolve(path.join('monaco-editor/esm', modulePath), {
@ -57,3 +59,20 @@ export const monacoPlugin = ({
build.onLoad({ filter }, () => ({ contents: '', loader: 'js' }))
},
})
// TODO(sqs): These Monaco Web Workers could be built as part of the main build if we switch to
// using MonacoEnvironment#getWorker (from #getWorkerUrl), which would then let us use the worker
// plugin (and in Webpack the worker-loader) to load these instead of needing to hardcode them as
// build entrypoints.
export const buildMonaco = async (outdir: string): Promise<void> => {
await esbuild.build({
entryPoints: {
'scripts/editor.worker.bundle': 'monaco-editor/esm/vs/editor/editor.worker.js',
'scripts/json.worker.bundle': 'monaco-editor/esm/vs/language/json/json.worker.js',
},
format: 'iife',
target: 'es2021',
bundle: true,
outdir,
})
}

View File

@ -0,0 +1,55 @@
import fs from 'fs'
import { CachedInputFileSystem, ResolverFactory } from 'enhanced-resolve'
import * as esbuild from 'esbuild'
import { NODE_MODULES_PATH } from '../paths'
interface Resolutions {
[fromModule: string]: string
}
/**
* An esbuild plugin to redirect imports from one package to another (for example, from 'path' to
* 'path-browserify' to run in the browser).
*/
export const packageResolutionPlugin = (resolutions: Resolutions): esbuild.Plugin => ({
name: 'packageResolution',
setup: build => {
const filter = new RegExp(`^(${Object.keys(resolutions).join('|')})$`)
const resolver = ResolverFactory.createResolver({
fileSystem: new CachedInputFileSystem(fs, 4000),
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
symlinks: true, // Resolve workspace symlinks
modules: [NODE_MODULES_PATH],
})
build.onResolve({ filter, namespace: 'file' }, async args => {
if ((args.kind === 'import-statement' || args.kind === 'require-call') && resolutions[args.path]) {
const resolvedPath = await new Promise<string>((resolve, reject) => {
resolver.resolve({}, args.resolveDir, resolutions[args.path], {}, (error, filepath) => {
if (filepath) {
resolve(filepath)
} else {
reject(error ?? new Error(`Could not resolve file path for ${resolutions[args.path]}`))
}
})
})
return { path: resolvedPath }
}
return undefined
})
},
})
export const RXJS_RESOLUTIONS: Resolutions = {
// Needed because imports of rxjs/internal/... actually import a different variant of
// rxjs in the same package, which leads to observables from combineLatestOrDefault (and
// other places that use rxjs/internal/...) not being cross-compatible. See
// https://stackoverflow.com/questions/53758889/rxjs-subscribeto-js-observable-check-works-in-chrome-but-fails-in-chrome-incogn.
'rxjs/internal/OuterSubscriber': require.resolve('rxjs/_esm5/internal/OuterSubscriber'),
'rxjs/internal/util/subscribeToResult': require.resolve('rxjs/_esm5/internal/util/subscribeToResult'),
'rxjs/internal/util/subscribeToArray': require.resolve('rxjs/_esm5/internal/util/subscribeToArray'),
'rxjs/internal/Observable': require.resolve('rxjs/_esm5/internal/Observable'),
}

View File

@ -0,0 +1,27 @@
import * as esbuild from 'esbuild'
import signale from 'signale'
export * from './monacoPlugin'
export * from './packageResolutionPlugin'
export * from './stylePlugin'
export * from './workerPlugin'
export const buildTimerPlugin: esbuild.Plugin = {
name: 'buildTimer',
setup: (build: esbuild.PluginBuild): void => {
let buildStarted: number
build.onStart(() => {
buildStarted = Date.now()
})
build.onEnd(() => console.log(`# esbuild: build took ${Date.now() - buildStarted}ms`))
},
}
export const experimentalNoticePlugin: esbuild.Plugin = {
name: 'experimentalNotice',
setup: (): void => {
signale.info(
'esbuild usage is experimental. See https://docs.sourcegraph.com/dev/background-information/web/build#esbuild.'
)
},
}

View File

@ -1,16 +1,16 @@
import fs from 'fs'
import path from 'path'
import { ResolverFactory, CachedInputFileSystem } from 'enhanced-resolve'
import esbuild from 'esbuild'
import postcss from 'postcss'
import postcssModules from 'postcss-modules'
import sass from 'sass'
import { ROOT_PATH } from '@sourcegraph/build-config'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import postcssConfig from '../../../../postcss.config'
import { NODE_MODULES_PATH, ROOT_PATH } from '../paths'
/**
* An esbuild plugin that builds .css and .scss stylesheets (including support for CSS modules).
@ -98,14 +98,29 @@ export const stylePlugin: esbuild.Plugin = {
return output
}
const resolver = ResolverFactory.createResolver({
fileSystem: new CachedInputFileSystem(fs, 4000),
extensions: ['.css', '.scss'],
symlinks: true, // Resolve workspace symlinks
modules: [NODE_MODULES_PATH],
})
build.onResolve({ filter: /\.s?css$/, namespace: 'file' }, async args => {
const inputPath = path.join(args.resolveDir, args.path)
const inputPath = await new Promise<string>((resolve, reject) => {
resolver.resolve({}, args.resolveDir, args.path, {}, (error, filepath) => {
if (filepath) {
resolve(filepath)
} else {
reject(error ?? new Error(`Could not resolve file path for ${args.path}`))
}
})
})
const { outputPath, outputContents, includedFiles } = await cachedTransform({
inputPath,
inputContents: await fs.promises.readFile(inputPath, 'utf8'),
})
const isCSSModule = outputPath.endsWith('.module.css')
return {
path: outputPath,
namespace: isCSSModule ? 'css-module' : 'css',

View File

@ -2,7 +2,7 @@ import path from 'path'
import * as esbuild from 'esbuild'
import { BUILD_OPTIONS } from './build'
import { packageResolutionPlugin, RXJS_RESOLUTIONS } from '@sourcegraph/build-config'
async function buildWorker(
workerPath: string,
@ -12,7 +12,12 @@ async function buildWorker(
entryPoints: [workerPath],
bundle: true,
write: false,
plugins: BUILD_OPTIONS.plugins?.filter(plugin => plugin.name === 'packageResolution'),
plugins: [
packageResolutionPlugin({
path: require.resolve('path-browserify'),
...RXJS_RESOLUTIONS,
}),
],
sourcemap: true,
metafile: true,
...extraConfig,

View File

@ -1,3 +1,4 @@
export * from './esbuild/plugins'
export * from './paths'
export * from './webpack/babel-loader'
export * from './webpack/css-loader'

View File

@ -21,6 +21,7 @@ const {
watchCSSModulesTypings,
} = require('../shared/gulpfile')
const buildScripts = require('./scripts/build')
const createWebpackConfig = require('./webpack.config')
const WEBPACK_STATS_OPTIONS = {
@ -67,6 +68,10 @@ async function watchWebpack() {
})
}
async function esbuild() {
await buildScripts.build()
}
// Ensure the typings that TypeScript depends on are build to avoid first-time-run errors
const generate = gulp.parallel(schema, graphQlSchema, graphQlOperations, cssModulesTypings)
@ -88,4 +93,4 @@ const watch = gulp.series(
gulp.parallel(watchGenerators, watchWebpack)
)
module.exports = { build, watch, webpack, watchWebpack }
module.exports = { build, watch, webpack, watchWebpack, esbuild }

View File

@ -5,7 +5,7 @@
"version": "2.2.3",
"description": "Sourcegraph for VS Code",
"publisher": "sourcegraph",
"sideEffects": false,
"sideEffects": true,
"license": "Apache-2.0",
"icon": "images/logo.png",
"repository": {
@ -221,6 +221,9 @@
"test": "ts-node ./tests/runTests.ts",
"package": "ts-node ./scripts/package.ts",
"task:gulp": "cross-env NODE_OPTIONS=\"--max_old_space_size=8192\" gulp",
"build:esbuild": "NODE_ENV=development yarn task:gulp esbuild",
"build:esbuild:web": "NODE_ENV=development TARGET_TYPE=webworker yarn task:gulp esbuild",
"watch:esbuild": "NODE_ENV=development WATCH=true yarn task:gulp esbuild",
"build": "NODE_ENV=production yarn task:gulp webpack",
"build:node": "NODE_ENV=production TARGET_TYPE=node yarn task:gulp webpack",
"build:web": "NODE_ENV=production TARGET_TYPE=webworker yarn task:gulp webpack",

View File

@ -0,0 +1,5 @@
// This file is used for esbuild's `inject` option
// in order to load node polyfills in the webworker
// extension host.
// See: https://esbuild.github.io/api/#inject.
export const Buffer = require('buffer/').Buffer

View File

@ -0,0 +1,149 @@
import { existsSync } from 'fs'
import path from 'path'
import * as esbuild from 'esbuild'
import { rm } from 'shelljs'
import {
buildMonaco,
monacoPlugin,
MONACO_LANGUAGES_AND_FEATURES,
packageResolutionPlugin,
stylePlugin,
workerPlugin,
RXJS_RESOLUTIONS,
buildTimerPlugin,
} from '@sourcegraph/build-config'
const watch = !!process.env.WATCH
const minify = process.env.NODE_ENV === 'production'
const outdir = path.join(__dirname, '../dist')
const isTest = !!process.env.IS_TEST
const TARGET_TYPE = process.env.TARGET_TYPE
const SHARED_CONFIG = {
outdir,
watch,
minify,
sourcemap: true,
}
export async function build(): Promise<void> {
if (existsSync(outdir)) {
rm('-rf', outdir)
}
const buildPromises = []
if (TARGET_TYPE === 'node' || !TARGET_TYPE) {
buildPromises.push(
esbuild.build({
entryPoints: { extension: path.join(__dirname, '/../src/extension.ts') },
bundle: true,
format: 'cjs',
platform: 'node',
external: ['vscode'],
banner: { js: 'global.Buffer = require("buffer").Buffer' },
define: {
'process.env.IS_TEST': isTest ? 'true' : 'false',
},
...SHARED_CONFIG,
outdir: path.join(SHARED_CONFIG.outdir, 'node'),
})
)
}
if (TARGET_TYPE === 'webworker' || !TARGET_TYPE) {
buildPromises.push(
esbuild.build({
entryPoints: { extension: path.join(__dirname, '/../src/extension.ts') },
bundle: true,
format: 'cjs',
platform: 'browser',
external: ['vscode'],
define: {
'process.env.IS_TEST': isTest ? 'true' : 'false',
global: 'globalThis',
},
inject: ['./scripts/process-shim.js', './scripts/buffer-shim.js'],
plugins: [
packageResolutionPlugin({
process: require.resolve('process/browser'),
path: require.resolve('path-browserify'),
http: require.resolve('stream-http'),
https: require.resolve('https-browserify'),
stream: require.resolve('stream-browserify'),
util: require.resolve('util'),
events: require.resolve('events'),
buffer: require.resolve('buffer/'),
'./browserActionsNode': path.resolve(__dirname, '../src', 'link-commands', 'browserActionsWeb'),
}),
],
...SHARED_CONFIG,
outdir: path.join(SHARED_CONFIG.outdir, 'webworker'),
})
)
}
buildPromises.push(
esbuild.build({
entryPoints: {
helpSidebar: path.join(__dirname, '../src/webview/sidebars/help'),
searchSidebar: path.join(__dirname, '../src/webview/sidebars/search'),
searchPanel: path.join(__dirname, '../src/webview/search-panel'),
style: path.join(__dirname, '../src/webview/index.scss'),
},
bundle: true,
format: 'esm',
platform: 'browser',
splitting: true,
plugins: [
stylePlugin,
workerPlugin,
packageResolutionPlugin({
path: require.resolve('path-browserify'),
...RXJS_RESOLUTIONS,
'./Link': require.resolve('../src/webview/search-panel/alias/Link'),
'../Link': require.resolve('../src/webview/search-panel/alias/Link'),
'./RepoSearchResult': require.resolve('../src/webview/search-panel/alias/RepoSearchResult'),
'./CommitSearchResult': require.resolve('../src/webview/search-panel/alias/CommitSearchResult'),
'./FileMatchChildren': require.resolve('../src/webview/search-panel/alias/FileMatchChildren'),
'./RepoFileLink': require.resolve('../src/webview/search-panel/alias/RepoFileLink'),
'../documentation/ModalVideo': require.resolve('../src/webview/search-panel/alias/ModalVideo'),
}),
// Note: leads to "file has no exports" warnings
monacoPlugin(MONACO_LANGUAGES_AND_FEATURES),
buildTimerPlugin,
{
name: 'codiconsDeduplicator',
setup(build): void {
build.onLoad({ filter: /\.ttf$/ }, args => {
// Both `@vscode/codicons` and `monaco-editor`
// node modules include a `codicons.ttf` file,
// so null one out.
if (!args.path.includes('@vscode/codicons')) {
return {
contents: '',
loader: 'text',
}
}
return null
})
},
},
],
loader: {
'.ttf': 'file',
},
assetNames: '[name]',
ignoreAnnotations: true,
treeShaking: false,
...SHARED_CONFIG,
outdir: path.join(SHARED_CONFIG.outdir, 'webview'),
})
)
buildPromises.push(buildMonaco(outdir))
await Promise.all(buildPromises)
}

View File

@ -0,0 +1,5 @@
// This file is used for esbuild's `inject` option
// in order to load node polyfills in the webworker
// extension host.
// See: https://esbuild.github.io/api/#inject.
export const process = require('process/browser')

View File

@ -1,7 +1,7 @@
@import './forkedBranded.scss';
@import './theming/highlight.scss';
@import './theming/monaco.scss';
@import '~@vscode/codicons/dist/codicon.css';
@import '../../../../node_modules/@vscode/codicons/dist/codicon.css';
:root {
// v2/debt: redefine our CSS variables using VS Code's CSS variables

View File

@ -23,15 +23,15 @@ export async function initializeSearchPanelWebview({
searchPanelAPI: Comlink.Remote<SearchPanelAPI>
webviewPanel: vscode.WebviewPanel
}> {
const webviewPath = vscode.Uri.joinPath(extensionUri, 'dist', 'webview')
const panel = vscode.window.createWebviewPanel('sourcegraphSearch', 'Sourcegraph', vscode.ViewColumn.One, {
enableScripts: true,
retainContextWhenHidden: true,
enableFindWidget: true,
localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'dist', 'webview')],
localResourceRoots: [webviewPath],
})
const webviewPath = vscode.Uri.joinPath(extensionUri, 'dist', 'webview')
const scriptSource = panel.webview.asWebviewUri(vscode.Uri.joinPath(webviewPath, 'searchPanel.js'))
const cssModuleSource = panel.webview.asWebviewUri(vscode.Uri.joinPath(webviewPath, 'searchPanel.css'))
const styleSource = panel.webview.asWebviewUri(vscode.Uri.joinPath(webviewPath, 'style.css'))
@ -53,7 +53,6 @@ export async function initializeSearchPanelWebview({
// Expose the "Core" extension API to the Webview.
Comlink.expose(extensionCoreAPI, expose)
// Use a nonce to only allow specific scripts to be run
const nonce = getNonce()
panel.iconPath = vscode.Uri.joinPath(extensionUri, 'images', 'logo.svg')
@ -85,7 +84,7 @@ export async function initializeSearchPanelWebview({
</head>
<body class="search-panel">
<div id="root" />
<script nonce="${nonce}" src="${scriptSource.toString()}"></script>
<script type="module" nonce="${nonce}" src="${scriptSource.toString()}"></script>
</body>
</html>`
@ -107,13 +106,13 @@ export function initializeSearchSidebarWebview({
}): {
searchSidebarAPI: Comlink.Remote<SearchSidebarAPI>
} {
const webviewPath = vscode.Uri.joinPath(extensionUri, 'dist', 'webview')
webviewView.webview.options = {
enableScripts: true,
localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'dist', 'webview')],
localResourceRoots: [webviewPath],
}
const webviewPath = vscode.Uri.joinPath(extensionUri, 'dist', 'webview')
const scriptSource = webviewView.webview.asWebviewUri(vscode.Uri.joinPath(webviewPath, 'searchSidebar.js'))
const cssModuleSource = webviewView.webview.asWebviewUri(vscode.Uri.joinPath(webviewPath, 'searchSidebar.css'))
const styleSource = webviewView.webview.asWebviewUri(vscode.Uri.joinPath(webviewPath, 'style.css'))
@ -151,7 +150,7 @@ export function initializeSearchSidebarWebview({
</head>
<body class="search-sidebar">
<div id="root" />
<script src="${scriptSource.toString()}"></script>
<script type="module" src="${scriptSource.toString()}"></script>
</body>
</html>`
@ -169,13 +168,13 @@ export function initializeHelpSidebarWebview({
}): {
helpSidebarAPI: Comlink.Remote<HelpSidebarAPI>
} {
const webviewPath = vscode.Uri.joinPath(extensionUri, 'dist', 'webview')
webviewView.webview.options = {
enableScripts: true,
localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'dist', 'webview')],
localResourceRoots: [webviewPath],
}
const webviewPath = vscode.Uri.joinPath(extensionUri, 'dist', 'webview')
const scriptSource = webviewView.webview.asWebviewUri(vscode.Uri.joinPath(webviewPath, 'helpSidebar.js'))
const cssModuleSource = webviewView.webview.asWebviewUri(vscode.Uri.joinPath(webviewPath, 'helpSidebar.css'))
const styleSource = webviewView.webview.asWebviewUri(vscode.Uri.joinPath(webviewPath, 'style.css'))
@ -202,7 +201,7 @@ export function initializeHelpSidebarWebview({
<link rel="stylesheet" href="${cssModuleSource.toString()}" />
</head>
<div id="root" />
<script src="${scriptSource.toString()}"></script>
<script type="module" src="${scriptSource.toString()}"></script>
</body>
</html>`

View File

@ -1,17 +1,24 @@
import path from 'path'
import * as esbuild from 'esbuild'
import signale from 'signale'
import { MONACO_LANGUAGES_AND_FEATURES, ROOT_PATH, STATIC_ASSETS_PATH } from '@sourcegraph/build-config'
import {
MONACO_LANGUAGES_AND_FEATURES,
ROOT_PATH,
STATIC_ASSETS_PATH,
stylePlugin,
packageResolutionPlugin,
workerPlugin,
monacoPlugin,
RXJS_RESOLUTIONS,
buildMonaco,
experimentalNoticePlugin,
buildTimerPlugin,
} from '@sourcegraph/build-config'
import { ENVIRONMENT_CONFIG } from '../utils'
import { manifestPlugin } from './manifestPlugin'
import { monacoPlugin } from './monacoPlugin'
import { packageResolutionPlugin } from './packageResolutionPlugin'
import { stylePlugin } from './stylePlugin'
import { workerPlugin } from './workerPlugin'
const isEnterpriseBuild = ENVIRONMENT_CONFIG.ENTERPRISE
@ -35,35 +42,11 @@ export const BUILD_OPTIONS: esbuild.BuildOptions = {
manifestPlugin,
packageResolutionPlugin({
path: require.resolve('path-browserify'),
// Needed because imports of rxjs/internal/... actually import a different variant of
// rxjs in the same package, which leads to observables from combineLatestOrDefault (and
// other places that use rxjs/internal/...) not being cross-compatible. See
// https://stackoverflow.com/questions/53758889/rxjs-subscribeto-js-observable-check-works-in-chrome-but-fails-in-chrome-incogn.
'rxjs/internal/OuterSubscriber': require.resolve('rxjs/_esm5/internal/OuterSubscriber'),
'rxjs/internal/util/subscribeToResult': require.resolve('rxjs/_esm5/internal/util/subscribeToResult'),
'rxjs/internal/util/subscribeToArray': require.resolve('rxjs/_esm5/internal/util/subscribeToArray'),
'rxjs/internal/Observable': require.resolve('rxjs/_esm5/internal/Observable'),
...RXJS_RESOLUTIONS,
}),
monacoPlugin(MONACO_LANGUAGES_AND_FEATURES),
{
name: 'buildTimer',
setup: (build: esbuild.PluginBuild): void => {
let buildStarted: number
build.onStart(() => {
buildStarted = Date.now()
})
build.onEnd(() => console.log(`# esbuild: build took ${Date.now() - buildStarted}ms`))
},
},
{
name: 'experimentalNotice',
setup: (): void => {
signale.info(
'esbuild usage is experimental. See https://docs.sourcegraph.com/dev/background-information/web/build#esbuild.'
)
},
},
buildTimerPlugin,
experimentalNoticePlugin,
],
define: {
...Object.fromEntries(
@ -90,29 +73,12 @@ export const BUILD_OPTIONS: esbuild.BuildOptions = {
treeShaking: false,
}
// TODO(sqs): These Monaco Web Workers could be built as part of the main build if we switch to
// using MonacoEnvironment#getWorker (from #getWorkerUrl), which would then let us use the worker
// plugin (and in Webpack the worker-loader) to load these instead of needing to hardcode them as
// build entrypoints.
export const buildMonaco = async (): Promise<void> => {
await esbuild.build({
entryPoints: {
'scripts/editor.worker.bundle': 'monaco-editor/esm/vs/editor/editor.worker.js',
'scripts/json.worker.bundle': 'monaco-editor/esm/vs/language/json/json.worker.js',
},
format: 'iife',
target: 'es2021',
bundle: true,
outdir: STATIC_ASSETS_PATH,
})
}
export const build = async (): Promise<void> => {
await esbuild.build({
...BUILD_OPTIONS,
outdir: STATIC_ASSETS_PATH,
})
await buildMonaco()
await buildMonaco(STATIC_ASSETS_PATH)
}
if (require.main === module) {

View File

@ -1,17 +0,0 @@
import * as esbuild from 'esbuild'
/**
* An esbuild plugin to redirect imports from one package to another (for example, from 'path' to
* 'path-browserify' to run in the browser).
*/
export const packageResolutionPlugin = (resolutions: { [fromModule: string]: string }): esbuild.Plugin => ({
name: 'packageResolution',
setup: build => {
const filter = new RegExp(`^(${Object.keys(resolutions).join('|')})$`)
build.onResolve({ filter, namespace: 'file' }, args =>
(args.kind === 'import-statement' || args.kind === 'require-call') && resolutions[args.path]
? { path: resolutions[args.path] }
: undefined
)
},
})

View File

@ -5,9 +5,9 @@ import express from 'express'
import { createProxyMiddleware } from 'http-proxy-middleware'
import signale from 'signale'
import { STATIC_ASSETS_PATH } from '@sourcegraph/build-config'
import { STATIC_ASSETS_PATH, buildMonaco } from '@sourcegraph/build-config'
import { buildMonaco, BUILD_OPTIONS } from './build'
import { BUILD_OPTIONS } from './build'
import { assetPathPrefix } from './manifestPlugin'
export const esbuildDevelopmentServer = async (
@ -16,7 +16,7 @@ export const esbuildDevelopmentServer = async (
): Promise<void> => {
// One-time build (these files only change when the monaco-editor npm package is changed, which
// is rare enough to ignore here).
await buildMonaco()
await buildMonaco(STATIC_ASSETS_PATH)
// Start esbuild's server on a random local port.
const { host: esbuildHost, port: esbuildPort, wait: esbuildStopped } = await serve(

View File

@ -243,6 +243,7 @@
"babel-plugin-lodash": "^3.3.4",
"babel-preset-react-app": "^10.0.0",
"browserslist": "^4.17.4",
"buffer": "^6.0.3",
"bundlesize2": "^0.0.31",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
@ -259,10 +260,12 @@
"css-minimizer-webpack-plugin": "^3.0.2",
"elm": "^0.19.1-3",
"elm-webpack-loader": "^8.0.0",
"enhanced-resolve": "^5.9.3",
"esbuild": "^0.14.2",
"eslint": "^8.13.0",
"eslint-formatter-lsif": "^1.0.3",
"eslint-plugin-monorepo": "^0.3.2",
"events": "^3.3.0",
"execa": "^5.0.0",
"express": "^4.17.1",
"express-static-gzip": "^2.1.1",
@ -325,6 +328,7 @@
"speed-measure-webpack-plugin": "^1.5.0",
"storybook-addon-designs": "^6.2.1",
"storybook-dark-mode": "^1.1.0",
"stream-browserify": "^3.0.0",
"string-width": "^4.2.0",
"style-loader": "^3.1.0",
"stylelint": "^14.3.0",

View File

@ -8567,6 +8567,14 @@ buffer@^5.2.1, buffer@^5.5.0, buffer@^5.7.0:
base64-js "^1.3.1"
ieee754 "^1.1.13"
buffer@^6.0.3:
version "6.0.3"
resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.2.1"
buffers@~0.1.1:
version "0.1.1"
resolved "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb"
@ -11752,10 +11760,10 @@ engine.io@~3.4.0:
engine.io-parser "~2.2.0"
ws "^7.1.2"
enhanced-resolve@^5.0.0, enhanced-resolve@^5.9.2:
version "5.9.2"
resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz#0224dcd6a43389ebfb2d55efee517e5466772dd9"
integrity sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==
enhanced-resolve@^5.0.0, enhanced-resolve@^5.9.2, enhanced-resolve@^5.9.3:
version "5.9.3"
resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88"
integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
@ -12528,7 +12536,7 @@ eventemitter3@^4.0.0:
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
events@^3.2.0:
events@^3.2.0, events@^3.3.0:
version "3.3.0"
resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
@ -14907,7 +14915,7 @@ identity-obj-proxy@^3.0.0:
dependencies:
harmony-reflect "^1.4.6"
ieee754@^1.1.13:
ieee754@^1.1.13, ieee754@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
@ -15030,7 +15038,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.3:
inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.3, inherits@~2.0.4:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -21216,7 +21224,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@ -22879,6 +22887,14 @@ storybook-dark-mode@^1.1.0:
fast-deep-equal "^3.0.0"
memoizerific "^1.11.3"
stream-browserify@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f"
integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==
dependencies:
inherits "~2.0.4"
readable-stream "^3.5.0"
stream-exhaust@^1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d"