웹의 계층화를 위한 Bazel

18617 단어 bazel

Bazel은 빠르고 공통적이며 안정적인 1.0입니다.
Bazel은 확정적 의존 관계도, 이전 중간 구축 결과의 분포식 캐시, 클라우드 작업자의 병행 실행을 통해 구축과 테스트 시간을 10배 높일 수 있는 구축 도구이다.
바젤이 가지고 있는 휴대전화just released 1.0는 거대한 거래였다.Bazel팀의 over four years of hard work 성과를 축하합니다!대기업은 테스트 버전 소프트웨어의 위험을 감당할 수 없기 때문에 안정적인 보증이 필요하다.이제 1.0이 되면 Bazel을 사용할 수 있습니다!하지만 바젤 자체가 부족해.
Bazel은 실행 엔진과 같습니다.그것은 사실상 시스템 구축의 핵심이다. 왜냐하면 어떤 특정한 언어를 어떻게 구축하는지 모르기 때문이다.이론적으로 Bazel을 단독으로 사용하고 저급 원어를 사용할 수 있다.그러나 실제로는 플러그인에 의존하여 더 높은 단계의 구축 설정을 작업으로 전환합니다. 이 작업은 Bazel이 다양한 방식으로 (예를 들어 원격 작업자) 생성한 하위 프로세스입니다.그래서 우리는 Bazel이 각종 언어 생태계의 특정 플러그인 아래에 있는 것을 보았다.
이 플러그인들은 규칙이라고 불리는데, 그것들의 성숙도는 각각 다르다.일부 규칙, 예를 들어 자바와 C++의 규칙은 Bazel 핵심과 함께 발표되었고 성숙했다.몇몇 규칙은 비슷하다.net와 루비는 지역 사회에서 공헌한 것으로 품질이 1.0이 아니다.

Javascripters 기쁨: Bazel은 거의 모든 도구를 npm에서 실행할 수 있습니다
내가 사용하는 플러그인은 JavaScript/Node용 플러그인입니다.js도 1.0에 가깝고 rules nodejs라고 불린다.
Bazel은 단지 당신이 실행하도록 하는 프로그램의 실행을 조율할 뿐입니다.바이너리 파일을 발표하는 모든 npm 패키지는 이 패키지에 특정한 Bazel 플러그인을 작성할 필요가 없습니다.rules nodejs에는'핵심'버전이 있는데 이것은 바로 Bazel이 실/npm을 어떻게 실행하고 생성된 가방을 사용하는지 가르치는 데 필요한 것입니다.잠시 후, 나는 우리가 어떻게 이 점을 해냈는지 상세하게 소개할 것이지만, 우선, 나는 당신에게 그것의 외관을 보여 드리겠습니다.https://github.com/alexeagle/my_bazel_project를 통해 최종 솔루션으로 이동할 수 있습니다.
우선, Bazel과 함께 제공된 프로필이 필요합니다.
$ npx @bazel/create my_bazel_project
# If you used Bazel before, make sure you got @bazel/create version 0.38.2 or later so later steps will work
$ cd my_bazel_project
새 작업공간을 제공합니다.
지금 공구를 좀 설치합시다.이 예에서 우리는 Babel을 사용하여 Google JS를 전송하고, Mocha를 사용하여 테스트를 실행하며, http 서버를 사용하여 Google 응용 프로그램에 서비스를 제공할 것입니다.이것은 단지 임의의 선택일 뿐이다. 너는 아마도 이미 네가 좋아하는 도구가 있을 것이다.
$ npm install mocha domino @babel/core @babel/cli @babel/preset-env http-server
이 도구들을 Bazel로 실행합시다.우선, 우리는 load 문구를 사용하여 그것들을 가져와야 한다.
그래서 편집BUILD.bazel 및 추가
load("@npm//@babel/cli:index.bzl", "babel")
load("@npm//mocha:index.bzl", "mocha_test")
load("@npm//http-server:index.bzl", "http_server")
이것은 rules nodejs가 Bazel에게 @npm 라는 작업 영역이 사용할 수 있다는 것을 보여 줍니다. (at 로고를 Bazel의 범위 패키지로 상상합니다.)rules nodejs는 index.bzl 파일을 추가하여 패키지 관리자가 설치한 모든 바이너리 파일(node_modules/.bin 폴더의 내용과 동일)을 공개합니다.우리가 설치한 세 가지 도구는 모두 이 @npm 범위 내에 있으며, 모든 도구는 확장자 .bzl 의 색인 파일을 가지고 있다.
이러한 색인 파일에서 를 로드하면 기호를 JavaScript 파일로 가져오는 것과 같습니다.우리load()s를 제작한 후에 우리는 지금 그것들을 사용할 수 있다.모든 기호는 함수입니다. 우리는 몇몇 명명 매개 변수를 사용하여 그것을 호출합니다.
이제 JavaScript와 테스트를 작성합니다.시간을 절약하기 위해서 나는 이 문장에서 이 문제를 토론하지 않을 것이다.
좋아, 우리는 어떻게 그것을 건설합니까?우리는 구축 요청의 출력이 무엇을 해야 하는지, 그리고 중간 결과를 캐시하는 방법을 Bazel에 전달하기 위해 입력, 도구, 출력의 도표에 따라 생각해야 한다.
이것을 에 추가BUILD.bazel:
babel(
    name = "compile",
    data = [
        "app.js",
        "es5.babelrc",
        "@npm//@babel/preset-env",
    ],
    outs = ["app.es5.js"],
    args = [
        "app.js",
        "--config-file",
        "$(location es5.babelrc)",
        "--out-file",
        "$(location app.es5.js)",
    ],
)
이것은 Babel CLI를 호출하는 것일 뿐이므로 문서를 보고 전달할 매개 변수를 알 수 있습니다.Bazel에서 $(location) 조수를 사용하기 때문에 입력이나 출력의 경로를 하드코딩할 필요가 없습니다.
우리는 이미 시험해 볼 수 있다. npm run build우리가 봤어.babel의 js 출력은 dist/bin 폴더에 표시됩니다.
BUILD에 추가하여 애플리케이션의 모양을 살펴 보겠습니다.바젤:
http_server(
    name = "server",
    data = [
        "index.html",
        "app.es5.js",
    ],
    args = ["."],
)
scripts에 추가package.json: "serve": "ibazel run :server"

