mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 15:31:48 +00:00
web: review environment variables before the Datadog integration (#33994)
This commit is contained in:
parent
33e7c8b494
commit
f3a11939af
@ -4,3 +4,4 @@ export * from './webpack/css-loader'
|
||||
export * from './webpack/getCacheConfig'
|
||||
export * from './webpack/monaco-editor'
|
||||
export * from './webpack/plugins'
|
||||
export * from './utils/environment-config'
|
||||
|
||||
6
client/build-config/src/utils/environment-config.ts
Normal file
6
client/build-config/src/utils/environment-config.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// Read the environment variable from `process.env` and cast it to `Boolean`.
|
||||
export function getEnvironmentBoolean(name: string): boolean {
|
||||
const variable = process.env[name]
|
||||
|
||||
return Boolean(variable && JSON.parse(variable))
|
||||
}
|
||||
@ -24,3 +24,26 @@ export const getProvidePlugin = (): webpack.ProvidePlugin =>
|
||||
})
|
||||
|
||||
export const getStatoscopePlugin = (): StatoscopeWebpackPlugin => new StatoscopeWebpackPlugin()
|
||||
|
||||
export const STATOSCOPE_STATS = {
|
||||
all: false, // disable all the stats
|
||||
hash: true, // compilation hash
|
||||
entrypoints: true,
|
||||
chunks: true,
|
||||
chunkModules: true, // modules
|
||||
reasons: true, // modules reasons
|
||||
ids: true, // IDs of modules and chunks (webpack 5)
|
||||
dependentModules: true, // dependent modules of chunks (webpack 5)
|
||||
chunkRelations: true, // chunk parents, children and siblings (webpack 5)
|
||||
cachedAssets: true, // information about the cached assets (webpack 5)
|
||||
|
||||
nestedModules: true, // concatenated modules
|
||||
usedExports: true,
|
||||
providedExports: true, // provided imports
|
||||
assets: true,
|
||||
chunkOrigins: true, // chunks origins stats (to find out which modules require a chunk)
|
||||
version: true, // webpack version
|
||||
builtAt: true, // build at time
|
||||
timings: true, // modules timing information
|
||||
performance: true, // info about oversized assets
|
||||
}
|
||||
|
||||
@ -36,3 +36,8 @@ export const createAggregateError = (errors: readonly ErrorLike[] = []): Error =
|
||||
name: AGGREGATE_ERROR_NAME,
|
||||
errors: errors.map(asError),
|
||||
})
|
||||
|
||||
export class AbortError extends Error {
|
||||
public readonly name = 'AbortError'
|
||||
public readonly message = 'Aborted'
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import { ProxyMarked, transferHandlers, releaseProxy, TransferHandler, Remote, p
|
||||
import { Observable, Observer, PartialObserver, Subscription } from 'rxjs'
|
||||
import { Subscribable, Unsubscribable } from 'sourcegraph'
|
||||
|
||||
import { hasProperty } from '@sourcegraph/common'
|
||||
import { hasProperty, AbortError } from '@sourcegraph/common'
|
||||
|
||||
import { ProxySubscribable } from './extension/api/common'
|
||||
|
||||
@ -123,11 +123,6 @@ export const observableFromAsyncIterable = <T>(iterable: AsyncIterable<T>): Obse
|
||||
}
|
||||
})
|
||||
|
||||
export class AbortError extends Error {
|
||||
public readonly name = 'AbortError'
|
||||
public readonly message = 'Aborted'
|
||||
}
|
||||
|
||||
/**
|
||||
* Promisifies method calls and objects if specified, throws otherwise if there is no stub provided
|
||||
* NOTE: it does not handle ProxyMethods and callbacks yet
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
const getEnvironmentBoolean = (value = 'false'): boolean => Boolean(JSON.parse(value))
|
||||
import { getEnvironmentBoolean } from '@sourcegraph/build-config'
|
||||
|
||||
export const environment = {
|
||||
customStoriesGlob: process.env.STORIES_GLOB,
|
||||
isDLLPluginEnabled: getEnvironmentBoolean(process.env.WEBPACK_DLL_PLUGIN),
|
||||
isProgressPluginEnabled: getEnvironmentBoolean(process.env.WEBPACK_PROGRESS_PLUGIN),
|
||||
isBundleAnalyzerEnabled: getEnvironmentBoolean(process.env.WEBPACK_BUNDLE_ANALYZER),
|
||||
isSpeedAnalyzerEnabled: getEnvironmentBoolean(process.env.WEBPACK_SPEED_ANALYZER),
|
||||
shouldMinify: getEnvironmentBoolean(process.env.MINIFY),
|
||||
export const ENVIRONMENT_CONFIG = {
|
||||
STORIES_GLOB: process.env.STORIES_GLOB,
|
||||
WEBPACK_DLL_PLUGIN: getEnvironmentBoolean('WEBPACK_DLL_PLUGIN'),
|
||||
WEBPACK_PROGRESS_PLUGIN: getEnvironmentBoolean('WEBPACK_PROGRESS_PLUGIN'),
|
||||
WEBPACK_BUNDLE_ANALYZER: getEnvironmentBoolean('WEBPACK_BUNDLE_ANALYZER'),
|
||||
WEBPACK_SPEED_ANALYZER: getEnvironmentBoolean('WEBPACK_SPEED_ANALYZER'),
|
||||
MINIFY: getEnvironmentBoolean('MINIFY'),
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ import {
|
||||
} from '@sourcegraph/build-config'
|
||||
|
||||
import { ensureDllBundleIsReady } from './dllPlugin'
|
||||
import { environment } from './environment-config'
|
||||
import { ENVIRONMENT_CONFIG } from './environment-config'
|
||||
import {
|
||||
monacoEditorPath,
|
||||
dllPluginConfig,
|
||||
@ -34,8 +34,8 @@ import {
|
||||
} from './webpack.config.common'
|
||||
|
||||
const getStoriesGlob = (): string[] => {
|
||||
if (process.env.STORIES_GLOB) {
|
||||
return [path.resolve(ROOT_PATH, process.env.STORIES_GLOB)]
|
||||
if (ENVIRONMENT_CONFIG.STORIES_GLOB) {
|
||||
return [path.resolve(ROOT_PATH, ENVIRONMENT_CONFIG.STORIES_GLOB)]
|
||||
}
|
||||
|
||||
// Stories in `Chromatic.story.tsx` are guarded by the `isChromatic()` check. It will result in noop in all other environments.
|
||||
@ -93,12 +93,12 @@ const config = {
|
||||
// Include DLL bundle script tag into preview-head.html if DLLPlugin is enabled.
|
||||
previewHead: (head: string) => `
|
||||
${head}
|
||||
${environment.isDLLPluginEnabled ? getDllScriptTag() : ''}
|
||||
${ENVIRONMENT_CONFIG.WEBPACK_DLL_PLUGIN ? getDllScriptTag() : ''}
|
||||
`,
|
||||
|
||||
webpackFinal: (config: Configuration, options: Options) => {
|
||||
config.stats = 'errors-warnings'
|
||||
config.mode = environment.shouldMinify ? 'production' : 'development'
|
||||
config.mode = ENVIRONMENT_CONFIG.MINIFY ? 'production' : 'development'
|
||||
|
||||
// Check the default config is in an expected shape.
|
||||
if (!config.module?.rules || !config.plugins) {
|
||||
@ -115,7 +115,7 @@ const config = {
|
||||
getProvidePlugin()
|
||||
)
|
||||
|
||||
if (environment.shouldMinify) {
|
||||
if (ENVIRONMENT_CONFIG.MINIFY) {
|
||||
if (!config.optimization) {
|
||||
throw new Error('The structure of the config changed, expected config.optimization to be not-null')
|
||||
}
|
||||
@ -155,7 +155,7 @@ const config = {
|
||||
exclude: storybookPath,
|
||||
use: getCSSLoaders(
|
||||
'style-loader',
|
||||
getCSSModulesLoader({ sourceMap: !environment.shouldMinify, url: false })
|
||||
getCSSModulesLoader({ sourceMap: !ENVIRONMENT_CONFIG.MINIFY, url: false })
|
||||
),
|
||||
})
|
||||
|
||||
@ -200,11 +200,11 @@ const config = {
|
||||
|
||||
// Disable `ProgressPlugin` by default to speed up development build.
|
||||
// Can be re-enabled by setting `WEBPACK_PROGRESS_PLUGIN` env variable.
|
||||
if (!environment.isProgressPluginEnabled) {
|
||||
if (!ENVIRONMENT_CONFIG.WEBPACK_PROGRESS_PLUGIN) {
|
||||
remove(config.plugins, plugin => plugin instanceof ProgressPlugin)
|
||||
}
|
||||
|
||||
if (environment.isDLLPluginEnabled && !options.webpackStatsJson) {
|
||||
if (ENVIRONMENT_CONFIG.WEBPACK_DLL_PLUGIN && !options.webpackStatsJson) {
|
||||
config.plugins.unshift(
|
||||
new DllReferencePlugin({
|
||||
context: dllPluginConfig.context,
|
||||
@ -216,11 +216,11 @@ const config = {
|
||||
config.module.rules.push(getMonacoCSSRule(), getMonacoTTFRule())
|
||||
}
|
||||
|
||||
if (environment.isBundleAnalyzerEnabled) {
|
||||
if (ENVIRONMENT_CONFIG.WEBPACK_BUNDLE_ANALYZER) {
|
||||
config.plugins.push(getStatoscopePlugin())
|
||||
}
|
||||
|
||||
if (environment.isSpeedAnalyzerEnabled) {
|
||||
if (ENVIRONMENT_CONFIG.WEBPACK_SPEED_ANALYZER) {
|
||||
const speedMeasurePlugin = new SpeedMeasurePlugin({
|
||||
outputFormat: 'human',
|
||||
})
|
||||
|
||||
@ -4,5 +4,4 @@ out/
|
||||
.eslintrc.js
|
||||
GH2SG.bookmarklet.js
|
||||
node_modules/
|
||||
dev/
|
||||
bookmarklet/
|
||||
|
||||
@ -55,7 +55,7 @@ sg start oss-web-standalone-prod
|
||||
|
||||
Web app should be available at `https://${SOURCEGRAPH_HTTPS_DOMAIN}:${SOURCEGRAPH_HTTPS_PORT}`. Build artifacts will be served from `<rootRepoPath>/ui/assets`.
|
||||
|
||||
Note: If you are unable to use the above commands (e.g. you can't install Caddy), you can use `sg run web-standalone-http` instead. This will start a development server using only Node, and will be available at `http://localhost:${CLIENT_PROXY_DEVELOPMENT_PORT}`.
|
||||
Note: If you are unable to use the above commands (e.g. you can't install Caddy), you can use `sg run web-standalone-http` instead. This will start a development server using only Node, and will be available at `http://localhost:${SOURCEGRAPH_HTTP_PORT}`.
|
||||
|
||||
### API proxy
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import signale from 'signale'
|
||||
|
||||
import { MONACO_LANGUAGES_AND_FEATURES } from '@sourcegraph/build-config'
|
||||
|
||||
import { environmentConfig, ROOT_PATH, STATIC_ASSETS_PATH } from '../utils'
|
||||
import { ENVIRONMENT_CONFIG, ROOT_PATH, STATIC_ASSETS_PATH } from '../utils'
|
||||
|
||||
import { manifestPlugin } from './manifestPlugin'
|
||||
import { monacoPlugin } from './monacoPlugin'
|
||||
@ -13,7 +13,7 @@ import { packageResolutionPlugin } from './packageResolutionPlugin'
|
||||
import { stylePlugin } from './stylePlugin'
|
||||
import { workerPlugin } from './workerPlugin'
|
||||
|
||||
const isEnterpriseBuild = environmentConfig.ENTERPRISE
|
||||
const isEnterpriseBuild = ENVIRONMENT_CONFIG.ENTERPRISE
|
||||
|
||||
export const BUILD_OPTIONS: esbuild.BuildOptions = {
|
||||
entryPoints: {
|
||||
@ -67,7 +67,7 @@ export const BUILD_OPTIONS: esbuild.BuildOptions = {
|
||||
],
|
||||
define: {
|
||||
...Object.fromEntries(
|
||||
Object.entries({ ...environmentConfig, SOURCEGRAPH_API_URL: undefined }).map(([key, value]) => [
|
||||
Object.entries({ ...ENVIRONMENT_CONFIG, SOURCEGRAPH_API_URL: undefined }).map(([key, value]) => [
|
||||
`process.env.${key}`,
|
||||
JSON.stringify(value),
|
||||
])
|
||||
|
||||
@ -8,7 +8,7 @@ import WebpackDevServer, { ProxyConfigArrayItem } from 'webpack-dev-server'
|
||||
import { getManifest } from '../esbuild/manifestPlugin'
|
||||
import { esbuildDevelopmentServer } from '../esbuild/server'
|
||||
import {
|
||||
environmentConfig,
|
||||
ENVIRONMENT_CONFIG,
|
||||
getAPIProxySettings,
|
||||
shouldCompressResponse,
|
||||
STATIC_ASSETS_PATH,
|
||||
@ -16,22 +16,15 @@ import {
|
||||
HTTPS_WEB_SERVER_URL,
|
||||
HTTP_WEB_SERVER_URL,
|
||||
PROXY_ROUTES,
|
||||
printSuccessBanner,
|
||||
} from '../utils'
|
||||
import { getHTMLPage } from '../webpack/get-html-webpack-plugins'
|
||||
|
||||
// TODO: migrate webpack.config.js to TS to use `import` in this file.
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
||||
const webpackConfig = require('../../webpack.config') as Configuration
|
||||
// TODO: migrate webpack.config.js to TS to use `import` in this file.
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
||||
const printSuccessBanner = require('../utils/success-banner') as (lines: string[], log: () => void) => void
|
||||
|
||||
const {
|
||||
SOURCEGRAPH_API_URL,
|
||||
SOURCEGRAPH_HTTPS_PORT,
|
||||
CLIENT_PROXY_DEVELOPMENT_PORT,
|
||||
IS_HOT_RELOAD_ENABLED,
|
||||
} = environmentConfig
|
||||
const { SOURCEGRAPH_API_URL, SOURCEGRAPH_HTTPS_PORT, SOURCEGRAPH_HTTP_PORT } = ENVIRONMENT_CONFIG
|
||||
|
||||
interface DevelopmentServerInit {
|
||||
proxyRoutes: string[]
|
||||
@ -39,10 +32,7 @@ interface DevelopmentServerInit {
|
||||
}
|
||||
|
||||
async function startDevelopmentServer(): Promise<void> {
|
||||
signale.start(
|
||||
`Starting ${environmentConfig.DEV_WEB_BUILDER} dev server with environment config:\n`,
|
||||
environmentConfig
|
||||
)
|
||||
signale.start(`Starting ${ENVIRONMENT_CONFIG.DEV_WEB_BUILDER} dev server.`, ENVIRONMENT_CONFIG)
|
||||
|
||||
if (!SOURCEGRAPH_API_URL) {
|
||||
throw new Error('development.server.ts only supports *web-standalone* usage')
|
||||
@ -55,7 +45,7 @@ async function startDevelopmentServer(): Promise<void> {
|
||||
}),
|
||||
}
|
||||
|
||||
switch (environmentConfig.DEV_WEB_BUILDER) {
|
||||
switch (ENVIRONMENT_CONFIG.DEV_WEB_BUILDER) {
|
||||
case 'webpack':
|
||||
await startWebpackDevelopmentServer(init)
|
||||
break
|
||||
@ -79,11 +69,11 @@ async function startWebpackDevelopmentServer({
|
||||
// react-refresh plugin triggers page reload if needed.
|
||||
liveReload: false,
|
||||
allowedHosts: 'all',
|
||||
hot: IS_HOT_RELOAD_ENABLED,
|
||||
hot: true,
|
||||
historyApiFallback: {
|
||||
disableDotRule: true,
|
||||
},
|
||||
port: CLIENT_PROXY_DEVELOPMENT_PORT,
|
||||
port: SOURCEGRAPH_HTTP_PORT,
|
||||
client: {
|
||||
overlay: false,
|
||||
webSocketTransport: 'ws',
|
||||
|
||||
@ -8,21 +8,21 @@ import signale from 'signale'
|
||||
import {
|
||||
PROXY_ROUTES,
|
||||
getAPIProxySettings,
|
||||
environmentConfig,
|
||||
ENVIRONMENT_CONFIG,
|
||||
STATIC_ASSETS_PATH,
|
||||
STATIC_INDEX_PATH,
|
||||
HTTP_WEB_SERVER_URL,
|
||||
HTTPS_WEB_SERVER_URL,
|
||||
} from '../utils'
|
||||
|
||||
const { SOURCEGRAPH_API_URL, CLIENT_PROXY_DEVELOPMENT_PORT } = environmentConfig
|
||||
const { SOURCEGRAPH_API_URL, SOURCEGRAPH_HTTP_PORT } = ENVIRONMENT_CONFIG
|
||||
|
||||
function startProductionServer(): void {
|
||||
if (!SOURCEGRAPH_API_URL) {
|
||||
throw new Error('production.server.ts only supports *web-standalone* usage')
|
||||
}
|
||||
|
||||
signale.await('Production server', { ...environmentConfig })
|
||||
signale.await('Starting production server', ENVIRONMENT_CONFIG)
|
||||
|
||||
const app = express()
|
||||
|
||||
@ -30,7 +30,6 @@ function startProductionServer(): void {
|
||||
app.use(historyApiFallback() as RequestHandler)
|
||||
|
||||
// Serve build artifacts.
|
||||
|
||||
app.use(
|
||||
'/.assets',
|
||||
expressStaticGzip(STATIC_ASSETS_PATH, {
|
||||
@ -53,7 +52,7 @@ function startProductionServer(): void {
|
||||
// Redirect remaining routes to index.html
|
||||
app.get('/*', (_request, response) => response.sendFile(STATIC_INDEX_PATH))
|
||||
|
||||
app.listen(CLIENT_PROXY_DEVELOPMENT_PORT, () => {
|
||||
app.listen(SOURCEGRAPH_HTTP_PORT, () => {
|
||||
signale.info(`Production HTTP server is ready at ${chalk.blue.bold(HTTP_WEB_SERVER_URL)}`)
|
||||
signale.success(`Production HTTPS server is ready at ${chalk.blue.bold(HTTPS_WEB_SERVER_URL)}`)
|
||||
})
|
||||
|
||||
@ -4,14 +4,14 @@ export const ROOT_PATH = path.resolve(__dirname, '../../../../')
|
||||
export const STATIC_ASSETS_PATH = path.resolve(ROOT_PATH, 'ui/assets')
|
||||
export const STATIC_INDEX_PATH = path.resolve(STATIC_ASSETS_PATH, 'index.html')
|
||||
export const STATIC_ASSETS_URL = '/.assets/'
|
||||
export const DEV_SERVER_LISTEN_ADDR = { host: 'localhost', port: 3080 }
|
||||
export const DEV_SERVER_PROXY_TARGET_ADDR = { host: 'localhost', port: 3081 }
|
||||
export const DEV_SERVER_LISTEN_ADDR = { host: 'localhost', port: 3080 } as const
|
||||
export const DEV_SERVER_PROXY_TARGET_ADDR = { host: 'localhost', port: 3081 } as const
|
||||
export const DEFAULT_SITE_CONFIG_PATH = path.resolve(ROOT_PATH, '../dev-private/enterprise/dev/site-config.json')
|
||||
|
||||
// TODO: share with gulpfile.js
|
||||
export const WEBPACK_STATS_OPTIONS = {
|
||||
all: false,
|
||||
timings: true,
|
||||
errors: true,
|
||||
warnings: true,
|
||||
colors: true,
|
||||
}
|
||||
} as const
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { SourcegraphContext } from '../../src/jscontext'
|
||||
|
||||
import { environmentConfig } from './environment-config'
|
||||
import { ENVIRONMENT_CONFIG } from './environment-config'
|
||||
import { getSiteConfig } from './get-site-config'
|
||||
|
||||
// TODO: share with `client/web/src/integration/jscontext` which is not included into `tsconfig.json` now.
|
||||
@ -50,7 +50,7 @@ export const createJsContext = ({ sourcegraphBaseUrl }: { sourcegraphBaseUrl: st
|
||||
},
|
||||
siteID: 'TestSiteID',
|
||||
siteGQLID: 'TestGQLSiteID',
|
||||
sourcegraphDotComMode: environmentConfig.SOURCEGRAPHDOTCOM_MODE,
|
||||
sourcegraphDotComMode: ENVIRONMENT_CONFIG.SOURCEGRAPHDOTCOM_MODE,
|
||||
githubAppCloudSlug: 'TestApp',
|
||||
githubAppCloudClientID: 'TestClientID',
|
||||
userAgentIsBot: false,
|
||||
|
||||
@ -1,30 +1,67 @@
|
||||
import path from 'path'
|
||||
/**
|
||||
* Unpack all `process.env.*` variables used during the build
|
||||
* time of the web application in this module to keep one source of truth.
|
||||
*/
|
||||
import { getEnvironmentBoolean } from '@sourcegraph/build-config'
|
||||
|
||||
import { ROOT_PATH } from './constants'
|
||||
import { DEFAULT_SITE_CONFIG_PATH } from './constants'
|
||||
|
||||
const DEFAULT_SITE_CONFIG_PATH = path.resolve(ROOT_PATH, '../dev-private/enterprise/dev/site-config.json')
|
||||
type WEB_BUILDER = 'esbuild' | 'webpack'
|
||||
|
||||
export const environmentConfig = {
|
||||
export const ENVIRONMENT_CONFIG = {
|
||||
/**
|
||||
* ----------------------------------------
|
||||
* Build configuration.
|
||||
* ----------------------------------------
|
||||
*/
|
||||
NODE_ENV: process.env.NODE_ENV || 'development',
|
||||
// Determines if build is running on CI.
|
||||
CI: getEnvironmentBoolean('CI'),
|
||||
// Enables `embed` Webpack entry point.
|
||||
EMBED_DEVELOPMENT: getEnvironmentBoolean('EMBED_DEVELOPMENT'),
|
||||
|
||||
// Should Webpack serve `index.html` with `HTMLWebpackPlugin`.
|
||||
WEBPACK_SERVE_INDEX: getEnvironmentBoolean('WEBPACK_SERVE_INDEX'),
|
||||
// Enables `StatoscopeWebpackPlugin` that allows to analyze application bundle.
|
||||
WEBPACK_BUNDLE_ANALYZER: getEnvironmentBoolean('WEBPACK_BUNDLE_ANALYZER'),
|
||||
|
||||
// Allow overriding default Webpack naming behavior for debugging
|
||||
WEBPACK_USE_NAMED_CHUNKS: getEnvironmentBoolean('WEBPACK_USE_NAMED_CHUNKS'),
|
||||
|
||||
// Webpack is the default web build tool, and esbuild is an experimental option (see
|
||||
// https://docs.sourcegraph.com/dev/background-information/web/build#esbuild).
|
||||
DEV_WEB_BUILDER: (process.env.DEV_WEB_BUILDER === 'esbuild' ? 'esbuild' : 'webpack') as WEB_BUILDER,
|
||||
|
||||
/**
|
||||
* ----------------------------------------
|
||||
* Application features configuration.
|
||||
* ----------------------------------------
|
||||
*/
|
||||
ENTERPRISE: getEnvironmentBoolean('ENTERPRISE'),
|
||||
SOURCEGRAPHDOTCOM_MODE: getEnvironmentBoolean('SOURCEGRAPHDOTCOM_MODE'),
|
||||
|
||||
// Is reporting to Datadog/Sentry enabled.
|
||||
ENABLE_MONITORING: getEnvironmentBoolean('ENABLE_MONITORING'),
|
||||
|
||||
// Is event logging with `TelemetryService` enabled.
|
||||
ENABLE_TELEMETRY: getEnvironmentBoolean('ENABLE_TELEMETRY'),
|
||||
|
||||
/**
|
||||
* ----------------------------------------
|
||||
* Local environment configuration.
|
||||
* ----------------------------------------
|
||||
*/
|
||||
SOURCEGRAPH_API_URL: process.env.SOURCEGRAPH_API_URL,
|
||||
SOURCEGRAPH_HTTPS_DOMAIN: process.env.SOURCEGRAPH_HTTPS_DOMAIN || 'sourcegraph.test',
|
||||
SOURCEGRAPH_HTTPS_PORT: Number(process.env.SOURCEGRAPH_HTTPS_PORT) || 3443,
|
||||
SOURCEGRAPHDOTCOM_MODE: process.env.SOURCEGRAPHDOTCOM_MODE === 'true',
|
||||
CLIENT_PROXY_DEVELOPMENT_PORT: Number(process.env.CLIENT_PROXY_DEVELOPMENT_PORT) || 3080,
|
||||
WEBPACK_SERVE_INDEX: process.env.WEBPACK_SERVE_INDEX === 'true',
|
||||
SOURCEGRAPH_HTTP_PORT: Number(process.env.SOURCEGRAPH_HTTP_PORT) || 3080,
|
||||
SITE_CONFIG_PATH: process.env.SITE_CONFIG_PATH || DEFAULT_SITE_CONFIG_PATH,
|
||||
ENTERPRISE: Boolean(process.env.ENTERPRISE),
|
||||
|
||||
// Webpack is the default web build tool, and esbuild is an experimental option (see
|
||||
// https://docs.sourcegraph.com/dev/background-information/web/build#esbuild).
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
DEV_WEB_BUILDER: (process.env.DEV_WEB_BUILDER === 'esbuild' ? 'esbuild' : 'webpack') as 'esbuild' | 'webpack',
|
||||
|
||||
// TODO: do we use process.env.NO_HOT anywhere?
|
||||
IS_HOT_RELOAD_ENABLED: process.env.NO_HOT !== 'true',
|
||||
}
|
||||
|
||||
const { SOURCEGRAPH_HTTPS_PORT, SOURCEGRAPH_HTTPS_DOMAIN, CLIENT_PROXY_DEVELOPMENT_PORT } = environmentConfig
|
||||
const { NODE_ENV, SOURCEGRAPH_HTTPS_DOMAIN, SOURCEGRAPH_HTTPS_PORT, SOURCEGRAPH_HTTP_PORT } = ENVIRONMENT_CONFIG
|
||||
|
||||
export const IS_DEVELOPMENT = NODE_ENV === 'development'
|
||||
export const IS_PRODUCTION = NODE_ENV === 'production'
|
||||
|
||||
export const HTTPS_WEB_SERVER_URL = `https://${SOURCEGRAPH_HTTPS_DOMAIN}:${SOURCEGRAPH_HTTPS_PORT}`
|
||||
export const HTTP_WEB_SERVER_URL = `http://localhost:${CLIENT_PROXY_DEVELOPMENT_PORT}`
|
||||
export const HTTP_WEB_SERVER_URL = `http://localhost:${SOURCEGRAPH_HTTP_PORT}`
|
||||
|
||||
@ -5,9 +5,9 @@ import lodash from 'lodash'
|
||||
|
||||
import { SourcegraphContext } from '../../src/jscontext'
|
||||
|
||||
import { environmentConfig } from './environment-config'
|
||||
import { ENVIRONMENT_CONFIG } from './environment-config'
|
||||
|
||||
const { SITE_CONFIG_PATH } = environmentConfig
|
||||
const { SITE_CONFIG_PATH } = ENVIRONMENT_CONFIG
|
||||
|
||||
// Get site-config from `SITE_CONFIG_PATH` as an object with camel cased keys.
|
||||
export const getSiteConfig = (): Partial<SourcegraphContext> => {
|
||||
|
||||
@ -3,3 +3,4 @@ export * from './create-js-context'
|
||||
export * from './environment-config'
|
||||
export * from './get-api-proxy-settings'
|
||||
export * from './should-compress-response'
|
||||
export * from './success-banner'
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return, @typescript-eslint/restrict-plus-operands, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
|
||||
const chalk = require('chalk')
|
||||
|
||||
module.exports = function printSuccessBanner(lines, log = console.log.bind(console)) {
|
||||
const lineLength = getLineLength(lines)
|
||||
const banner = '='.repeat(lineLength)
|
||||
const emptyLine = ' '.repeat(lineLength)
|
||||
|
||||
log(chalk.bgGreenBright.black(banner))
|
||||
log(chalk.bgGreenBright.black(emptyLine))
|
||||
for (const line of lines) {
|
||||
log(chalk.bgGreenBright.black(padLine(line, lineLength)))
|
||||
log(chalk.bgGreenBright.black(emptyLine))
|
||||
}
|
||||
log(chalk.bgGreenBright.black(banner))
|
||||
}
|
||||
|
||||
function padLine(content, length) {
|
||||
const spaceRequired = length - content.length
|
||||
const half = spaceRequired / 2
|
||||
let line = `${' '.repeat(half)}${content}${' '.repeat(half)}`
|
||||
if (line.length < length) {
|
||||
line += ' '
|
||||
}
|
||||
return line
|
||||
}
|
||||
|
||||
function getLineLength(lines) {
|
||||
const longestLine = lines.reduce((accumulator, current) => {
|
||||
if (accumulator < current.length) {
|
||||
return current.length
|
||||
}
|
||||
return accumulator
|
||||
}, 0)
|
||||
|
||||
return Math.max(40, longestLine + 10)
|
||||
}
|
||||
36
client/web/dev/utils/success-banner.ts
Normal file
36
client/web/dev/utils/success-banner.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import chalk from 'chalk'
|
||||
|
||||
export function printSuccessBanner(lines: string[], log = console.log.bind(console)): void {
|
||||
const lineLength = getLineLength(lines)
|
||||
const banner = '='.repeat(lineLength)
|
||||
const emptyLine = ' '.repeat(lineLength)
|
||||
|
||||
log(chalk.bgGreenBright.black(banner))
|
||||
log(chalk.bgGreenBright.black(emptyLine))
|
||||
for (const line of lines) {
|
||||
log(chalk.bgGreenBright.black(padLine(line, lineLength)))
|
||||
log(chalk.bgGreenBright.black(emptyLine))
|
||||
}
|
||||
log(chalk.bgGreenBright.black(banner))
|
||||
}
|
||||
|
||||
function padLine(content: string, length: number): string {
|
||||
const spaceRequired = length - content.length
|
||||
const half = spaceRequired / 2
|
||||
let line = `${' '.repeat(half)}${content}${' '.repeat(half)}`
|
||||
if (line.length < length) {
|
||||
line += ' '
|
||||
}
|
||||
return line
|
||||
}
|
||||
|
||||
function getLineLength(lines: string[]): number {
|
||||
const longestLine = lines.reduce((accumulator, current) => {
|
||||
if (accumulator < current.length) {
|
||||
return current.length
|
||||
}
|
||||
return accumulator
|
||||
}, 0)
|
||||
|
||||
return Math.max(40, longestLine + 10)
|
||||
}
|
||||
@ -2,11 +2,12 @@ import path from 'path'
|
||||
|
||||
import HtmlWebpackHarddiskPlugin from 'html-webpack-harddisk-plugin'
|
||||
import HtmlWebpackPlugin, { TemplateParameter, Options } from 'html-webpack-plugin'
|
||||
import signale from 'signale'
|
||||
import { WebpackPluginInstance } from 'webpack'
|
||||
|
||||
import { createJsContext, environmentConfig, STATIC_ASSETS_PATH } from '../utils'
|
||||
import { createJsContext, ENVIRONMENT_CONFIG, STATIC_ASSETS_PATH } from '../utils'
|
||||
|
||||
const { SOURCEGRAPH_HTTPS_PORT, NODE_ENV } = environmentConfig
|
||||
const { SOURCEGRAPH_HTTPS_PORT, NODE_ENV } = ENVIRONMENT_CONFIG
|
||||
|
||||
export interface WebpackManifest {
|
||||
/** Main app entry JS bundle */
|
||||
@ -45,7 +46,7 @@ export const getHTMLPage = ({
|
||||
<meta name="color-scheme" content="light dark"/>
|
||||
${cssBundle ? `<link rel="stylesheet" href="${cssBundle}">` : ''}
|
||||
${
|
||||
environmentConfig.SOURCEGRAPHDOTCOM_MODE
|
||||
ENVIRONMENT_CONFIG.SOURCEGRAPHDOTCOM_MODE
|
||||
? '<script src="https://js.sentry-cdn.com/ae2f74442b154faf90b5ff0f7cd1c618.min.js" crossorigin="anonymous"></script>'
|
||||
: ''
|
||||
}
|
||||
@ -77,6 +78,8 @@ const getBundleFromPath = (files: string[], filePrefix: string): string | undefi
|
||||
files.find(file => file.startsWith(`/.assets/${filePrefix}`))
|
||||
|
||||
export const getHTMLWebpackPlugins = (): WebpackPluginInstance[] => {
|
||||
signale.info('Serving `index.html` with `HTMLWebpackPlugin`.')
|
||||
|
||||
const htmlWebpackPlugin = new HtmlWebpackPlugin({
|
||||
// `TemplateParameter` can be mutated. We need to tell TS that we didn't touch it.
|
||||
templateContent: (({ htmlWebpackPlugin }: TemplateParameter): string => {
|
||||
|
||||
@ -7,7 +7,6 @@ require('ts-node').register({
|
||||
})
|
||||
|
||||
const compression = require('compression')
|
||||
const log = require('fancy-log')
|
||||
const gulp = require('gulp')
|
||||
const { createProxyMiddleware } = require('http-proxy-middleware')
|
||||
const signale = require('signale')
|
||||
@ -30,28 +29,34 @@ const {
|
||||
|
||||
const { build: buildEsbuild } = require('./dev/esbuild/build')
|
||||
const { esbuildDevelopmentServer } = require('./dev/esbuild/server')
|
||||
const { DEV_SERVER_LISTEN_ADDR, DEV_SERVER_PROXY_TARGET_ADDR, shouldCompressResponse } = require('./dev/utils')
|
||||
const { DEV_WEB_BUILDER } = require('./dev/utils/environment-config').environmentConfig
|
||||
const printSuccessBanner = require('./dev/utils/success-banner')
|
||||
const {
|
||||
ENVIRONMENT_CONFIG,
|
||||
HTTPS_WEB_SERVER_URL,
|
||||
WEBPACK_STATS_OPTIONS,
|
||||
DEV_SERVER_LISTEN_ADDR,
|
||||
DEV_SERVER_PROXY_TARGET_ADDR,
|
||||
shouldCompressResponse,
|
||||
printSuccessBanner,
|
||||
} = require('./dev/utils')
|
||||
const webpackConfig = require('./webpack.config')
|
||||
|
||||
const WEBPACK_STATS_OPTIONS = {
|
||||
all: false,
|
||||
timings: true,
|
||||
errors: true,
|
||||
warnings: true,
|
||||
colors: true,
|
||||
}
|
||||
const { DEV_WEB_BUILDER, SOURCEGRAPH_HTTPS_DOMAIN, SOURCEGRAPH_HTTPS_PORT } = ENVIRONMENT_CONFIG
|
||||
|
||||
/**
|
||||
* @param {import('webpack').Stats} stats
|
||||
*/
|
||||
const logWebpackStats = stats => {
|
||||
log(stats.toString(WEBPACK_STATS_OPTIONS))
|
||||
signale.info(stats.toString(WEBPACK_STATS_OPTIONS))
|
||||
}
|
||||
|
||||
function createWebApplicationCompiler() {
|
||||
signale.info('Building web application with the environment config', ENVIRONMENT_CONFIG)
|
||||
|
||||
return createWebpackCompiler(webpackConfig)
|
||||
}
|
||||
|
||||
async function webpack() {
|
||||
const compiler = createWebpackCompiler(webpackConfig)
|
||||
const compiler = createWebApplicationCompiler()
|
||||
/** @type {import('webpack').Stats} */
|
||||
const stats = await new Promise((resolve, reject) => {
|
||||
compiler.run((error, stats) => (error ? reject(error) : resolve(stats)))
|
||||
@ -68,24 +73,21 @@ const webBuild = DEV_WEB_BUILDER === 'webpack' ? webpack : buildEsbuild
|
||||
* Watch files and update the webpack bundle on disk without starting a dev server.
|
||||
*/
|
||||
async function watchWebpack() {
|
||||
const compiler = createWebpackCompiler(webpackConfig)
|
||||
compiler.hooks.watchRun.tap('Notify', () => log('Webpack compiling...'))
|
||||
const compiler = createWebApplicationCompiler()
|
||||
compiler.hooks.watchRun.tap('Notify', () => signale.info('Webpack compiling...'))
|
||||
await new Promise(() => {
|
||||
compiler.watch({ aggregateTimeout: 300 }, (error, stats) => {
|
||||
logWebpackStats(stats)
|
||||
if (error || stats.hasErrors()) {
|
||||
log.error('Webpack compilation error')
|
||||
signale.error('Webpack compilation error')
|
||||
} else {
|
||||
log('Webpack compilation done')
|
||||
signale.info('Webpack compilation done')
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function webpackDevelopmentServer() {
|
||||
const sockHost = process.env.SOURCEGRAPH_HTTPS_DOMAIN || 'sourcegraph.test'
|
||||
const sockPort = Number(process.env.SOURCEGRAPH_HTTPS_PORT || 3443)
|
||||
|
||||
/** @type {import('webpack-dev-server').ProxyConfigMap } */
|
||||
const proxyConfig = {
|
||||
'/': {
|
||||
@ -105,7 +107,7 @@ async function webpackDevelopmentServer() {
|
||||
const options = {
|
||||
// react-refresh plugin triggers page reload if needed.
|
||||
liveReload: false,
|
||||
hot: !process.env.NO_HOT,
|
||||
hot: true,
|
||||
host: DEV_SERVER_LISTEN_ADDR.host,
|
||||
port: DEV_SERVER_LISTEN_ADDR.port,
|
||||
// Disable default DevServer compression. We need more fine grained compression to support streaming search.
|
||||
@ -119,8 +121,8 @@ async function webpackDevelopmentServer() {
|
||||
webSocketTransport: 'ws',
|
||||
logging: 'verbose',
|
||||
webSocketURL: {
|
||||
hostname: sockHost,
|
||||
port: sockPort,
|
||||
hostname: SOURCEGRAPH_HTTPS_DOMAIN,
|
||||
port: SOURCEGRAPH_HTTPS_PORT,
|
||||
protocol: 'wss',
|
||||
},
|
||||
},
|
||||
@ -138,7 +140,7 @@ async function webpackDevelopmentServer() {
|
||||
webpackConfig.plugins.push(new DevServerPlugin(options))
|
||||
}
|
||||
|
||||
const compiler = createWebpackCompiler(webpackConfig)
|
||||
const compiler = createWebApplicationCompiler()
|
||||
let compilationDoneOnce = false
|
||||
compiler.hooks.done.tap('Print external URL', stats => {
|
||||
stats = stats.toJson()
|
||||
@ -151,7 +153,7 @@ async function webpackDevelopmentServer() {
|
||||
}
|
||||
compilationDoneOnce = true
|
||||
|
||||
printSuccessBanner(['✱ Sourcegraph is really ready now!', `Click here: https://${sockHost}:${sockPort}`])
|
||||
printSuccessBanner(['✱ Sourcegraph is really ready now!', `Click here: ${HTTPS_WEB_SERVER_URL}`])
|
||||
})
|
||||
|
||||
const server = new WebpackDevServer(options, compiler)
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
"lint:js": "NODE_OPTIONS=\"--max_old_space_size=16192\" eslint --cache '**/*.[tj]s?(x)'",
|
||||
"lint:css": "stylelint 'src/**/*.scss' --quiet",
|
||||
"browserslist": "browserslist",
|
||||
"analyze-bundle": "WEBPACK_USE_NAMED_CHUNKS=true NODE_ENV=production ENTERPRISE=1 WEBPACK_ANALYZER=1 yarn build",
|
||||
"analyze-bundle": "WEBPACK_USE_NAMED_CHUNKS=true NODE_ENV=production ENTERPRISE=1 WEBPACK_BUNDLE_ANALYZER=1 yarn build",
|
||||
"bundlesize": "bundlesize --config=./bundlesize.config.js"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { AbortError } from '@sourcegraph/common'
|
||||
import { HTTPStatusError } from '@sourcegraph/http-client'
|
||||
import { AbortError } from '@sourcegraph/shared/src/api/util'
|
||||
|
||||
import { shouldErrorBeReported } from './shouldErrorBeReported'
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ export const COHORT_ID_KEY = 'sourcegraphCohortId'
|
||||
export const FIRST_SOURCE_URL_KEY = 'sourcegraphSourceUrl'
|
||||
export const LAST_SOURCE_URL_KEY = 'sourcegraphRecentSourceUrl'
|
||||
export const DEVICE_ID_KEY = 'sourcegraphDeviceId'
|
||||
const isTelemetryDisabled = process.env.DISABLE_TELEMETRY
|
||||
const isTelemetryEnabled = process.env.ENABLE_TELEMETRY || process.env.NODE_ENV === 'production'
|
||||
|
||||
export class EventLogger implements TelemetryService {
|
||||
private hasStrippedQueryParameters = false
|
||||
@ -57,7 +57,7 @@ export class EventLogger implements TelemetryService {
|
||||
|
||||
private logViewEventInternal(eventName: string, eventProperties?: any, logAsActiveUser = true): void {
|
||||
const props = pageViewQueryParameters(window.location.href)
|
||||
if (!isTelemetryDisabled) {
|
||||
if (isTelemetryEnabled) {
|
||||
serverAdmin.trackPageView(eventName, logAsActiveUser, eventProperties)
|
||||
}
|
||||
this.logToConsole(eventName, props)
|
||||
@ -114,7 +114,7 @@ export class EventLogger implements TelemetryService {
|
||||
if (window.context?.userAgentIsBot || !eventLabel) {
|
||||
return
|
||||
}
|
||||
if (!isTelemetryDisabled) {
|
||||
if (isTelemetryEnabled) {
|
||||
serverAdmin.trackAction(eventLabel, eventProperties, publicArgument)
|
||||
}
|
||||
this.logToConsole(eventLabel, eventProperties, publicArgument)
|
||||
|
||||
@ -5,7 +5,7 @@ const path = require('path')
|
||||
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
|
||||
const CompressionPlugin = require('compression-webpack-plugin')
|
||||
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
|
||||
const logger = require('gulplog')
|
||||
const mapValues = require('lodash/mapValues')
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
const webpack = require('webpack')
|
||||
const { WebpackManifestPlugin } = require('webpack-manifest-plugin')
|
||||
@ -23,85 +23,55 @@ const {
|
||||
getMonacoTTFRule,
|
||||
getBasicCSSLoader,
|
||||
getStatoscopePlugin,
|
||||
STATOSCOPE_STATS,
|
||||
} = require('@sourcegraph/build-config')
|
||||
|
||||
const { IS_PRODUCTION, IS_DEVELOPMENT, ENVIRONMENT_CONFIG } = require('./dev/utils')
|
||||
const { getHTMLWebpackPlugins } = require('./dev/webpack/get-html-webpack-plugins')
|
||||
const { isHotReloadEnabled } = require('./src/integration/environment')
|
||||
|
||||
const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development'
|
||||
logger.info('Using mode', mode)
|
||||
const {
|
||||
NODE_ENV,
|
||||
CI: IS_CI,
|
||||
ENTERPRISE,
|
||||
EMBED_DEVELOPMENT,
|
||||
ENABLE_TELEMETRY,
|
||||
ENABLE_MONITORING,
|
||||
SOURCEGRAPH_API_URL,
|
||||
WEBPACK_SERVE_INDEX,
|
||||
WEBPACK_BUNDLE_ANALYZER,
|
||||
WEBPACK_USE_NAMED_CHUNKS,
|
||||
} = ENVIRONMENT_CONFIG
|
||||
|
||||
const isDevelopment = mode === 'development'
|
||||
const isProduction = mode === 'production'
|
||||
const isCI = process.env.CI === 'true'
|
||||
const isCacheEnabled = isDevelopment && !isCI
|
||||
const isEmbedDevelopment = isDevelopment && process.env.EMBED_DEVELOPMENT === 'true'
|
||||
const IS_PERSISTENT_CACHE_ENABLED = IS_DEVELOPMENT && !IS_CI
|
||||
const IS_EMBED_ENTRY_POINT_ENABLED = ENTERPRISE && (IS_PRODUCTION || (IS_DEVELOPMENT && EMBED_DEVELOPMENT))
|
||||
|
||||
/** Allow overriding default Webpack naming behavior for debugging */
|
||||
const useNamedChunks = process.env.WEBPACK_USE_NAMED_CHUNKS === 'true'
|
||||
|
||||
const devtool = isProduction ? 'source-map' : 'eval-cheap-module-source-map'
|
||||
|
||||
const shouldServeIndexHTML = process.env.WEBPACK_SERVE_INDEX === 'true'
|
||||
if (shouldServeIndexHTML) {
|
||||
logger.info('Serving index.html with HTMLWebpackPlugin')
|
||||
}
|
||||
const webServerEnvironmentVariables = {
|
||||
WEBPACK_SERVE_INDEX: JSON.stringify(process.env.WEBPACK_SERVE_INDEX),
|
||||
SOURCEGRAPH_API_URL: JSON.stringify(process.env.SOURCEGRAPH_API_URL),
|
||||
}
|
||||
|
||||
const shouldAnalyze = process.env.WEBPACK_ANALYZER === '1'
|
||||
|
||||
const STATOSCOPE_STATS = {
|
||||
all: false, // disable all the stats
|
||||
hash: true, // compilation hash
|
||||
entrypoints: true,
|
||||
chunks: true,
|
||||
chunkModules: true, // modules
|
||||
reasons: true, // modules reasons
|
||||
ids: true, // IDs of modules and chunks (webpack 5)
|
||||
dependentModules: true, // dependent modules of chunks (webpack 5)
|
||||
chunkRelations: true, // chunk parents, children and siblings (webpack 5)
|
||||
cachedAssets: true, // information about the cached assets (webpack 5)
|
||||
|
||||
nestedModules: true, // concatenated modules
|
||||
usedExports: true,
|
||||
providedExports: true, // provided imports
|
||||
assets: true,
|
||||
chunkOrigins: true, // chunks origins stats (to find out which modules require a chunk)
|
||||
version: true, // webpack version
|
||||
builtAt: true, // build at time
|
||||
timings: true, // modules timing information
|
||||
performance: true, // info about oversized assets
|
||||
}
|
||||
|
||||
if (shouldAnalyze) {
|
||||
logger.info('Running bundle analyzer')
|
||||
const RUNTIME_ENV_VARIABLES = {
|
||||
NODE_ENV,
|
||||
ENABLE_TELEMETRY,
|
||||
ENABLE_MONITORING,
|
||||
...(WEBPACK_SERVE_INDEX && { SOURCEGRAPH_API_URL }),
|
||||
}
|
||||
|
||||
const hotLoadablePaths = ['branded', 'shared', 'web', 'wildcard'].map(workspace =>
|
||||
path.resolve(ROOT_PATH, 'client', workspace, 'src')
|
||||
)
|
||||
|
||||
const isEnterpriseBuild = process.env.ENTERPRISE && Boolean(JSON.parse(process.env.ENTERPRISE))
|
||||
const isEmbedEntrypointEnabled = isEnterpriseBuild && (isProduction || isEmbedDevelopment)
|
||||
const enterpriseDirectory = path.resolve(__dirname, 'src', 'enterprise')
|
||||
|
||||
const styleLoader = isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader
|
||||
const styleLoader = IS_DEVELOPMENT ? 'style-loader' : MiniCssExtractPlugin.loader
|
||||
|
||||
const extensionHostWorker = /main\.worker\.ts$/
|
||||
|
||||
/** @type {import('webpack').Configuration} */
|
||||
const config = {
|
||||
context: __dirname, // needed when running `gulp webpackDevServer` from the root dir
|
||||
mode,
|
||||
stats: shouldAnalyze
|
||||
mode: IS_PRODUCTION ? 'production' : 'development',
|
||||
stats: WEBPACK_BUNDLE_ANALYZER
|
||||
? STATOSCOPE_STATS
|
||||
: {
|
||||
// Minimize logging in case if Webpack is used along with multiple other services.
|
||||
// Use `normal` output preset in case of running standalone web server.
|
||||
preset: shouldServeIndexHTML || isProduction ? 'normal' : 'errors-warnings',
|
||||
preset: WEBPACK_SERVE_INDEX || IS_PRODUCTION ? 'normal' : 'errors-warnings',
|
||||
errorDetails: true,
|
||||
timings: true,
|
||||
},
|
||||
@ -111,9 +81,11 @@ const config = {
|
||||
},
|
||||
target: 'browserslist',
|
||||
// Use cache only in `development` mode to speed up production build.
|
||||
cache: isCacheEnabled && getCacheConfig({ invalidateCacheFiles: [path.resolve(__dirname, 'babel.config.js')] }),
|
||||
cache:
|
||||
IS_PERSISTENT_CACHE_ENABLED &&
|
||||
getCacheConfig({ invalidateCacheFiles: [path.resolve(__dirname, 'babel.config.js')] }),
|
||||
optimization: {
|
||||
minimize: isProduction,
|
||||
minimize: IS_PRODUCTION,
|
||||
minimizer: [getTerserPlugin(), new CssMinimizerWebpackPlugin()],
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
@ -124,7 +96,7 @@ const config = {
|
||||
},
|
||||
},
|
||||
},
|
||||
...(isDevelopment && {
|
||||
...(IS_DEVELOPMENT && {
|
||||
// Running multiple entries on a single page that do not share a runtime chunk from the same compilation is not supported.
|
||||
// https://github.com/webpack/webpack-dev-server/issues/2792#issuecomment-808328432
|
||||
runtimeChunk: isHotReloadEnabled ? 'single' : false,
|
||||
@ -136,51 +108,48 @@ const config = {
|
||||
entry: {
|
||||
// Enterprise vs. OSS builds use different entrypoints. The enterprise entrypoint imports a
|
||||
// strict superset of the OSS entrypoint.
|
||||
app: isEnterpriseBuild ? path.join(enterpriseDirectory, 'main.tsx') : path.join(__dirname, 'src', 'main.tsx'),
|
||||
app: ENTERPRISE ? path.join(enterpriseDirectory, 'main.tsx') : path.join(__dirname, 'src', 'main.tsx'),
|
||||
// Embedding entrypoint. It uses a small subset of the main webapp intended to be embedded into
|
||||
// iframes on 3rd party sites. Added only in production enterprise builds or if embed development is enabled.
|
||||
...(isEmbedEntrypointEnabled && { embed: path.join(enterpriseDirectory, 'embed', 'main.tsx') }),
|
||||
...(IS_EMBED_ENTRY_POINT_ENABLED && { embed: path.join(enterpriseDirectory, 'embed', 'main.tsx') }),
|
||||
},
|
||||
output: {
|
||||
path: path.join(ROOT_PATH, 'ui', 'assets'),
|
||||
// Do not [hash] for development -- see https://github.com/webpack/webpack-dev-server/issues/377#issuecomment-241258405
|
||||
// Note: [name] will vary depending on the Webpack chunk. If specified, it will use a provided chunk name, otherwise it will fallback to a deterministic id.
|
||||
filename:
|
||||
mode === 'production' && !useNamedChunks ? 'scripts/[name].[contenthash].bundle.js' : 'scripts/[name].bundle.js',
|
||||
IS_PRODUCTION && !WEBPACK_USE_NAMED_CHUNKS
|
||||
? 'scripts/[name].[contenthash].bundle.js'
|
||||
: 'scripts/[name].bundle.js',
|
||||
chunkFilename:
|
||||
mode === 'production' && !useNamedChunks ? 'scripts/[name]-[contenthash].chunk.js' : 'scripts/[name].chunk.js',
|
||||
IS_PRODUCTION && !WEBPACK_USE_NAMED_CHUNKS ? 'scripts/[name]-[contenthash].chunk.js' : 'scripts/[name].chunk.js',
|
||||
publicPath: '/.assets/',
|
||||
globalObject: 'self',
|
||||
pathinfo: false,
|
||||
},
|
||||
devtool,
|
||||
devtool: IS_PRODUCTION ? 'source-map' : 'eval-cheap-module-source-map',
|
||||
plugins: [
|
||||
// Needed for React
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify(mode),
|
||||
DISABLE_TELEMETRY: process.env.DISABLE_TELEMETRY,
|
||||
...(shouldServeIndexHTML && webServerEnvironmentVariables),
|
||||
},
|
||||
'process.env': mapValues(RUNTIME_ENV_VARIABLES, JSON.stringify),
|
||||
}),
|
||||
getProvidePlugin(),
|
||||
new MiniCssExtractPlugin({
|
||||
// Do not [hash] for development -- see https://github.com/webpack/webpack-dev-server/issues/377#issuecomment-241258405
|
||||
filename: mode === 'production' ? 'styles/[name].[contenthash].bundle.css' : 'styles/[name].bundle.css',
|
||||
filename: IS_PRODUCTION ? 'styles/[name].[contenthash].bundle.css' : 'styles/[name].bundle.css',
|
||||
}),
|
||||
getMonacoWebpackPlugin(),
|
||||
!shouldServeIndexHTML &&
|
||||
!WEBPACK_SERVE_INDEX &&
|
||||
new WebpackManifestPlugin({
|
||||
writeToFileEmit: true,
|
||||
fileName: 'webpack.manifest.json',
|
||||
// Only output files that are required to run the application.
|
||||
filter: ({ isInitial, name }) => isInitial || name?.includes('react'),
|
||||
}),
|
||||
...(shouldServeIndexHTML ? getHTMLWebpackPlugins() : []),
|
||||
shouldAnalyze && getStatoscopePlugin(),
|
||||
...(WEBPACK_SERVE_INDEX ? getHTMLWebpackPlugins() : []),
|
||||
WEBPACK_BUNDLE_ANALYZER && getStatoscopePlugin(),
|
||||
isHotReloadEnabled && new webpack.HotModuleReplacementPlugin(),
|
||||
isHotReloadEnabled && new ReactRefreshWebpackPlugin({ overlay: false }),
|
||||
isProduction &&
|
||||
IS_PRODUCTION &&
|
||||
new CompressionPlugin({
|
||||
filename: '[path][base].gz',
|
||||
algorithm: 'gzip',
|
||||
@ -190,7 +159,7 @@ const config = {
|
||||
level: 9,
|
||||
},
|
||||
}),
|
||||
isProduction &&
|
||||
IS_PRODUCTION &&
|
||||
new CompressionPlugin({
|
||||
filename: '[path][base].br',
|
||||
algorithm: 'brotliCompress',
|
||||
@ -224,7 +193,7 @@ const config = {
|
||||
include: hotLoadablePaths,
|
||||
exclude: extensionHostWorker,
|
||||
use: [
|
||||
...(isProduction ? ['thread-loader'] : []),
|
||||
...(IS_PRODUCTION ? ['thread-loader'] : []),
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
@ -237,13 +206,13 @@ const config = {
|
||||
{
|
||||
test: /\.[jt]sx?$/,
|
||||
exclude: [...hotLoadablePaths, extensionHostWorker],
|
||||
use: [...(isProduction ? ['thread-loader'] : []), getBabelLoader()],
|
||||
use: [...(IS_PRODUCTION ? ['thread-loader'] : []), getBabelLoader()],
|
||||
},
|
||||
{
|
||||
test: /\.(sass|scss)$/,
|
||||
// CSS Modules loaders are only applied when the file is explicitly named as CSS module stylesheet using the extension `.module.scss`.
|
||||
include: /\.module\.(sass|scss)$/,
|
||||
use: getCSSLoaders(styleLoader, getCSSModulesLoader({ sourceMap: isDevelopment })),
|
||||
use: getCSSLoaders(styleLoader, getCSSModulesLoader({ sourceMap: IS_DEVELOPMENT })),
|
||||
},
|
||||
{
|
||||
test: /\.(sass|scss)$/,
|
||||
|
||||
@ -903,14 +903,11 @@ commandsets:
|
||||
- caddy
|
||||
env:
|
||||
ENTERPRISE: 1
|
||||
DISABLE_TELEMETRY: true
|
||||
|
||||
oss-web-standalone:
|
||||
commands:
|
||||
- web-standalone-http
|
||||
- caddy
|
||||
env:
|
||||
DISABLE_TELEMETRY: true
|
||||
|
||||
web-standalone-prod:
|
||||
commands:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user