Plain is headed towards 1.0! Subscribe for development updates →

plain.esbuild

Build JavaScript files with esbuild.

gitignore

**/assets/**/*.esbuilt.*
 1import os
 2
 3import click
 4from watchfiles import Change, DefaultFilter, watch
 5
 6from plain.assets.finders import iter_asset_dirs, iter_assets
 7from plain.cli import register_cli
 8
 9from .core import esbuild, get_esbuilt_path
10
11
12@register_cli("esbuild")
13@click.group("esbuild")
14def cli():
15    pass
16
17
18@cli.command()
19@click.option("--minify", is_flag=True, default=True)
20def build(minify):
21    returncode = 0
22    for asset in iter_assets():
23        if ".esbuild." in asset.absolute_path:
24            if not esbuild(
25                asset.absolute_path,
26                get_esbuilt_path(asset.absolute_path),
27                minify=minify,
28            ):
29                returncode = 1
30            print()
31
32    if returncode:
33        exit(returncode)
34
35
36@cli.command()
37@click.pass_context
38def dev(ctx):
39    # Do an initial build of the assets
40    ctx.invoke(build, minify=False)
41
42    asset_dirs = list(iter_asset_dirs())
43
44    class EsbuildFilter(DefaultFilter):
45        def __call__(self, change, path):
46            return super().__call__(change, path) and ".esbuild." in path
47
48    print("Watching for changes in .esbuild. asset files...")
49
50    for changes in watch(*asset_dirs, watch_filter=EsbuildFilter()):
51        for change, path in changes:
52            if change in [Change.added, Change.modified]:
53                esbuild(path, get_esbuilt_path(path))
54            elif change == Change.deleted:
55                dist_path = get_esbuilt_path(path)
56                if os.path.exists(dist_path):
57                    print(f"Deleting {os.path.relpath(dist_path)}")
58                    os.remove(dist_path)