使用Bazel构建前端Sass

使用Bazel构建前端Sass_第1张图片

注:本文假设对Bazel有一定的了解。本文基于Bazel 4.2.2 版本

在web前端领域,前端样式,web浏览器只认CSS样式语言。而CSS样式语言又过于低级。于是有人发明了更高级的语言:Sass[1],用于生成CSS代码。

这样的方案,称为:“CSS预处理器”。除了使用Sass实现,还可以使用LESS实现等。

本文介绍是如何使用Bazel将Sass文件编译成CSS文件。

为什么使用Bazel

编译Sass的方法已经很多了,为什么我们还要使用Bazel呢?虽然本质上,Bazel编译Sass源代码时,使用的是sass原生的编译工具[2] 。

使用Bazel的原因如下:

  1. 1. 它支持增量构建:以避免将来的不必要的构建速度成本;

  2. 2. 对单仓库友好:因为它支持多语言,所以,我们可以放心地把前后端代码、基础设施代码放在同一个仓库中;

  3. 3. 统一构建工具:使整个工程的构建逻辑达到高度一致,以避免将来构建逻辑不一致的成本。

样例工程结构

[workspace]/
    WORKSPACE
    hello_world/
        BUILD
        main.scss
    shared/
        BUILD
        _fonts.scss
        _colors.scss

WORKSPACE说明

在WORKSPACE中引入Rule:

git_repository(  
    name = "io_bazel_rules_sass",  
    commit = "354793d0603dbe26232f4a5fb25e67e0e9e4c909", 
    # 我这里指定最新的是commit  
    remote = "https://github.com/bazelbuild/rules_sass.git",  
)

# Setup Bazel NodeJS rules.
# See: https://bazelbuild.github.io/rules_nodejs/install.html.

# Setup repositories which are needed for the Sass rules.
load("@io_bazel_rules_sass//:defs.bzl", "sass_repositories")
sass_repositories()

我们采用git_repository的方式引入rules_sass

当你执行构建时,会遇到错误:

ERROR: Failed to load Starlark extension '@build_bazel_rules_nodejs//:index.bzl'.
Cycle in the workspace file detected. This indicates that a repository is used prior to being defined.
The following chain of repository dependencies lead to the missing definition.
 - @build_bazel_rules_nodejs
This could either mean you have to add the '@build_bazel_rules_nodejs' repository with a statement like `http_archive` in your WORKSPACE file (note that transitive dependencies are not added automatically), or move an existing definition earlier in your WORKSPACE file.
ERROR: cycles detected during target parsing

这是因为rules_sass依赖于rules_nodejs。解决办法是在rules_sass之前声明rules_nodejs

http_archive(  
    name = "build_bazel_rules_nodejs",  
    sha256 = "c077680a307eb88f3e62b0b662c2e9c6315319385bc8c637a861ffdbed8ca247",  
    urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.1.0/rules_nodejs-5.1.0.tar.gz"],  
)  
  
load("@build_bazel_rules_nodejs//:repositories.bzl", "build_bazel_rules_nodejs_dependencies")  
  
build_bazel_rules_nodejs_dependencies()  
  
load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")  
load("@rules_nodejs//nodejs:yarn_repositories.bzl", "yarn_repositories")  
  
nodejs_register_toolchains(  
    name = "nodejs",  
    node_version = "16.13.2",  
)  
  
yarn_repositories(  
    name = "yarn",  
    yarn_version = "1.22.17",  
)
以下是rules_sass的声明

注:将rules_nodejs显示声明在WORKSPACE中,是一个避免与其它Rules发生冲突的好习惯。

注:执行构建的过程需要连接外网,请留意你的网络。

BUILD说明

样例工程中,shared/BUILD定义的是sass库:

package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_sass//:defs.bzl", "sass_library")

sass_library(
    name = "colors",
    srcs = ["_colors.scss"],
)

sass_library(
    name = "fonts",
    srcs = ["_fonts.scss"],
)

hello_world/BUILD声明的是最终的sass文件的构建逻辑,注意它使用的是sass_binary

package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_sass//:defs.bzl", "sass_binary")

sass_binary(
    name = "hello_world",
    src = "main.scss",
    deps = [
         "//shared:colors",
         "//shared:fonts",
    ],
)

sass_binary用于输出一个css文件。它还有很多参数,比如:

  • • output_dir: css输出文件的文件夹

  • • output_name:css输出的文件名称

更多参数,请前往Github仓库。

main.scss说明

在main.scss文件中,我们需要注意的是:在@import时,import的是sass_library的名称,而不是带有下划线的真实文件名:

@import "shared/fonts"; // 这里需要注意
@import "shared/colors";

html {
  body {
    font-family: $default-font-stack;
    h1 {
      font-family: $modern-font-stack;
      color: $example-red;
    }
  }
}

执行构建

$ bazel build //hello_world
INFO: Found 1 target...
Target //hello_world:hello_world up-to-date:
  bazel-bin/hello_world/hello_world.css
  bazel-bin/hello_world/hello_world.css.map
INFO: Elapsed time: 1.911s, Critical Path: 0.01s

成本

采用Bazel构建Sass不是没有成本的。比如旧工程的迁移成本、前端开发人员的学习成本等。你需要根据你的项目的实际情况做权衡。

引用链接

[1] Sass: https://sass-lang.com/
[2] 编译工具: https://github.com/bazelbuild/rules_sass/blob/main/sass/sass_wrapper.js

往期文章推荐:

比构建速度,Bazel是Gradle的10倍,不服不行!!!

你可能感兴趣的:(前端,sass,css)