Skip to content

Commit e3ad301

Browse files
authored
Support async bundling with JS resolver (parcel-bundler#263)
1 parent ccc1fd6 commit e3ad301

File tree

12 files changed

+1051
-110
lines changed

12 files changed

+1051
-110
lines changed

Cargo.lock

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,25 @@ let {code, map} = css.bundle({
100100
});
101101
```
102102

103+
The `bundleAsync` API is an asynchronous version of `bundle`, which also accepts a custom `resolver` object. This allows you to provide custom JavaScript functions for resolving `@import` specifiers to file paths, and reading files from the file system (or another source). The `read` and `resolve` functions are both optional, and may either return a string synchronously, or a Promise for asynchronous resolution.
104+
105+
```js
106+
let {code, map} = await css.bundleAsync({
107+
filename: 'style.css',
108+
minify: true,
109+
resolver: {
110+
read(filePath) {
111+
return fs.readFileSync(filePath, 'utf8');
112+
},
113+
resolve(specifier, from) {
114+
return path.resolve(path.dirname(from), specifier);
115+
}
116+
}
117+
});
118+
```
119+
120+
Note that using a custom resolver can slow down bundling significantly, especially when reading files asynchronously. Use `readFileSync` rather than `readFile` if possible for better performance, or omit either of the methods if you don't need to override the default behavior.
121+
103122
### From Rust
104123

105124
See the Rust API docs on [docs.rs](https://docs.rs/parcel_css).

node/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ parcel_sourcemap = { version = "2.1.0", features = ["json"] }
1919
jemallocator = { version = "0.3.2", features = ["disable_initial_exec_tls"] }
2020

2121
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
22-
napi = {version = "2.2.0", default-features = false, features = ["napi4", "compat-mode", "serde-json"]}
22+
napi = {version = "2.2.0", default-features = false, features = ["napi4", "napi5", "compat-mode", "serde-json"]}
2323
napi-derive = "2"
24+
crossbeam-channel = "0.5.6"
25+
rayon = "1.5.1"
2426

2527
[target.'cfg(target_arch = "wasm32")'.dependencies]
2628
js-sys = "0.3"

node/index.d.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@ export interface TransformOptions {
4545

4646
export type BundleOptions = Omit<TransformOptions, 'code'>;
4747

48+
export interface BundleAsyncOptions extends BundleOptions {
49+
resolver?: Resolver;
50+
}
51+
52+
/** Custom resolver to use when loading CSS files. */
53+
export interface Resolver {
54+
/** Read the given file and return its contents as a string. */
55+
read?: (file: string) => string | Promise<string>;
56+
57+
/**
58+
* Resolve the given CSS import specifier from the provided originating file to a
59+
* path which gets passed to `read()`.
60+
*/
61+
resolve?: (specifier: string, originatingFile: string) => string | Promise<string>;
62+
}
63+
4864
export interface Drafts {
4965
/** Whether to enable CSS nesting. */
5066
nesting?: boolean,
@@ -226,3 +242,8 @@ export declare function browserslistToTargets(browserslist: string[]): Targets;
226242
* Bundles a CSS file and its dependencies, inlining @import rules.
227243
*/
228244
export declare function bundle(options: BundleOptions): TransformResult;
245+
246+
/**
247+
* Bundles a CSS file and its dependencies asynchronously, inlining @import rules.
248+
*/
249+
export declare function bundleAsync(options: BundleAsyncOptions): TransformResult;

node/index.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import index from './index.js';
22

3-
const { transform, transformStyleAttribute, bundle, browserslistToTargets } = index;
4-
export { transform, transformStyleAttribute, bundle, browserslistToTargets };
3+
const { transform, transformStyleAttribute, bundle, bundleAsync, browserslistToTargets } = index;
4+
export { transform, transformStyleAttribute, bundle, bundleAsync, browserslistToTargets };

0 commit comments

Comments
 (0)