使用go-libsass实现100%兼容Sass的CSS预处理器
go-libsass是一个Go语言实现的Sass/SCSS处理器,它基于LibSass库,提供了100%兼容Sass的功能。下面我将详细介绍如何使用这个库。
安装go-libsass
首先需要安装go-libsass库:
go get github.com/wellington/go-libsass
基本使用示例
package main
import (
"bytes"
"fmt"
"log"
"github.com/wellington/go-libsass/libs"
)
func main() {
// 定义SCSS输入
scss := `
$primary-color: #333;
body {
color: $primary-color;
.content {
margin: 20px;
}
}
`
// 创建编译器
comp, err := libs.New(bytes.NewReader([]byte(scss)), &bytes.Buffer{})
if err != nil {
log.Fatal(err)
}
// 编译SCSS为CSS
err = comp.Run()
if err != nil {
log.Fatal(err)
}
// 获取编译后的CSS
var buf bytes.Buffer
_, err = comp.WriteTo(&buf)
if err != nil {
log.Fatal(err)
}
fmt.Println("编译结果:")
fmt.Println(buf.String())
}
高级功能示例
1. 使用自定义函数
package main
import (
"bytes"
"fmt"
"log"
"github.com/wellington/go-libsass/libs"
)
func main() {
scss := `
body {
font-size: rem(16);
}
`
comp, err := libs.New(bytes.NewReader([]byte(scss)), &bytes.Buffer{})
if err != nil {
log.Fatal(err)
}
// 注册自定义函数
comp.RegisterFunc("rem($px)", func(px libs.SassValue) (libs.SassValue, error) {
// 从SassValue中提取值
val, err := libs.Unmarshal(px)
if err != nil {
return nil, err
}
// 转换px为rem (假设基础字体大小为16px)
rem := val.(float64) / 16
// 返回新的SassValue
return libs.Marshal(fmt.Sprintf("%.2frem", rem))
})
err = comp.Run()
if err != nil {
log.Fatal(err)
}
var buf bytes.Buffer
_, err = comp.WriteTo(&buf)
if err != nil {
log.Fatal(err)
}
fmt.Println("编译结果:")
fmt.Println(buf.String())
}
2. 使用导入功能
package main
import (
"bytes"
"fmt"
"log"
"os"
"github.com/wellington/go-libsass/libs"
)
func main() {
// 创建临时文件作为导入
err := os.WriteFile("_variables.scss", []byte("$primary-color: #ff0000;"), 0644)
if err != nil {
log.Fatal(err)
}
defer os.Remove("_variables.scss")
scss := `
@import "variables";
body {
color: $primary-color;
}
`
comp, err := libs.New(bytes.NewReader([]byte(scss)), &bytes.Buffer{})
if err != nil {
log.Fatal(err)
}
// 设置导入路径
comp.Option(libs.IncludePaths([]string{"."}))
err = comp.Run()
if err != nil {
log.Fatal(err)
}
var buf bytes.Buffer
_, err = comp.WriteTo(&buf)
if err != nil {
log.Fatal(err)
}
fmt.Println("编译结果:")
fmt.Println(buf.String())
}
3. 使用源映射(Source Map)
package main
import (
"bytes"
"fmt"
"log"
"github.com/wellington/go-libsass/libs"
)
func main() {
scss := `
$primary-color: #333;
body {
color: $primary-color;
}
`
var cssBuf, mapBuf bytes.Buffer
comp, err := libs.New(bytes.NewReader([]byte(scss)), &cssBuf)
if err != nil {
log.Fatal(err)
}
// 启用源映射
comp.Option(libs.SourceMap(&mapBuf))
comp.Option(libs.SourceMapEmbed())
comp.Option(libs.SourceMapRoot("/scss"))
err = comp.Run()
if err != nil {
log.Fatal(err)
}
fmt.Println("CSS输出:")
fmt.Println(cssBuf.String())
fmt.Println("\n源映射:")
fmt.Println(mapBuf.String())
}
性能优化建议
- 复用编译器:创建编译器实例有一定开销,可以复用编译器处理多个文件
- 预编译常用部分:将不常变动的部分预编译并缓存
- 并行处理:对于大量文件,可以使用goroutine并行处理
// 复用编译器示例
func processFiles(compiler *libs.Compiler, files []string) error {
for _, file := range files {
f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()
var buf bytes.Buffer
compiler.Reset(f, &buf)
if err := compiler.Run(); err != nil {
return err
}
// 处理编译后的CSS...
}
return nil
}
注意事项
- go-libsass基于LibSass,而LibSass目前处于维护模式,不再添加新功能
- 对于最新的Sass特性,可能需要考虑Dart Sass实现
- 在生产环境中使用时,建议添加适当的错误处理和日志记录
go-libsass提供了完整的Sass功能支持,包括变量、嵌套、混合、继承、运算等所有Sass特性,可以满足大多数项目的需求。