or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bundling.mdindex.mdrust-api.mdstyle-attributes.mdtargets.mdtransformation.mdvisitors.md
tile.json

bundling.mddocs/

0

# CSS Bundling

1

2

Bundle CSS files with dependency resolution, @import inlining, and asset tracking for complete CSS processing pipelines that combine multiple files into optimized output.

3

4

## Capabilities

5

6

### Bundle Function

7

8

Synchronously bundles a CSS file and its dependencies by inlining @import rules.

9

10

```typescript { .api }

11

/**

12

* Bundles a CSS file and its dependencies, inlining @import rules

13

* @param options - Bundle configuration options (same as transform but without code)

14

* @returns Bundle result with combined CSS and dependency information

15

*/

16

function bundle<C extends CustomAtRules>(

17

options: BundleOptions<C>

18

): TransformResult;

19

20

type BundleOptions<C extends CustomAtRules> = Omit<TransformOptions<C>, 'code'>;

21

```

22

23

**Usage Examples:**

24

25

```typescript

26

import { bundle } from "lightningcss";

27

28

// Basic CSS bundling

29

const result = bundle({

30

filename: "src/main.css", // Entry point CSS file

31

minify: true,

32

targets: {

33

chrome: 90 << 16,

34

firefox: 88 << 16

35

}

36

});

37

38

console.log(new TextDecoder().decode(result.code));

39

40

// Bundle with CSS modules

41

const moduleBundle = bundle({

42

filename: "src/components/index.css",

43

cssModules: true,

44

minify: true

45

});

46

47

console.log(moduleBundle.exports); // Combined CSS module exports

48

```

49

50

### Bundle Async Function

51

52

Asynchronously bundles CSS files with custom resolver support for advanced file loading scenarios.

53

54

```typescript { .api }

55

/**

56

* Bundles a CSS file and its dependencies asynchronously, inlining @import rules

57

* @param options - Async bundle configuration with optional custom resolver

58

* @returns Promise resolving to bundle result

59

*/

60

function bundleAsync<C extends CustomAtRules>(

61

options: BundleAsyncOptions<C>

62

): Promise<TransformResult>;

63

64

interface BundleAsyncOptions<C extends CustomAtRules> extends BundleOptions<C> {

65

resolver?: Resolver;

66

}

67

```

68

69

**Usage Examples:**

70

71

```typescript

72

import { bundleAsync } from "lightningcss";

73

74

// Async bundling with default file system resolver

75

const result = await bundleAsync({

76

filename: "src/styles.css",

77

minify: true,

78

sourceMap: true

79

});

80

81

// Custom resolver for non-file-system sources

82

const customResult = await bundleAsync({

83

filename: "virtual://main.css",

84

resolver: {

85

async resolve(specifier, originatingFile) {

86

// Custom resolution logic (e.g., resolve from database, URL, etc.)

87

if (specifier.startsWith('virtual://')) {

88

return specifier;

89

}

90

return path.resolve(path.dirname(originatingFile), specifier);

91

},

92

93

async read(file) {

94

// Custom file reading logic

95

if (file.startsWith('virtual://')) {

96

return await fetchFromDatabase(file);

97

}

98

return await fs.readFile(file, 'utf8');

99

}

100

}

101

});

102

```

103

104

### Custom Resolver Interface

105

106

Define custom file resolution and reading logic for advanced bundling scenarios.

107

108

```typescript { .api }

109

/** Custom resolver to use when loading CSS files. */

110

interface Resolver {

111

/** Read the given file and return its contents as a string. */

112

read?: (file: string) => string | Promise<string>;

113

114

/**

115

* Resolve the given CSS import specifier from the provided originating file to a

116

* path which gets passed to `read()`.

117

*/

118

resolve?: (specifier: string, originatingFile: string) => string | Promise<string>;

119

}

120

```

121

122

**Usage Examples:**

123

124

