Develop and build your client-server projects, powered by typescript and webpack.
npm install --save-dev @gravity-ui/app-builder
@gravity-ui/app-builder
provides CLI (npx app-builder
). You can view available commands with the --help
flag.
npx app-builder dev # to view supported options add the --help flag.
npx app-builder build # to view supported options add the --help flag.
You can use any of these files:
- app-builder.config.ts
- app-builder.config.js
- app-builder.config.json
- app-builder property in your package.json
You can also specify a custom filename using the --config
flag
import {defineConfig} from '@gravity-ui/app-builder';
export default defineConfig({
client: {
// client settings
},
server: {
// server settings
},
});
If the config needs to be conditionally determined, it can export a function instead:
import {defineConfig} from '@gravity-ui/app-builder';
export default defineConfig(
async function (
/** @type dev | build */
command,
/**
* values specified with --env flag
*
* @type {[k in string]: string}
*
* @example
* With follow command:
* app-build dev --env=path.to.member1=value1 --env=path.to.member2=value2
* you get:
* env = {path: {to: {member1: 'value1', member2: 'value2'}}}
*/
env,
) {
return {
verbose: command === 'dev',
client: {
// client settings
},
server: {
// server settings
},
};
},
);
export default config;
{
"app-builder": {
"client": {
// client settings
},
"server": {
// server settings
}
},
"scripts": {
"dev": "app-builder dev",
"build": "app-builder build"
}
}
target
(client | server
) — select compilation unit.verbose
(boolean
) - turn on verbose output.
app-builder
compiles server with typescript.
Default folder for server code is src/server
. There is must be file tsconfig.json
{
"compilerOptions": {
"outDir": "../../dist/server"
}
}
and index.ts
- server entrypoint.
outDir
- must be configured to place compiled files to {rootDir}/dist/server
.
The server is started with the command node {rootDir}/dist/server/index.js
.
All server settings are used only in dev mode:
port
(number | true
) — specify port that server listens. The port will be used to pass through requests from the client to the server. If set totrue
, the port will be selected automatically. The server is started with the commandAPP_PORT=${port} node dist/server/index.js --port ${port}
.watch
(string[]
) — by defaultapp-builder
monitors onlysrc/server
directory. If you need to watch other directories, specify them here.watchThrottle
(number
) — use to add an extra throttle, or delay restarting.inspect/inspectBrk
(number | true
) — listen for a debugging client on specified port. If specifiedtrue
, try to listen on9229
.
app-builder
bundles client with webpack. Client code must be in src/ui
folder.
src/ui/entries
- each file in this folder is used as entrypoint. dist/public/build
is output directory for bundles.
All paths must be specified relative rootDir
of the project.
modules
(string[]
) — Tell webpack what directories should be searched when resolving modules.modules
automatically populates withbaseUrl
fromsrc/ui/tsconfig.json
.alias
(Record<string, string>
) — Create aliases to import or require certain modules more easily, more
With this {rootDir}/src/ui/tsconfig.json
:
{
"compilerOptions": {
"baseDir": ".",
"paths": {
"~units": ["units/*"]
}
}
}
modules
will contain ["{rootDir}/src"]
and aliases - {"~units": ["{rootDir}/src/units"]}
;
includes
(string[]
) — additional compilation paths. Example:includes: ['node_modules/my-lib', 'src/shared']
images
(string[]
) — Additional paths for images. Example:images: ['node_modules/my-lib/img']
icons
(string[]
) — Additional paths for svg icons. By default, all svgs with paths includingicons/
will be processed. Example:icons: [node_modules/@fortawesome/fontawesome-pro/svgs]
publicPathPrefix
(string
) — publicPath prefix, will be added to/build/
symlinks
(boolean
) — Follow symbolic links while looking for a file. moreexternals
— specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. morenode
— include polyfills or mocks for various node stuff. morefallback
— Redirect module requests when normal resolving fails. morepolyfill
— allow enable Node.jsprocess
object polyfill.hiddenSourceMap
(boolean=true
) - iffalse
- source maps will be generated for prod buildsdisableSourceMapGeneration
(boolean
) — disable sourcemap generation;definitions
— add additional options to DefinePlugin. morenewJsxTransform
(boolean=true
) — use new JSX Transform.svgr
(SvgrConfig
) — svgr plugin options. moreentryFilter
(string[]
) — filter used entrypoints.excludeFromClean
(string[]
) — do not clean provided paths before build.forkTsCheker
(false | ForkTsCheckerWebpackPluginOptions
) - config for ForkTsCheckerWebpackPlugin more. Iffalse
, ForkTsCheckerWebpackPlugin will be disabled.cache
(boolean | FileCacheOptions | MemoryCacheOptions
) — Cache the generated webpack modules and chunks to improve build speed. morebabelCacheDirectory
(boolean | string
) — Set directory for babel-loader cache (`default: node_modules/.cache/babel-loader``)babel
((config: babel.TransformOptions, options: {configType: 'development' | 'production'}) => babel.TransformOptions | Promise<babel.TransformOptions>
) - Allow override the default babel transform options.webpack
((config: webpack.Configuration, options: {configType: 'development' | 'production'}) => webpack.Configuration | Promise<webpack.Configuration>
) - Allow override the default configuration.
devServer
(Object
) — webpack dev server options.ipc
(string
) — the Unix socket to listen to. Ifipc
andport
are not defined, then the socket{rootDir}/dist/run/client.sock
is used.port
(number | true
) — specify a port number to listen for requests on. Iftrue
, the free port will be selected automatically.webSocketPath
(string
) — tells clients connected to devServer to use the provided path to connect. Default is${publicPathPrefix}/build/sockjs-node
.type
('https'
) — allow to serve over HTTPS.options
(import('https').ServerOptions
) — allow to provide your own certificate.
watchOptions
— a set of options used to customize watch mode, morewatchPackages
(boolean
) - watch all changes innode_modules
.
reactRefresh
(false | (options: ReactRefreshPluginOptions) => ReactRefreshPluginOptions
) — disable or configurereact-refresh
in dev mode, moredetectCircularDependencies
(true | CircularDependenciesOptions
) - detect modules with circular dependencies, morelazyCompilation
(true | LazyCompilationConfig
) — enable experimental lazy compilation featuretrue
— enable featureLazyCompilationConfig
port
(number
) — port where to listen to from the serverentries
(boolean=true
) — iffalse
- disables lazy compilation forsrc/ui/entries
folder content
analyzeBundle
(true | statoscope
) — tools to analyze bundle.true
— enable webpack-bundle-analyzer plugin. Report generated todist/public/build/stats.html
statoscope
— enable statoscope plugin. Reports generated todist/public/build/stats.json
anddist/public/build/report.json
reactProfiling
(boolean
) — use react profiler API in production, this option also disable minimization. The API is required by React developers tools for profile.statoscopeConfig
(Options
) —@statoscope/webpack-plugin
configuration options. Might be used to override the defaults. RequiresanalyzeBundle: statoscope
.cdn
(CdnUploadConfig | CdnUploadConfig[]
) - upload bundled client files to CDN.bucket
(string
) — bucket nameprefix
(string
) — path to files inside the bucketregion
(string
) — AWS region or any stringendpoint
(string
) - cdn host to upload filescompress
(boolean
) - upload also gzip and brotli compressed versions of filesadditionalPattern
(string[]
) — patterns for uploading additional files. By default, only files generated by webpack are loaded.
sentryConfig
(Options
) —@sentry/webpack-plugin
configuration options.
vendors
(string[] | (defaultVendors: string[]) => string[]
) — additional libraries or a function returning libraries for a vendor chunk;momentTz
— settings for moment-timezone (by default data is truncated);contextReplacement
(object
)highlight.js
(string[]
) — list of language names to include, e.g.['javascript', 'python', 'bash']
;locale
: (string[]=['ru']
) — list ofmoment.js
orday.js
locales to include, e.g.['de', 'es']
. LocaleEn
is always present.
safari10
(boolean
) — Enablessafari10
terser's option. Terser optionstransformCssWithLightningCss
(boolean
) — use Lighting CSS to transform and minimize css instead of PostCSS and cssnanoterser
((options: TerserOptions) => TerserOptions
) - modify or return a custom Terser options.
-
monaco
(object
) — use monaco-editor-webpack-pluginfileName
(string
) — custom filename template for worker scripts.languages
(string[]
) - include only a subset of the languages supported. If you don't need support for all languages, set needed languages explicitly, since it may significantly affect build time.features
(string[]
) - include only a subset of the editor features.customLanguages
(IFeatureDefinition[]
) - include custom languages (outside of the ones shipped with themonaco-editor
).
Web workers allow you to run JavaScript code in a separate thread from the main UI thread. This can improve the performance and responsiveness of your web application by offloading intensive tasks to the background.
To create a web worker, you need to write a script file that defines the logic of the worker. For example, this file (my.worker.ts) implements a simple function that adds two numbers and sends the result back to the main thread:
// my.worker.ts
self.onmessage = async (ev) => {
const {a = 0, b = 0} = ev.data || {};
const result = a + b;
self.postMessage({
result,
});
};
app-builder
provides built-in support for web workers for files with the .worker.[jt]s
suffix. You can choose
between two variants of getting web workers by setting the newWebWorkerSyntax
option:
newWebWorkerSyntax: false
(default) - use theworker-loader
to import web workers. Content of worker file will be included in main bundle as blob. This variant does not support dynamic imports inside worker. For example:
// main.ts
import MyWorker from './my.worker.ts';
const worker = new MyWorker();
In this variant, you need to add some type declarations for the worker files::
// worker.d.ts
declare module '*.worker.ts' {
class WebpackWorker extends Worker {}
export default WebpackWorker;
}
newWebWorkerSyntax: true
- use the webpack 5 web workers syntax to import web workers. This variant allows to use dynamic imports inside worker and load worker bundle from CDN. For example:
import {Worker} from '@gravity-ui/app-builder/worker';
const MyWorker = new Worker(new URL('./my.worker', import.meta.url));
To use the web worker in your main script, you need to communicate with it using the postMessage and onmessage methods. For example:
// main.ts
const worker = '...'; // Worker creation, first or second variant
worker.onmessage = ({data: {result}}) => {
console.log(result);
};
worker.postMessage({a: 1, b: 2});