ibazel is the watch mode for bazel.
Note that on Windows, you need to pass --enable_runfiles flag to Bazel. That's because Bazel creates a directory where inputs and outputs both appear together, for convenience.


현재 우리는 응용 프로그램을 제공할 수 있다. npm run serve마지막으로 모카를 실행해 봅시다.
mocha_test(
    name = "unit_tests",
    args = ["*.spec.js"],
    data = glob(["*.spec.js"]) + [
        "@npm//domino",
        "app.es5.js",
    ],
)

Note that we installed the domino package here so we could test the webapp including DOM interactions in node, which is faster than starting up a headless browser.


그것을 실행하려면 다음과 같이 하십시오.$ npm testBazel이 Babel, http 서버,mocha에 대해 아무것도 모르는 상황에서, 우리는 작은 응용 프로그램을 구축하기 위해 작업, 증가, 원격 실행 가능한 도구 체인을 조립했을 뿐이다.

더 많은 예
  • Bazel은 TypeScript/SAss로 작성된 React 프로그램을 실행합니다: https://github.com/bazelbuild/rules_nodejs/pull/1255
  • 더 많은 모카 테스트를 위한 Bazel: https://github.com/bazelbuild/rules_nodejs/blob/0.38.2/examples/webapp/BUILD.bazel#L34-L51
  • Bazel 실행 유형 스크립트tsc: https://github.com/bazelbuild/rules_nodejs/blob/0.38.2/examples/app/BUILD.bazel#L51-L74
  • Bazel은 Babel을 사용하고 생성된 프로그램을 Docker 이미지로 포장한다: https://github.com/bazelbuild/rules_nodejs/blob/0.38.2/examples/angular/src/BUILD.bazel#L131-L204
  • Bazel 실행 감소, Stylus css 사전 처리기: https://github.com/bazelbuild/rules_nodejs/blob/0.38.2/examples/app/styles/BUILD.bazel
  • Bazel은 구글 패키지 컴파일러를 사용하여 가장 작은 패키지 크기를 실현한다. https://github.com/bazelbuild/rules_nodejs/blob/0.38.2/examples/closure/BUILD.bazel#L4-L15
  • Bazel running Nuxt.서버측 렌더링 Vue의 js 구축: https://github.com/albttx/bazel-nuxt

  • 추가: 사용자 정의 규칙 및 매크로
    Bazel은 임의의 npm 도구를 실행할 수 있습니다. 이것은 좋지만, 이 도구에 필요한 CLI 파라미터를 알아야 합니다.이것은 인체공학$(location)이라는 문법으로 Bazel의 경로에 적응해야 하는 것도 아니다. 우리는 Bazel의 많은 기능을 이용하지 않았다. 예를 들어workers(공구를 감시 모드에서 운행하게 하는 것),Provider(규칙에 따라 다른 출력을 생성하도록 하는 것) 등이다.
    그것은 아직 너무 많은 학습과 평가가 필요하다.Angular CLI 팀의 엔지니어와 같은 도구 체인 전문가들은 사용 가능한 많은 도구의 기능과 균형을 이해하고 적합한 도구를 선택하는 데 절반의 시간을 들였다.
    최종 사용자로서 우리는 하나의 도구로 모든 Bazel 설정을 조립하는 것에 싫증이 납니다. 현재의 경험은 보통 더 높은 수준에 있습니다. 우리는 하나의 프레임워크를 사용하여 완전한 상자를 열고 사용할 수 있는 구축/서비스/테스트 도구 체인을 제공하기를 희망합니다.Bazel은 도구 체인 전문가가 이런 개발자의 체험을 제공하기에 매우 적합하다.
    예를 들어 Angular CLI에는 다각형 채우기를 사용하지 않고 기존 브라우저를 파괴하지 않는 방식으로 더 작고 현대적인 JS를 얻을 수 있는'차이 로드'기능이 있다.이것은 약간의 밑바닥 공구의 기교를 필요로 한다.
    Angular CLI는 Bazel을 사용하여 위에 표시된 규칙을 조합하는 차이 로드 도구 체인을 생성할 수 있습니다.Bazel에는 매크로라는 고급 작성 기능이 있습니다.매크로를 사용하여 일련의 도구 CLI 호출을 연결하고 사용자가 사용할 수 있도록 할 수 있습니다.사용자가 이렇게 부르도록 하려면 다음과 같이 하십시오.
    load("@npm//http-server:index.bzl", "http_server")
    load("@cool-rules//:differential_loading.bzl", "differential_loading")
    
    differential_loading(
        name = "app",
        srcs = glob(["*.ts"]),
        entry_point = "index.ts",
    )
    http_server(
        name = "server",
        data = [":app"],
        templated_args = ["app"],
    )
    
    
    우리는 differential_loading 이라는 매크로가 필요하다. 이것은 대량의 TypeScript 소스 코드와 응용 프로그램의 입구점을 가져오고, 낡은 브라우저와 현대 브라우저를 위한 디렉터리를 만들 수 있다.
    다음은 차이점을 로드하기 위해 도구체인 공급업체가 작성한 내용입니다.
    def differential_loading(name, entry_point, srcs):
        "Common workflow to serve TypeScript to modern browsers"
    
        ts_library(
            name = name + "_lib",
            srcs = srcs,
        )
    
        rollup_bundle(
            name = name + "_chunks",
            deps = [name + "_lib"],
            sourcemap = "inline",
            entry_points = {
                entry_point: "index",
            },
            output_dir = True,
        )
    
        # For older browsers, we'll transform the output chunks to es5 + systemjs loader
        babel(
            name = name + "_chunks_es5",
            data = [
                name + "_chunks",
                "es5.babelrc",
                "@npm//@babel/preset-env",
            ],
            output_dir = True,
            args = [
                "$(location %s_chunks)" % name,
                "--config-file",
                "$(location es5.babelrc)",
                "--out-dir",
                "$@",
            ],
        )
    
        # Run terser against both modern and legacy browser chunks
        terser_minified(
            name = name + "_chunks_es5.min",
            src = name + "_chunks_es5",
        )
    
        terser_minified(
            name = name + "_chunks.min",
            src = name + "_chunks",
        )
    
        web_package(
            name = name,
            assets = [
                "styles.css",
            ],
            data = [
                "favicon.png",
                name + "_chunks.min",
                name + "_chunks_es5.min",
            ],
            index_html = "index.html",
        )
    
    이것은 매우 길어 보이지만 현재 기본 Angular CLI에서 구축된 것보다 훨씬 간단합니다. 후자는 순수한 Webpack을 사용합니다.이곳의 조합 모델은 서로 다른 도구 사이에 명확한 관심사가 분리되어 있기 때문이다.

    개요: 계층화
    각 계층은 독립적으로 작업할 수 있지만 사용자는 더 높은 수준의 추상화를 선호합니다.
  • 원본 도구, 예를 들어 babel: 자바스크립트를 전송하기 위해 직접 호출할 수 있습니다.이것들은 모두 많은 개원 공헌자들이 쓴 것이다.
  • Bazel: 저급 원어로genrule에서 호출babel하지만 기계에 연결해야 합니다.구글의 바젤팀은 이를 지지했다.
  • Bazel+rules nodejs: 제공된 바이너리 파일을 사용하여 로드하고 실행babel합니다.구글의 JavaScript 구축/서비스 팀에서 작성했습니다.
  • Bazel+사용자 정의 규칙/매크로: 세부사항을 모르고 더 높은 수준의 API로 구축을 실행합니다.
  • 다양한 프레임워크의 CLI 팀과 같은 더 많은 툴 공급업체가 Bazel을 막후에서 사용하는 고급 체험을 제공할 수 있기를 바랍니다.이렇게 하면 표준 CLI를 사용하여 기존 도구에서 쉽게 도구 체인을 조립하고 증가분, 캐시 및 원격 병렬화를 자동으로 구현할 수 있습니다.

    좋은 웹페이지 즐겨찾기