Skip to content

stephen/cssc

Repository files navigation

cssc

PkgGoDev

A fast, friendly css compiler in go.

This repo is the start of a css compiler (parser, ast, and printer) and set of transforms to support new CSS syntax in current browsers. To start with, it aims to be able to replace projects like postcss-preset-env and cssnext.

It's approach is inspired from experimenting with esbuild (see here).

Status

The package can currently parse and print most standard CSS. There are likely bugs in both.

Some transforms are supported:

Transform Support Notes
@import rules Partial Only non-conditional imports can be inlined. Import conditions will be ignored.
Custom Properties Partial Only variables defined on :root will be substituted. The compiler will ignore any non-:root variables. See #3.
Custom Media Queries Complete
Media Feature Ranges Complete
:any-link Complete

API

For now, there is only a go API.

package main

import (
  "log"

  "github.com/stephen/cssc"
)

func main() {
  result := cssc.Compile(cssc.Options{
    Entry: []string{"css/index.css"},
  })

  // result.Files is a map of all output files.
  for path, content := range result.Files {
    log.Println(path, content)
  }
}

Transforms

Transforms can be specified via options:

package main

import (
  "github.com/stephen/cssc"
  "github.com/stephen/cssc/transforms"
)

func main() {
  result := cssc.Compile(cssc.Options{
    Entry: []string{"css/index.css"},
    Transforms: transforms.Options{
      // Transform :any-link into :link and :visited equivalents.
      AnyLink: transforms.AnyLinkTransform,
      // Keep @import rules without transforming them or inlining their content.
      ImportRules: transforms.ImportRulesPassthrough,
    },
  })

  // result.Files...
}

By default, all features are in passthrough mode and will not get transformed.

Error reporting

By default, errors and warnings are printed to stderr. You can control this behavior by providing a Reporter:

package main

import (
  "log"

  "github.com/stephen/cssc"
)

type TestReporter []error

func (r *TestReporter) AddError(err error) {
  *r = append(*r, err)
}

func main() {
  var errors TestReporter
  result := cssc.Compile(cssc.Options{
    Entry:    []string{"css/index.css"},
    Reporter: &errors,
  })

  for _, err := range errors {
    log.Println(err)
  }
}

Benchmarks

To keep track of performance, I've been benchmarking performance on (partially) parsing bootstrap.css.

$ go test -bench=. internal/parser/*.go
goos: darwin
goarch: amd64
BenchmarkParser-12    	     296	   3934884 ns/op	 1548281 B/op	   45916 allocs/op
PASS

I expect this to be a moving target as I complete the parser implementation.

About

a fast, friendly css compiler in go

Resources

License

Stars

Watchers

Forks

Languages