@lynx-js/rspeedy
Version:
A webpack/rspack-based frontend toolchain for Lynx
1,786 lines (1,754 loc) • 105 kB
TypeScript
/**
* @packageDocumentation
*
* The document contains all the configurations of the `@lynx-js/rspeedy` package.
*
* @example
*
* Use `lynx.config.ts` with {@link defineConfig} to get better TypeScript intellisense.
*
* ```ts
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* entry: './src/index.tsx',
* })
* ```
*/
import type { CompressOptions } from '@rsbuild/core';
import type { CreateRsbuildOptions } from '@rsbuild/core';
import type { DataUriLimit } from '@rsbuild/core';
import type { DistPathConfig } from '@rsbuild/core';
import type { InlineChunkConfig } from '@rsbuild/core';
import { logger } from '@rsbuild/core';
import type { PerformanceConfig } from '@rsbuild/core';
import type { ProxyConfig } from '@rsbuild/core';
import type { RsbuildConfig } from '@rsbuild/core';
import type { RsbuildInstance } from '@rsbuild/core';
import { RsbuildPlugin } from '@rsbuild/core';
import { RsbuildPluginAPI } from '@rsbuild/core';
import type { RsbuildPlugins } from '@rsbuild/core';
import { version as rsbuildVersion } from '@rsbuild/core';
import type { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin';
import { Rspack } from '@rsbuild/core';
import { rspack } from '@rsbuild/core';
import type { ServerConfig } from '@rsbuild/core';
import type { ToolsConfig } from '@rsbuild/core';
import type { WatchFiles } from '@rsbuild/core';
/**
* {@inheritdoc Performance.buildCache}
*
* @beta
*/
export declare interface BuildCache {
/**
* Add additional cache digests, the previous build cache will be invalidated
* when any value in the array changes.
*
* @defaultValue undefined
*
* @example
*
* Add `process.env.SOME_ENV` to the cache digest.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* performance: {
* buildCache: {
* cacheDigest: [process.env.SOME_ENV],
* },
* },
* })
* ```
*/
cacheDigest?: Array<string | undefined> | undefined;
/**
* The output directory of the cache files.
*
* @defaultValue 'node_modules/.cache'
*/
cacheDirectory?: string | undefined;
/**
* An array of files containing build dependencies.
* Rspack will use the hash of each of these files to invalidate the persistent cache.
*
* @remarks
*
* Rspeedy will use the following configuration files as the default build dependencies:
*
* - `package.json`
*
* - `tsconfig.json` (or `source.tsconfigPath`)
*
* - `.env`, `.env.*`
*
* - `tailwindcss.config.*`
*
* When using Rspeedy CLI, it will also automatically add
* `lynx.config.js` to the build dependencies.
*
* @example
*
* Add `postcss.config.js` to the build dependencies.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* performance: {
* buildCache: {
* buildDependencies: ['postcss.config.js'],
* },
* },
* })
* ```
*/
buildDependencies?: string[] | undefined;
}
/**
* {@inheritdoc Performance.chunkSplit}
*
* @public
*/
export declare interface ChunkSplit {
/**
* The ChunkSplitting strategy.
*
* @remarks
*
* - `split-by-experience`(default): an empirical splitting strategy, automatically splits some commonly used npm packages into chunks of moderate size.
*
* - `split-by-module`: split by NPM package granularity, each NPM package corresponds to a chunk.
*
* - `split-by-size`: automatically split according to module size.
*
* - `all-in-one`: bundle all codes into one chunk.
*
* - `single-vendor`: bundle all NPM packages into a single chunk.
*
* - `custom`: custom chunk splitting strategy.
*
* @example
*
* - Use `all-in-one` to put all modules in one chunk.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* performance: {
* chunkSplit: {
* strategy: 'all-in-one',
* },
* },
* })
* ```
*
* @example
*
* - Use `single-vendor` to put all third-party dependencies in one chunk. And source code in another chunk.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* performance: {
* chunkSplit: {
* strategy: 'single-vendor',
* },
* },
* })
* ```
*/
strategy?: 'all-in-one' | 'split-by-module' | 'split-by-experience' | 'single-vendor' | undefined;
/**
* Custom Rspack chunk splitting config can be specified.
*
* @example
*
* - Split `@lynx-js/react` and `react-router` into chunk `lib-react`.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* performance: {
* chunkSplit: {
* strategy: 'split-by-experience',
* override: {
* cacheGroups: {
* react: {
* test: /node_modules[\\/](@lynx-js[\\/]react|react-router)[\\/]/,
* name: 'lib-react',
* },
* },
* },
* },
* },
* })
* ```
*/
override?: Rspack.Configuration extends {
optimization?: {
splitChunks?: infer P;
} | undefined;
} ? P : never;
}
/**
* {@inheritdoc Performance.chunkSplit}
*
* @public
*/
export declare interface ChunkSplitBySize {
/**
* {@inheritdoc ChunkSplit.strategy}
*/
strategy: 'split-by-size';
/**
* The minimum size of a chunk, unit in bytes. Defaults to `10000`.
*
* @example
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* performance: {
* chunkSplit: {
* strategy: 'split-by-size',
* minSize: 20000,
* },
* },
* })
* ```
*/
minSize?: number | undefined;
/**
* The maximum size of a chunk, unit in bytes. Defaults to `Number.POSITIVE_INFINITY`.
*
* @example
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* performance: {
* chunkSplit: {
* strategy: 'split-by-size',
* maxSize: 50000,
* },
* },
* })
* ```
*/
maxSize?: number | undefined;
/**
* {@inheritdoc ChunkSplit.override}
*/
override?: Rspack.Configuration extends {
optimization?: {
splitChunks?: infer P;
} | undefined;
} ? P : never;
}
/**
* {@inheritdoc Performance.chunkSplit}
*
* @public
*/
export declare interface ChunkSplitCustom {
/**
* {@inheritdoc ChunkSplit.strategy}
*/
strategy: 'custom';
/**
* {@inheritdoc ChunkSplit.override}
*
* @example
*
* - Split `@lynx-js/react` and `react-router` into chunk `lib-react`.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* performance: {
* chunkSplit: {
* strategy: 'custom',
* splitChunks: {
* cacheGroups: {
* react: {
* test: /node_modules[\\/](@lynx-js[\\/]react|react-router)[\\/]/,
* name: 'lib-react',
* },
* },
* },
* },
* },
* })
* ```
*/
splitChunks?: Rspack.Configuration extends {
optimization?: {
splitChunks?: infer P;
} | undefined;
} ? P : never;
}
/**
* The `Config` is the configuration that `rspeedy` uses.
*
* @public
*/
export declare interface Config {
/**
* The {@link Dev} option is used to control the behavior related with development. Including: HMR, DevServer, etc.
*/
dev?: Dev | undefined;
/**
* The {@link Config.environments} option is used to set the output environment.
*
* @remarks
*
* Normally you don't need this if you are not using Lynx for Web.
*
* @example
*
* - Using different entries for Lynx and Web.
*
* ```ts
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* environments: {
* lynx: {},
* web: {
* source: { entry: { web: './src/index.web.jsx' } },
* },
* },
* source: {
* entry: './src/index.jsx',
* },
* })
* ```
*
* @example
*
* - Building Web-only outputs.
*
* ```ts
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* environments: {
* web: {
* source: { entry: { web: './src/index.web.jsx' } },
* },
* },
* })
* ```
*/
environments?: RsbuildConfig['environments'] | undefined;
/**
* Specify the build mode for Rsbuild and Rspack, as each mode has different default behavior and optimizations.
*
* @remarks
*
* The default value of mode depends on the `process.env.NODE_ENV` environment variable:
*
* - If `NODE_ENV` is production, the default value is production.
*
* - If `NODE_ENV` is development, the default value is development.
*
* - If `NODE_ENV` has any other value, the default value is none.
*
* - If you set the value of mode, the value of `NODE_ENV` will be ignored.
*
* When using Rspeedy's CLI:
*
* - `rspeedy dev` and `rspeedy preview` will set the default values of `NODE_ENV` and `mode` to `'development'`.
*
* - `rspeedy build` will set the default values of `NODE_ENV` and `mode` to `'production'`.
*
* @example
*
* If the value of `mode` is `'development'`:
*
* - Enable HMR and register the {@link https://rspack.dev/plugins/webpack/hot-module-replacement-plugin | HotModuleReplacementPlugin}.
*
* - Generate JavaScript source maps, but do not generate CSS source maps. See {@link Output.sourceMap} for details.
*
* - The `process.env.NODE_ENV` in the source code will be replaced with `'development'`.
*
* - The `import.meta.env.MODE` in the source code will be replaced with `'development'`.
*
* - The `import.meta.env.DEV` in the source code will be replaced with `true`.
*
* - The `import.meta.env.PROD` in the source code will be replaced with `false`.
*
* @example
*
* If the value of `mode` is `'production'`:
*
* - Enable JavaScript code minification and register the {@link https://rspack.dev/plugins/rspack/swc-js-minimizer-rspack-plugin | SwcJsMinimizerRspackPlugin}.
*
* - Generated JavaScript and CSS filenames will have hash suffixes, see {@link Output.filenameHash}.
*
* - Generated CSS Modules classnames will be shorter, see {@link CssModules.localIdentName}.
*
* - Do not generate JavaScript and CSS source maps, see {@link Output.sourceMap}.
*
* - The `process.env.NODE_ENV` in the source code will be replaced with `'production'`.
*
* - The `import.meta.env.MODE` in the source code will be replaced with `'production'`.
*
* - The `import.meta.env.DEV` in the source code will be replaced with `false`.
*
* - The `import.meta.env.PROD` in the source code will be replaced with `true`.
*/
mode?: 'development' | 'production' | 'none' | undefined;
/**
* The {@link Output} option is used to set how and where should the bundles and assets output.
*/
output?: Output | undefined;
/**
* The {@link Performance} option is used to optimize the build-time and runtime performance.
*/
performance?: Performance | undefined;
/**
* The {@link Resolve} option is used to control the resolution behavior of Rspack.
*/
resolve?: Resolve | undefined;
/**
* The {@link Server} option changes the behavior of dev-server.
*/
server?: Server | undefined;
/**
* The {@link Source} option changes the behavior of source files.
*/
source?: Source | undefined;
/**
* The {@link Tools} options changes the behavior of various building tools.
*/
tools?: Tools | undefined;
/**
* The `plugins` option is used to customize the build process in a variety of ways.
*
* @remarks
* Rspeedy use the plugin APIs from {@link https://rsbuild.dev/plugins/dev/index | Rsbuild}. See the corresponding document for developing a plugin.
*/
plugins?: RsbuildPlugins | undefined;
}
/**
* Parameters for the function exported from `lynx.config.js`.
*
* @public
*/
export declare interface ConfigParams {
/**
* The value of `process.env['NODE_ENV']`
*
* @remarks
* Common values include (non-exhaustive):
* - `'production'`
*
* - `'development'`
*
* - `'test'`
*/
env: 'production' | 'development' | 'test' | (string & Record<never, never>);
/**
* The CLI command of Rspeedy.
*
* @remarks
*
* Possible values:
*
* - `'build'`
*
* - `'dev'`
*
* - `'inspect'`
*
* - `'preview'`
*/
command: 'build' | 'dev' | 'inspect' | 'preview' | (string & Record<never, never>);
}
/**
* The type of the console method.
*
* @public
*/
export declare type ConsoleType = 'log' | 'warn' | 'error' | 'info' | 'debug' | 'profile' | 'profileEnd' | (string & Record<never, never>);
/**
* The `createRspeedy` method can let you create a Rspeedy instance and you can customize the build or development process in Node.js Runtime.
*
* @param options - {@link CreateRspeedyOptions}
* @returns - Rspeedy instance.
*
* @example
*
* ```ts
* import { createRspeedy } from '@lynx-js/rspeedy'
*
* void async function () {
* const rspeedy = await createRspeedy({})
* await rspeedy.build()
* }()
* ```
*
* @public
*/
export declare function createRspeedy({ cwd, rspeedyConfig, loadEnv, environment, callerName, }: CreateRspeedyOptions): Promise<RspeedyInstance>;
/**
* The options of `createRspeedy` method.
*
* @public
*/
export declare interface CreateRspeedyOptions {
/**
* The root path of the current build.
*/
cwd?: string;
/**
* The config of Rspeedy.
*/
rspeedyConfig?: Config;
/**
* Rspeedy automatically loads the .env file by default, utilizing the [Rsbuild API](https://rsbuild.dev/api/javascript-api/core#load-env-variables).
* You can use the environment variables defined in the .env file within your code by accessing them via `import.meta.env.FOO` or `process.env.Foo`.
* @see https://rsbuild.dev/guide/advanced/env-vars#env-file
* @defaultValue true
*/
loadEnv?: CreateRsbuildOptions['loadEnv'];
/**
* Only build specified environments.
* For example, passing `['lynx']` will only build the `lynx` environment.
* If not specified or passing an empty array, all environments will be built.
* @see https://rsbuild.dev/guide/advanced/environments#build-specified-environment
* @defaultValue []
*/
environment?: CreateRsbuildOptions['environment'];
/**
* The name of the framework or tool that is currently invoking Rsbuild.
* This allows plugins to tailor their behavior based on the calling context.
*
* @example
*
* Rsbuild plugins can access this value via `api.context.callerName`.
*
* ```js
* export function myPlugin() {
* return {
* name: 'my-plugin',
* setup(api) {
* // Log the name of the tool invoking Rsbuild
* console.log(`Called by: ${api.context.callerName}`);
*
* // Conditionally apply plugin logic based on caller
* if (api.context.callerName === 'rspeedy') {
* api.modifyRsbuildConfig((config) => {
* // Apply rspeedy-specific config changes
* return config;
* });
* } else if (api.context.callerName === 'rslib') {
* api.modifyRsbuildConfig((config) => {
* // Apply rslib-specific config changes
* return config;
* });
* }
* }
* };
* }
* ```
*
* @defaultValue 'rspeedy'
*/
callerName?: string;
}
/**
* {@inheritdoc Tools.cssExtract}
*
* @public
*/
export declare interface CssExtract {
/**
* {@inheritdoc @lynx-js/css-extract-webpack-plugin#LoaderOptions}
*/
loaderOptions?: CssExtractRspackLoaderOptions | undefined;
/**
* {@inheritdoc @lynx-js/css-extract-webpack-plugin#CssExtractRspackPluginOptions}
*/
pluginOptions?: CssExtractRspackPluginOptions | undefined;
}
/**
* {@inheritdoc @lynx-js/css-extract-webpack-plugin#LoaderOptions}
*
* @public
*/
export declare interface CssExtractRspackLoaderOptions {
/**
* The same as {@link https://github.com/webpack-contrib/mini-css-extract-plugin#esModule}.
* By default, `@lynx-js/css-extract-webpack-plugin` generates JS modules that use the ES modules syntax.
* There are some cases in which using ES modules is beneficial,
* like in the case of module concatenation and tree shaking.
*
* @example
* You can enable a CommonJS syntax using:
*
* ```js
* import {CssExtractWebpackPlugin} from "@lynx-js/css-extract-webpack-plugin";
* export default {
* plugins: [new CssExtractWebpackPlugin()],
* module: {
* rules: [
* {
* test: /\.css$/i,
* use: [
* {
* loader: CssExtractWebpackPlugin.loader,
* options: {
* esModule: false,
* },
* },
* "css-loader",
* ],
* },
* ],
* },
* };
* ```
*
* @public
*/
esModule?: boolean | undefined;
}
/**
* {@inheritdoc @lynx-js/css-extract-webpack-plugin#CssExtractRspackPluginOptions}
*
* @public
*/
export declare interface CssExtractRspackPluginOptions {
/**
* {@inheritdoc @lynx-js/css-extract-webpack-plugin#CssExtractRspackPluginOptions.ignoreOrder}
*/
ignoreOrder?: boolean | undefined;
/**
* {@inheritdoc @lynx-js/css-extract-webpack-plugin#CssExtractRspackPluginOptions.pathinfo}
*/
pathinfo?: boolean | undefined;
}
/**
* {@inheritdoc Tools.cssLoader}
*
* @public
*/
export declare interface CssLoader {
/**
* The option `importLoaders` allows you to configure how many loaders before `css-loader` should be applied to `@imported` resources and CSS modules imports.
*
* @remarks
*
* The default value of `importLoaders` is:
*
* - `1` when compiling CSS files
*
* - `2` when compiling Sass or Less files
*
* See {@link https://github.com/webpack-contrib/css-loader?tab=readme-ov-file#importloaders | css-loader#import-loaders} for details.
*/
importLoaders?: 0 | 1 | 2 | undefined;
/**
* The {@link CssLoaderModules | cssLoader.modules} option enables/disables the CSS Modules specification and setup basic behavior.
*
* @example
*
* Using `false` value to increase performance because we avoid parsing CSS Modules features, it will be useful for developers who use vanilla css or use other technologies.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* tools: {
* cssLoader: {
* modules: false,
* },
* },
* })
* ```
*
* @example
*
* Using `() => true` value to enable CSS Modules for all files.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* tools: {
* cssLoader: {
* modules: () => true,
* },
* },
* })
* ```
*
* @example
*
* Using object value to enable CSS Modules based-on {@link CssLoaderModules.auto} option and setup more configurations about CSS Modules.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* tools: {
* cssLoader: {
* modules: {
* namedExport: true,
* },
* },
* },
* })
* ```
*/
modules?: boolean | CssLoaderModules | undefined;
}
/**
* {@inheritdoc CssLoader.modules}
*
* @public
*/
export declare interface CssLoaderModules {
/**
* {@inheritdoc CssModules.auto}
*/
auto?: boolean | RegExp | ((filename: string) => boolean) | undefined;
/**
* {@inheritdoc CssModules.exportLocalsConvention}
*/
exportLocalsConvention?: CssModuleLocalsConvention | undefined;
/**
* {@inheritdoc CssModules.localIdentName}
*/
localIdentName?: string | undefined;
/**
* Enables/disables ES modules named export for locals.
*
* @example
*
* - `style.css`
*
* ```css
* .foo-baz {
* color: red;
* }
* .bar {
* color: blue;
* }
* .default {
* color: green;
* }
* ```
*
* - `index.js`
*
* ```js
* import * as styles from "./styles.css";
*
* // If using `exportLocalsConvention: "as-is"` (default value):
* console.log(styles["foo-baz"], styles.bar);
*
* // If using `exportLocalsConvention: "camel-case-only"`:
* console.log(styles.fooBaz, styles.bar);
*
* // For the `default` class name
* console.log(styles["_default"]);
* ```
*/
namedExport?: boolean | undefined;
}
/**
* {@inheritdoc CssModules.exportLocalsConvention}
*
* @public
*/
export declare type CssModuleLocalsConvention = 'asIs' | 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly';
/**
* {@inheritdoc Output.cssModules}
*
* @public
*/
export declare interface CssModules {
/**
* The `auto` option allows CSS modules to be automatically enabled based on their filenames.
*
* @remarks
*
* Given the various `auto` values, the behavior is described as follows:
*
* - `true`: enable CSS modules for all files matching `/\.module\.\w+$/i.test(filename)` RegExp.
*
* - `false`: disable CSS modules.
*
* - `RegExp`: enable CSS modules for all files matching the `auto.test(filename)` RegExp.
*
* - `function`: enable CSS modules based on the filter function.
*
* See {@link https://github.com/webpack-contrib/css-loader?tab=readme-ov-file#auto | css-loader#auto} for details.
*
* @example
*
* Enable CSS module for `*.module.css` and `shared/*.css`:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* output: {
* cssModules: {
* auto: (filename) => {
* return filename.includes('.module.') || filename.includes('shared/')
* },
* },
* },
* })
* ```
*/
auto?: boolean | RegExp | ((filename: string) => boolean) | undefined;
/**
* Allows exporting names from global class names, so you can use them via import.
*
* @remarks
*
* See {@link https://github.com/webpack-contrib/css-loader?tab=readme-ov-file#exportglobals | css-loader#exportGlobals} for details.
*/
exportGlobals?: boolean | undefined;
/**
* The style of exported class names.
*
* @remarks
*
* Given the various `exportLocalsConvention` values, the behavior is described as follows:
*
* - `'asIs'`: Class names will be exported as is.
*
* - `'camelCase'`: Class names will be camelized, the original class name will not to be removed from the locals
*
* - `'camelCaseOnly'`: Class names will be camelized, the original class name will be removed from the locals
*
* - `'dashes'`: Only dashes in class names will be camelized
*
* - `'dashesOnly'`: Dashes in class names will be camelized, the original class name will be removed from the locals
*
* See {@link https://github.com/webpack-contrib/css-loader?tab=readme-ov-file#exportlocalsconvention | css-loader#exportLocalsConvention} for details.
*/
exportLocalsConvention?: CssModuleLocalsConvention | undefined;
/**
* Sets the format of the className generated by CSS Modules after compilation.
*
* @remarks
*
* The default value is `'[local]-[hash:base64:6]'` which combines the original class name with a 6-character hash.
*
* Available placeholders:
*
* - `[local]`: Original class name
*
* - `[hash]`: Hash of the class name
*
* - `[path]`: File path
*
* - `[name]`: File name
*
* - `[ext]`: File extension
*
* See {@link https://github.com/webpack-contrib/css-loader?tab=readme-ov-file#localIdentName | css-loader#localIdentName} for details.
*
* @example
*
* Use only hash for shorter class names:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* output: {
* cssModules: {
* localIdentName: '[hash:base64:8]',
* },
* },
* })
* ```
*
* @example
*
* Include file name for debugging:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* output: {
* cssModules: {
* localIdentName: '[name]__[local]--[hash:base64:5]',
* },
* },
* })
* ```
*/
localIdentName?: string | undefined;
}
/**
* {@inheritdoc Source.decorators}
*
* @public
*/
export declare interface Decorators {
/**
* Specify the decorator syntax version to be used.
*
* @remarks
*
* If you want to know the differences between different decorators versions, you can refer to: {@link https://github.com/tc39/proposal-decorators?tab=readme-ov-file#how-does-this-proposal-compare-to-other-versions-of-decorators | How does this proposal compare to other versions of decorators?}
*
* @example
*
* `'2022-03'` corresponds to the Stage 3 decorator proposal, equivalent to the decorator syntax supported by TypeScript 5.0 by default.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* source: {
* decorators: { version: '2022-03' },
* },
* })
* ```
*
* @example
*
* `'legacy'` corresponds to TypeScript's `experimentalDecorators: true`.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* source: {
* decorators: { version: 'legacy' },
* },
* })
* ```
*/
version?: 'legacy' | '2022-03';
}
/**
* The `defineConfig` method is a helper function used to get TypeScript intellisense.
*
* @param config - The config of Rspeedy.
* @returns - The identical config as the input config.
*
* @example
*
* Use `defineConfig` in `lynx.config.ts`:
*
* ```ts
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* // autocompletion works here!
* })
* ```
*
* @public
*/
export declare function defineConfig(config: Config): Config;
/**
* The `defineConfig` method is a helper function used to get TypeScript intellisense.
*
* @param config - The function that returns a config of Rspeedy.
* @returns - The identical function as the input.
*
* @example
*
* Use `defineConfig` in `lynx.config.ts`:
*
* ```ts
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig(() => {
* return {
* // autocompletion works here!
* }
* })
* ```
*
* @example
*
* Use `defineConfig` with parameters in `lynx.config.ts`:
*
* ```ts
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig(({ env }) => {
* const isTest = env === 'test'
* return {
* output: {
* minify: isTest ? false : true,
* },
* }
* })
* ```
*
* @public
*/
export declare function defineConfig(config: (params: ConfigParams) => Config): (params: ConfigParams) => Config;
/**
* The `defineConfig` method is a helper function used to get TypeScript intellisense.
*
* @param config - The promise that resolves to a config of Rspeedy.
* @returns - The identical promise as the input.
*
* @example
*
* Use `defineConfig` in `lynx.config.ts`:
*
* ```ts
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig(
* import('@lynx-js/react-rsbuild-plugin').then(({ pluginReactLynx }) => ({
* plugins: [pluginReactLynx()],
* })),
* );
* ```
*
* @public
*/
export declare function defineConfig(config: Promise<Config>): Promise<Config>;
/**
* The `defineConfig` method is a helper function used to get TypeScript intellisense.
*
* @param config - The function that returns a promise that resolves to a config of Rspeedy.
* @returns - The identical function as the input.
*
* @example
*
* Use `defineConfig` in `lynx.config.ts`:
*
* ```ts
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig(async () => {
* const foo = await bar()
* return {
* // autocompletion works here!
* }
* })
* ```
*
* @example
*
* Use `defineConfig` with parameters in `lynx.config.ts`:
*
* ```ts
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig(async ({ env }) => {
* const foo = await bar()
* const isTest = env === 'test'
* return {
* output: {
* minify: isTest ? false : true,
* },
* }
* })
* ```
*
* @public
*/
export declare function defineConfig(config: (params: ConfigParams) => Promise<Config>): (params: ConfigParams) => Promise<Config>;
/**
* {@inheritdoc Config.dev}
* @public
*/
export declare interface Dev {
/**
* The {@link Dev.assetPrefix} is used to set the URL prefix for static assets during development.
* @remarks
*
* The functionality of {@link Dev.assetPrefix} is basically the same as the {@link https://www.rspack.dev/config/output#outputpublicpath | output.publicPath}
* config in Rspack. With the following differences:
*
* - `dev.assetPrefix` only takes effect during development.
*
* - `dev.assetPrefix` automatically appends a trailing `/` by default.
*
* - The value of `dev.assetPrefix` is written to the `process.env.ASSET_PREFIX` environment variable.
*
* @example
*
* If `dev.assetPrefix` is set to true, the URL prefix will be `http://<host>:<port>/`:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* dev: {
* assetPrefix: true,
* },
* })
* ```
*
* @example
*
* If `dev.assetPrefix` is set to a string, the value will be used as a prefix and automatically appended to the static resource URL.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* dev: {
* assetPrefix: 'https://example.com/assets/',
* },
* })
* ```
*
* @example
*
* The port number that Rspeedy server listens on may change. For example, if the port is in use, Rspeedy will automatically increment the port number until it finds an available port.
*
* To avoid `dev.assetPrefix` becoming invalid due to port changes, you can use one of the following methods:
*
* - Enable `server.strictPort`.
*
* - Use the `<port>` placeholder to refer to the current port number. Rspeedy will replace the placeholder with the actual port number it is listening on.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* dev: {
* assetPrefix: 'https://example.com:<port>/assets/',
* },
* })
* ```
*/
assetPrefix?: string | boolean | undefined;
/**
* Configuration of the development client.
*/
client?: DevClient | undefined;
/**
* Whether to enable Hot Module Replacement (HMR).
*
* @remarks
*
* Defaults to `true`.
*
* By default, Rspeedy uses HMR as the preferred method to update modules. If HMR is disabled or cannot be used in certain scenarios, it will automatically fallback to {@link Dev.liveReload}.
*
* To completely disable both HMR and live reload, set both `dev.hmr` and `dev.liveReload` to `false`. Then, no WebSocket requests will be made to the dev server on the page, and the page will not automatically refresh when file changes.
*
* @example
*
* Disable HMR:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* hmr: false,
* },
* })
* ```
*
* @example
*
* Disable both HMR and live reload:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* hmr: false,
* liveReload: false,
* },
* })
* ```
*/
hmr?: boolean | undefined;
/**
* Whether to enable live reload functionality.
*
* Defaults to `true`.
*
* Live reload is used as a fallback when {@link Dev.hmr} is disabled or cannot be used in certain scenarios. When enabled, the page will automatically refresh when source files are changed.
*
* To completely disable both HMR and live reload, set both `dev.hmr` and `dev.liveReload` to `false`. Then, no WebSocket requests will be made to the dev server on the page, and the page will not automatically refresh when file changes.
*
* @example
*
* Disable live reload:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* liveReload: false,
* },
* })
* ```
*
* @example
*
* Disable both HMR and live reload:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* hmr: false,
* liveReload: false,
* },
* })
* ```
*/
liveReload?: boolean | undefined;
/**
* Watch specified files and directories for changes. When a file change is detected, it can trigger a page reload or restart the dev server.
*
* @example
*
* - Specify the files and directories watched for changes.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* watchFiles: {
* paths: ['src/**', 'public/**'],
* },
* },
* })
* ```
*
* @example
*
* - Use {@link https://github.com/paulmillr/chokidar#api | chokidar} options for watching.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* watchFiles: {
* paths: ['src/**', 'public/**'],
* options: { usePolling: false },
* },
* },
* })
* ```
*/
watchFiles?: WatchFiles | WatchFiles[] | undefined;
/**
* Used to control whether the build artifacts of the development environment are written to the disk.
*
* @remarks
*
* This is bypassed to {@link https://github.com/webpack/webpack-dev-middleware?tab=readme-ov-file#writetodisk | `webpack-dev-middleware`}.
*
* Setting `writeToDisk: true` won't change the behavior of the `webpack-dev-middleware`, and bundle files accessed through the browser will still be served from memory.
*
* This option also accepts a `Function` value, which can be used to filter which files are written to disk.
*
* The function follows the same premise as `Array#filter` in which a return value of `false` will not write the file, and a return value of `true` will write the file to disk.
*
* @example
* ```js
* // lynx.config.ts
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* dev: {
* writeToDisk: (filePath) => /superman\.css$/.test(filePath),
* },
* })
* ```
*/
writeToDisk?: boolean | ((filename: string) => boolean) | undefined;
/**
* Whether to display progress bar during compilation.
*
* Defaults to `true`.
*
* @example
*
* Disable the progress bar.
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* progressBar: false,
* },
* })
* ```
*
* @example
*
* Modify the progress bar `id`
*
* To modify the text displayed on the left side of the progress bar, set the `id` option:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* progressBar: {
* id: 'Some Text'
* },
* },
* })
* ```
*/
progressBar?: boolean | {
id?: string;
} | undefined;
}
/**
* {@inheritdoc Dev.client}
*
* @public
*/
export declare interface DevClient {
/**
* The path to websocket.
*
* @remarks
*
* Defaults to `require.resolve('@lynx-js/websocket')`
*/
websocketTransport?: string | undefined;
}
/**
* {@inheritdoc Output.distPath}
*
* @public
*/
export declare interface DistPath extends DistPathConfig {
/**
* The output directory of the intermediate files.
*
* @deprecated
*
* This option is never read and will be removed in the future version.
*
* @remarks
*
* Default value:
*
* - `'.rspeedy'`
*/
intermediate?: string | undefined;
}
/**
* {@inheritdoc Source.entry}
*
* @example
*
* - Use a single entry:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* source: {
* entry: './src/pages/main/index.js',
* }
* })
* ```
*
* @example
*
* - Use a single entry with multiple entry modules:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* source: {
* entry: ['./src/prefetch.js', './src/pages/main/index.js'],
* }
* })
* ```
*
* @example
*
* - Use multiple entries(with multiple entry modules):
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* source: {
* entry: {
* foo: './src/pages/foo/index.js',
* bar: ['./src/pages/bar/index.js', './src/post.js'], // multiple entry modules is allowed
* }
* }
* })
* ```
*
* @example
*
* - Use multiple entries with {@link EntryDescription}:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
* export default defineConfig({
* source: {
* entry: {
* foo: './src/pages/foo/index.js',
* bar: {
* import: ['./src/prefetch.js', './src/pages/bar'],
* }
* }
* }
* })
* ```
* @public
*/
export declare type Entry = string | string[] | Record<string, string | string[] | EntryDescription>;
/**
* The `EntryDescription` describes a entry. It is useful when the project has multiple entries with different configuration.
*
* @remarks
* It is similar with the {@link https://www.rspack.dev/config/entry#entry-description-object | Entry Description Object} of Rspack.
* But only a few properties that Lynx supports is allowed.
*
* @public
*/
export declare interface EntryDescription {
/**
* The path to the entry module(s).
*
* @remarks
*
* If no value is provided, the default value `src/index.js` will be used.
*
* @defaultValue `'./src/index.js'`
*/
import?: string | string[] | undefined;
/**
* This is an important option when using on-demand-loading or loading external resources like images, files, etc. If an incorrect value is specified you'll receive 404 errors while loading these resources.
*
* @see https://webpack.js.org/configuration/output/#outputpublicpath
*/
publicPath?: string | undefined;
}
/**
* The exposed API of Rspeedy. Can be used in Rsbuild plugin with {@link https://rsbuild.dev/plugins/dev/core#apiuseexposed | api.useExposed}.
*
* @public
*
* @example
*
* ```ts
* import type { ExposedAPI } from '@lynx-js/rspeedy'
* const RsbuildPlugin = {
* name: 'my-rsbuild-plugin',
* pre: ['lynx:rsbuild:plugin-api'],
* setup(api) {
* const rspeedyAPI = api.useExposed<ExposedAPI>(Symbol.for('rspeedy.api'))
* },
* }
* ```
*/
export declare interface ExposedAPI {
/**
* The user config.
*/
config: Config;
/**
* Print debug logs.
*
* @param message - The printed message.
*/
debug: (message: string | (() => string)) => void;
/**
* Exit the process.
*
* @param code - The exit code.
*/
exit: (code?: number) => Promise<void> | void;
/**
* Get the Rspeedy logger.
*/
logger: typeof logger;
/**
* The version of Rspeedy.
*/
version: string;
}
/**
* {@inheritdoc Output.filename}
*
* @public
*/
export declare interface Filename {
/**
* The name of the bundle files.
*
* @remarks
*
* Default values:
*
* - `'[name].[platform].bundle'`
*
* The following placeholder is supported:
*
* - `[name]`: the name of the entry.
* - `[contenthash]`: the contenthash of the bundle.
* - `[platform]`: the environment name of the bundle.
*
* @example
*
* - Using content hash in bundle filename:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* output: {
* filename: {
* bundle: '[name].[contenthash].bundle',
* },
* },
* })
* ```
*
* @example
*
* - Using content hash with length in bundle filename:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* output: {
* filename: {
* bundle: '[name].[contenthash:8].bundle',
* },
* },
* })
* ```
*/
bundle?: string | undefined;
/**
* The name of the template files.
*
* @deprecated
*
* Use {@link Filename.bundle} instead.
*
* @remarks
*
* Default values:
*
* - `'[name].lynx.bundle'`
*
* The following placeholder is supported:
*
* - `[name]`: the name of the entry.
* - `[contenthash]`: the contenthash of the template.
*
* @example
*
* - Using content hash in bundle filename:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* output: {
* filename: {
* template: '[name].[contenthash].bundle',
* },
* },
* })
* ```
*
* @example
*
* - Using content hash with length in bundle filename:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* output: {
* filename: {
* template: '[name].[contenthash:8].bundle',
* },
* },
* })
* ```
*/
template?: string | undefined;
/**
* The name of the JavaScript files.
*
* @remarks
*
* Default values:
*
* - Development: `'[name].js'`
* - Production: `'[name].[contenthash:8].js'`
*
* @example
*
* - Using a function to dynamically set the filename based on the file information:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* output: {
* filename: {
* js: (pathData, assetInfo) => {
* console.log(pathData); // You can check the contents of pathData here
*
* if (pathData.chunk?.name === 'index') {
* return isProd ? '[name].[contenthash:8].js' : '[name].js';
* }
* return '/some-path/[name].js';
* },
* },
* },
* })
* ```
*/
js?: Rspack.Filename | undefined;
/**
* The name of the CSS files.
*
* @remarks
*
* Default values:
*
* - `'[name].css'`
*
* @example
*
* - Using a function to dynamically set the filename based on the file information:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* output: {
* filename: {
* css: (pathData, assetInfo) => {
* console.log(pathData); // You can check the contents of pathData here
*
* if (pathData.chunk?.name === 'index') {
* return isProd ? '[name].[contenthash:8].css' : '[name].css';
* }
* return '/some-path/[name].css';
* },
* },
* },
* })
* ```
*/
css?: Rspack.CssFilename | undefined;
/**
* The name of the SVG images.
*
* @remarks
*
* Default values:
*
* - `'[name].[contenthash:8].svg'`
*/
svg?: Rspack.AssetModuleFilename | undefined;
/**
* The name of the font files.
*
* @remarks
*
* Default values:
*
* - `'[name].[contenthash:8][ext]'`
*/
font?: Rspack.AssetModuleFilename | undefined;
/**
* The name of non-SVG images.
*
* @remarks
*
* Default values:
*
* - `'[name].[contenthash:8][ext]'`
*/
image?: Rspack.AssetModuleFilename | undefined;
/**
* The name of media assets, such as video.
*
* @remarks
*
* Default values:
*
* - `'[name].[contenthash:8][ext]'`
*/
media?: Rspack.AssetModuleFilename | undefined;
/**
* The name of WebAssembly files.
*
* @remarks
*
* Default values:
*
* - `'[hash].module.wasm'`
*/
wasm?: Rspack.WebassemblyModuleFilename;
/**
* The name of other assets, except for above (image, svg, font, html, wasm...)
*
* @remarks
*
* Default values:
*
* - `'[name].[contenthash:8][ext]'`
*/
assets?: Rspack.AssetModuleFilename;
}
/**
* Load the build config by the config path.
*
* @param loadConfigOptions - the options of `loadConfig` method.
* @returns Build config.
*
* @example
*
* ```ts
* import { loadConfig } from '@lynx-js/rspeedy'
*
* void async function () {
* const config = await loadConfig({ configPath: './lynx.config.js' })
* console.log(config);
* }()
* ```
*
* @public
*/
export declare function loadConfig(loadConfigOptions: LoadConfigOptions): Promise<LoadConfigResult>;
/**
* The options of loadConfig.
*
* @public
*/
export declare interface LoadConfigOptions {
configPath?: string | undefined;
cwd?: string | undefined;
}
/**
* The result of {@link loadConfig}.
*
* @public
*/
export d