Esmx is a high-performance web application framework based on Rspack, providing complete application lifecycle management, static resource handling, and Server-Side Rendering capabilities.
type BuildEnvironment = 'client' | 'server'Application runtime environment types:
client: Runs in the browser environment, supporting DOM operations and browser APIsserver: Runs in the Node.js environment, supporting file system and server-side functionalitytype ImportMap = {
imports?: SpecifierMap
scopes?: ScopesMap
}ES module import mapping type.
type SpecifierMap = Record<string, string>Module specifier mapping type, used to define module import path mappings.
type ScopesMap = Record<string, SpecifierMap>Scope mapping type, used to define module import mappings within specific scopes.
enum COMMAND {
dev = 'dev',
build = 'build',
preview = 'preview',
start = 'start'
}Command type enumeration:
dev: Development environment command, starts the development server with hot reload supportbuild: Build command, generates production build artifactspreview: Preview command, starts a local preview serverstart: Start command, runs the production environment serverDefines the core configuration options of the Esmx framework.
interface EsmxOptions {
root?: string
isProd?: boolean
basePathPlaceholder?: string | false
modules?: ModuleConfig
packs?: PackConfig
devApp?: (esmx: Esmx) => Promise<App>
server?: (esmx: Esmx) => Promise<void>
postBuild?: (esmx: Esmx) => Promise<void>
}stringprocess.cwd()Project root directory path. Can be an absolute or relative path; relative paths are resolved based on the current working directory.
booleanprocess.env.NODE_ENV === 'production'Environment identifier.
true: Production environmentfalse: Development environmentstring | false'[[[___ESMX_DYNAMIC_BASE___]]]'Base path placeholder configuration. Used for runtime dynamic replacement of resource base paths. Set to false to disable this feature.
ModuleConfigModule configuration options. Used to configure project module resolution rules, including module aliases, external dependencies, etc.
PackConfigPackaging configuration options. Used to package build artifacts into standard npm .tgz format packages.
(esmx: Esmx) => Promise<App>Development environment application creation function. Only used in the development environment to create development server application instances.
export default {
async devApp(esmx) {
return import('@esmx/rspack').then((m) =>
m.createRspackHtmlApp(esmx, {
config(context) {}
})
)
}
}(esmx: Esmx) => Promise<void>Server startup configuration function. Used to configure and start the HTTP server, available in both development and production environments.
export default {
async server(esmx) {
const server = http.createServer((req, res) => {
esmx.middleware(req, res, async () => {
const render = await esmx.render({
params: { url: req.url }
});
res.end(render.html);
});
});
server.listen(3000);
}
}(esmx: Esmx) => Promise<void>Post-build processing function. Executed after project build completion, can be used for:
stringtrueCurrent module name, sourced from the module configuration.
stringtrueLegal JavaScript variable name generated based on the module name.
stringtrueAbsolute path of the project root directory. If the configured root is a relative path, it's resolved based on the current working directory.
booleantrueDetermines if the current environment is production. Prioritizes isProd from the configuration; if not configured, determines based on process.env.NODE_ENV.
stringtrueNotReadyError - When framework is not initializedGets the module base path starting and ending with slashes. Returns format /${name}/, where name comes from the module configuration.
stringtrueGets the base path placeholder for runtime dynamic replacement. Can be disabled through configuration.
MiddlewaretrueGets the static resource handling middleware. Provides different implementations based on the environment:
const server = http.createServer((req, res) => {
esmx.middleware(req, res, async () => {
const rc = await esmx.render({ url: req.url });
res.end(rc.html);
});
});(options?: RenderContextOptions) => Promise<RenderContext>trueGets the Server-Side Rendering function. Provides different implementations based on the environment:
const rc = await esmx.render({
params: { url: req.url }
});
const rc = await esmx.render({
base: '',
importmapMode: 'inline',
entryName: 'default',
params: {
url: req.url,
state: { user: 'admin' }
}
});typeof COMMANDtrueGets the command enumeration type definition.
ParsedModuleConfigtrueNotReadyError - When framework is not initializedGets complete configuration information of the current module, including module resolution rules, alias configuration, etc.
ParsedPackConfigtrueNotReadyError - When framework is not initializedGets packaging-related configuration of the current module, including output paths, package.json processing, etc.
options?: EsmxOptions - Framework configuration optionsEsmxCreate Esmx framework instance.
const esmx = new Esmx({
root: './src',
isProd: process.env.NODE_ENV === 'production'
});command: COMMANDPromise<boolean>Error: When initialized repeatedlyNotReadyError: When accessing uninitialized instanceInitializes the Esmx framework instance. Executes the following core initialization process:
NotReadyError when accessing an uninitialized instanceconst esmx = new Esmx({
root: './src',
isProd: process.env.NODE_ENV === 'production'
});
await esmx.init(COMMAND.dev);Promise<boolean>Destroys the Esmx framework instance, executing resource cleanup and connection closing operations. Mainly used for:
process.once('SIGTERM', async () => {
await esmx.destroy();
process.exit(0);
});Promise<boolean>Executes the application build process, including:
Throws NotReadyError when called on uninitialized framework instance
export default {
async postBuild(esmx) {
await esmx.build();
const render = await esmx.render({
params: { url: '/' }
});
esmx.writeSync(
esmx.resolvePath('dist/client', 'index.html'),
render.html
);
}
}Promise<void>NotReadyError - When framework is not initializedStarts the HTTP server and configures the server instance. Called in the following lifecycles:
export default {
async server(esmx) {
const server = http.createServer((req, res) => {
esmx.middleware(req, res, async () => {
const render = await esmx.render({
params: { url: req.url }
});
res.end(render.html);
});
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000');
});
}
}Promise<boolean>Executes post-build processing logic, used for:
export default {
async postBuild(esmx) {
const pages = ['/', '/about', '/404'];
for (const url of pages) {
const render = await esmx.render({
params: { url }
});
await esmx.write(
esmx.resolvePath('dist/client', url.substring(1), 'index.html'),
render.html
);
}
}
}Resolves project paths, converting relative paths to absolute paths.
Parameters:
projectPath: ProjectPath - Project path type...args: string[] - Path fragmentsReturns: string - Resolved absolute path
Example:
const htmlPath = esmx.resolvePath('dist/client', 'index.html');Synchronously writes file content.
Parameters:
filepath: string - Absolute path of filedata: any - Data to write, can be string, Buffer, or objectReturns: boolean - Whether write was successful
Example:
async postBuild(esmx) {
const htmlPath = esmx.resolvePath('dist/client', 'index.html');
const success = esmx.writeSync(htmlPath, '<html>...</html>');
}Synchronously reads and parses JSON files.
Parameters:
filename: string - Absolute path of JSON fileReturns: any - Parsed JSON object
Exception: Throws exception when file doesn't exist or JSON format is invalid
Example:
async server(esmx) {
const manifest = esmx.readJsonSync(esmx.resolvePath('dist/client', 'manifest.json'));
}Asynchronously reads and parses JSON files.
Parameters:
filename: string - Absolute path of JSON fileReturns: Promise<any> - Parsed JSON object
Exception: Throws exception when file doesn't exist or JSON format is invalid
Example:
async server(esmx) {
const manifest = await esmx.readJson(esmx.resolvePath('dist/client', 'manifest.json'));
}Get build manifest list.
Parameters:
target: BuildEnvironment - Target environment type
'client': Client environment'server': Server environmentReturns: Promise<readonly ManifestJson[]> - Read-only build manifest list
Exception: Throws NotReadyError when framework instance is not initialized
This method gets build manifest list for specified target environment, includes following features:
Cache Management
Environment Adaptation
Module Mapping
async server(esmx) {
const manifests = await esmx.getManifestList('client');
const appModule = manifests.find(m => m.name === 'my-app');
if (appModule) {
console.log('App exports:', appModule.exports);
console.log('App chunks:', appModule.chunks);
}
}Get import mapping object.
Parameters:
target: BuildEnvironment - Target environment type
'client': Generate import map for browser environment'server': Generate import map for server environmentReturns: Promise<Readonly<ImportMap>> - Read-only import mapping object
Exception: Throws NotReadyError when framework instance is not initialized
This method generates ES module import maps (Import Maps), with the following characteristics:
Module Resolution
Cache Optimization
Path Handling
async server(esmx) {
const importmap = await esmx.getImportMap('client');
const html = `
<!DOCTYPE html>
<html>
<head>
<script type="importmap">
${JSON.stringify(importmap)}
</script>
</head>
<body>
</body>
</html>
`;
}Get client import map information.
Parameters:
mode: ImportmapMode - Import map mode
'inline': Inline mode, returns HTML script tag'js': JS file mode, returns information with file pathReturns:
{
src: string;
filepath: string;
code: string;
}{
src: null;
filepath: null;
code: string;
}Exception: Throws NotReadyError when framework instance is not initialized
This method generates import map code for the client environment, supporting two modes:
Inline Mode (inline)
JS File Mode (js)
Core features:
Automatically handles dynamic base paths
Supports runtime replacement of module paths
Optimizes caching strategies
Ensures module loading order
Example:
async server(esmx) {
const server = express();
server.use(esmx.middleware);
server.get('*', async (req, res) => {
const result = await esmx.render({
importmapMode: 'js',
params: { url: req.url }
});
res.send(result.html);
});
server.get('/inline', async (req, res) => {
const result = await esmx.render({
importmapMode: 'inline',
params: { url: req.url }
});
res.send(result.html);
});
}Gets the module's static import path list.
Parameters:
target: BuildEnvironment - Build target
'client': Client environment'server': Server environmentspecifier: string - Module specifierReturns: Promise<readonly string[] | null> - Returns static import path list, returns null if not found
Exception: Throws NotReadyError when framework instance is not initialized
Example:
const paths = await esmx.getStaticImportPaths(
'client',
`your-app-name/src/entry.client`
);