```typescript

125

import { bundleAsync } from "lightningcss";

126

import path from "path";

127

import fs from "fs/promises";

128

129

// URL-based resolver

130

const urlResolver: Resolver = {

131

async resolve(specifier, originatingFile) {

132

if (specifier.startsWith('http')) {

133

return specifier; // Keep URLs as-is

134

}

135

if (originatingFile.startsWith('http')) {

136

return new URL(specifier, originatingFile).href;

137

}

138

return path.resolve(path.dirname(originatingFile), specifier);

139

},

140

141

async read(file) {

142

if (file.startsWith('http')) {

143

const response = await fetch(file);

144

return await response.text();

145

}

146

return await fs.readFile(file, 'utf8');

147

}

148

};

149

150

const result = await bundleAsync({

151

filename: "https://cdn.example.com/styles.css",

152

resolver: urlResolver,

153

minify: true

154

});

155

156

// Package-based resolver

157

const packageResolver: Resolver = {

158

async resolve(specifier, originatingFile) {

159

if (specifier.startsWith('@')) {

160

// Resolve scoped packages from node_modules

161

return require.resolve(specifier + '/style.css');

162

}

163

return path.resolve(path.dirname(originatingFile), specifier);

164

},

165

166

async read(file) {

167

return await fs.readFile(file, 'utf8');

168

}

169

};

170

```

171

172

### Bundle Result Processing

173

174

Process the bundling results to extract combined CSS, source maps, and dependency information.

175

176

```typescript { .api }

177

// Bundle results use the same TransformResult interface

178

interface TransformResult {

179

/** The bundled and transformed CSS code. */

180

code: Uint8Array;

181

/** The generated source map, if enabled. */

182

map: Uint8Array | void;

183

/** Combined CSS module exports from all bundled files, if enabled. */

184

exports: CSSModuleExports | void;

185

/** CSS module references from all bundled files. */

186

references: CSSModuleReferences;

187

/** All dependencies found during bundling, if enabled. */

188

dependencies: Dependency[] | void;

189

/** Warnings that occurred during bundling. */

190

warnings: Warning[];

191

}

192

```

193

194

**Usage Examples:**

195

196

```typescript

197

import { bundle } from "lightningcss";

198

import fs from "fs";

199

200

const result = bundle({

201

filename: "src/main.css",

202

sourceMap: true,

203

cssModules: true,

204

analyzeDependencies: true,

205

minify: true

206

});

207

208

// Write bundled CSS

209

fs.writeFileSync('dist/bundle.css', result.code);

210

211

// Write source map if generated

212

if (result.map) {

213

fs.writeFileSync('dist/bundle.css.map', result.map);

214

}

215

216

// Process CSS module exports

217

if (result.exports) {

218

const moduleMap = Object.fromEntries(

219

Object.entries(result.exports).map(([key, value]) => [key, value.name])

220

);

221

fs.writeFileSync('dist/css-modules.json', JSON.stringify(moduleMap, null, 2));

222

}

223

224

// Log dependency information

225

if (result.dependencies) {

226

console.log('Bundle dependencies:');

227

result.dependencies.forEach(dep => {

228

console.log(` ${dep.type}: ${dep.url}`);

229

});

230

}

231

232

// Handle warnings

233

if (result.warnings.length > 0) {

234

console.warn('Bundle warnings:');

235

result.warnings.forEach(warning => {

236

console.warn(` ${warning.message} at ${warning.loc.filename}:${warning.loc.line}:${warning.loc.column}`);

237

});

238

}

239

```

240

241

### Bundling with Import Analysis

242

243

Enable dependency analysis during bundling to track @import and url() dependencies.

244

245

```typescript { .api }

246

interface DependencyOptions {

247

/** Whether to preserve `@import` rules rather than removing them. */

248

preserveImports?: boolean;

249

}

250

```

251

252

**Usage Examples:**

253

254

```typescript

255

const result = bundle({

256

filename: "src/main.css",

257

analyzeDependencies: {

258

preserveImports: false // Default: remove @import rules after inlining

259

},

260

minify: true

261

});

262

263

// Dependencies contain all @import and url() references

264

result.dependencies?.forEach(dep => {

265

if (dep.type === 'import') {

266

console.log(`Imported: ${dep.url} with media: ${dep.media}`);

267

} else if (dep.type === 'url') {

268

console.log(`Asset: ${dep.url}`);

269

}

270

});

271

```