Deno 웹 응용 프로그램에 코드 번들 방법

저는 이전 글에서 JSPM을 사용하여 서버에 나타나는 React 응용 프로그램을 작성하는 방법과 템플릿 텍스트를 사용하여 클라이언트 패키지에 서비스를 제공하는 방법을 소개했습니다.
한 달여 전에 이 글을 쓴 이래로 Deno팀은 일련의 기능과 오류 복구를 발표했다. 이것은 우리가 현재 클라이언트 스크립트를 더욱 우아한 방식으로 연결할 수 있고 노드 프로젝트의 현재 작업 흐름에 더욱 가깝다는 것을 의미한다.
본고에서 deno bundle 명령과 Deno 컴파일러 API를 소개하고, 이러한 기능을 사용하여 작업하는React SSR 응용 프로그램과 묶인 클라이언트 스크립트를 만드는 방법을 가르쳐 드리겠습니다.

Deno bundle 명령


Deno는 CLI에 it's own bundling capability을 내장하고 있습니다.
$ deno bundle [OPTIONS] <source_file> [out_file]

This can be used to output a single JavaScript file, which includes all dependencies of the specified input.


즉, 이 명령은 URL로 가져온 원격 모듈을 포함하여 모듈과 코드가 가져온 모든 하위 모듈을 포함합니다.
예를 들어, 간단한 Deno 스크립트 helloDeno.ts을 만듭니다.
import { bgBlue, red, bold, italic } from "https://deno.land/x/[email protected]/fmt/colors.ts";

console.log(bgBlue(italic(red(bold("Hello Deno!")))));
우리는 deno run helloDeno.ts을 사용하여 정상적으로 운행할 수 있다.
$ deno run ./helloDeno.ts 

Hello Deno!
그곳에서 우리는 무서운 읽을 수 없는 Hello Deno!을 볼 수 있는데, 빨간색으로 파란색 배경에 쓰여 있다😂.
이제 deno bundle 명령의 작용을 봅시다!우리는 helloDeno.ts 파일로 그것을 호출할 수 있으며, 목표 출력 helloDeno.bundle.js을 제공할 수 있습니다.출력을 제공하지 않으면, 컨트롤러에서 stdout에 출력합니다.
$ deno bundle ./helloDeno.ts helloDeno.bundle.js
Bundle ~/helloDeno.ts
Emit "helloDeno.bundle.js" (9.37 KB)
현재 디렉터리에 helloDeno.bundle.js이라는 다른 파일이 있어야 합니다🎉. 나는 네가 그것을 열고 빠르게 읽도록 격려한다. - 이것은 매우 복잡하지만, 시스템 등록 코드에서, 너는 네가 쓴 것을 찾을 수 있을 것이다.그것은 보기에 다음과 같다.
// ... rest of the code

execute: function () {
    console.log(colors_ts_1.bgBlue(colors_ts_1.italic(colors_ts_1.red(colors_ts_1.bold("Hello Deno!")))));
}

// ... rest of the code
자세히 보면, 우리가 가져온 https://deno.land/std/fmt/colors.ts 모듈의 모든 코드를 찾을 수 있을 것이다. 약속한 바와 같이, 하위 모듈을 포함한 모든 코드를 묶고 있다.
Deno CLI를 다시 사용하여 실행 여부를 확인할 수 있습니다.
$ deno run ./helloDeno.bundle.js                
Hello Deno!
이번에는 실행이 거의 즉각적이라는 것을 알아야 한다.우리는 이미 Deno 코드를 하나의 JavaScript 파일에 묶었기 때문에, TypeScript 컴파일러를 실행하고 원격 모듈을 가져오는 데 더 이상 비용이 필요하지 않습니다. Deno는 코드를 계속 실행할 수 있습니다!
클라이언트 자산의 CI/CD 파이프라인의 일부로 이 명령을 사용하여 번들 코드를 만들 수 있습니다.

Deno 컴파일러 API


Deno는 또한 핵심 실행 시 Compiler API의 일부로 묶는 방법을 제공합니다.

Please note that this API is currently unstable. To learn more about using unstable APIs and how to use them, check out the Deno stability documentation.


이 API는 내장 TypeScript 컴파일러에 대한 액세스를 제공하는 Deno 네임스페이스에 내장된 세 가지 방법을 지원합니다.다음과 같습니다.

  • Deno.compile() - deno cache과 유사하다.그것은 코드를 가져오고 캐시할 수 있으며, 코드를 컴파일할 수 있지만, 코드를 실행하지 않습니다.진단 및 컴파일된 파일 이름의 매핑을 코드로 되돌리지만 파일을 만들지 않습니다. 이 작업을 직접 수행해야 합니다.

  • Deno.bundle() - deno bundle과 매우 비슷하다.또한 Deno.compile()에 가깝지만, 파일을 코드로 되돌리는 맵이 아니라 문자열로 되돌려줍니다. 이것은 자체적으로 포함된 ES 모듈입니다.

  • Deno.transpileOnly() - TypeScript 함수 transpileModule()을 기반으로 간단하게 코드를 TypeScript에서 JavaScript로 변환하고 원본 코드와 원본 맵을 되돌려줍니다.
  • 첫 번째 두 가지가 어떻게 간단한 helloDeno.ts 스크립트와 함께 작업하는지 봅시다!우리는 Deno.transpileOnly()을 포함하지 않지만, 그것은 다른 두 개와 매우 비슷하다.

    덕노야.컴파일()

    compile.ts이라는 파일을 만들고 다음을 추가합니다.
    const [diagnostics, emitMap] = await Deno.compile(
      "./helloDeno.ts",
    );
    
    console.log(emitMap);
    
    그런 다음 다음 다음 명령을 사용하여 컴파일 스크립트를 실행할 수 있습니다.
    $ deno run --unstable --allow-read --allow-net ./compile.ts
    

    Note the various permissions we need to add. We are reading a local file helloDeno.ts which requires --allow-read, fetching a remote file for colours which requires --allow-net and using an unstable API which needs --unstable.


    그런 다음 콘솔에서 다음을 볼 수 있습니다.
    {
      https://deno.land/std/fmt/colors.js.map: '{"version":3,"file":"colors.js","sourceRoot":"","sources":["colors.ts"],"names":[],"mappings":"AAAA,...',
      https://deno.land/std/fmt/colors.js: "// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
    /** A module to print ANS...",
      ~/helloDeno.js.map: '{"version":3,"file":"helloDeno.js","sourceRoot":"","sources":["helloDeno.ts"],"names":[],"mappings":...',
      ~/helloDeno.js: 'import { bgBlue, red, bold, italic } from "https://deno.land/std/fmt/colors.ts";
    console.log(bgBlue(...'
    }
    
    이것은 성공적으로 우리의 코드를 컴파일하고 자바스크립트 코드와 원본 코드에 파일 이름을 매핑하는 맵을 생성했습니다.

    덕노야.번들 ()


    이제 bundle.ts 파일을 만들고 다음을 추가합니다.
    const [diagnostics, emit] = await Deno.bundle(
      "./helloDeno.ts",
    );
    
    console.log(emit);
    
    이게 저희 compile.ts 스크립트처럼 보일 것 같아요!그러나 만약 우리가 그것을 실행하고 있다면, 우리는 컨트롤러에서 매우 다른 것을 보아야 한다.
    $ deno run --unstable --allow-read --allow-net ./bundle.ts
    
    // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
    
    // This is a specialized implementation of a System module loader.
    
    "use strict";
    
    // @ts-nocheck
    /* eslint-disable */
    let System, __instantiate;
    (() => {
      const r = new Map();
    
    // ... rest of the code
    
    이 문자열은 deno bundle 명령을 실행한 정확한 출력과 일치하는 번들 코드 문자열을 stdout에 인쇄했습니다.실제로 deno bundle의 값을 파일에 기록하여 emit 명령을 다시 만들 수 있습니다. 예를 들어 다음과 같습니다.
    const [diagnostics, emit] = await Deno.bundle(
      "./helloDeno.ts",
    );
    
    await Deno.writeTextFile("./helloDeno.bundle.v2.js", emit);
    
    스크립트를 다시 실행하지만 --allow-write 권한을 사용하면 모든 번들 코드를 포함하는 helloDeno.bundle.v2.js이라는 파일을 만들 수 있습니다.🎉
    $ deno run --unstable --allow-read --allow-net --allow-write ./bundle.ts
    

    클라이언트 JS 바인딩을 사용하여 React SSR 응용 프로그램 작성


    이제 Opine React example을 통해 이 컴파일러 API를 응용 프로그램에서 어떻게 사용하는지 알아보겠습니다.client.tsx을 보면 클라이언트 JavaScript의 입구점입니다. React 응용 프로그램을 id로 설정하는 요소를 담당합니다.
    import React from "https://dev.jspm.io/[email protected]";
    import ReactDOM from "https://dev.jspm.io/[email protected]";
    import { App } from "./components/App.tsx";
    
    (ReactDOM as any).hydrate(
      <App />,
      // @ts-ignore
      document.getElementById("root"),
    );
    
    인용된 App은components 폴더에 있습니다. 간단한 React 프로그램을 만들 것입니다. 일부 하위 구성 요소는React 궁금증을 사용하여 렌더링합니다.
    // @deno-types="https://raw.githubusercontent.com/Soremwar/deno_types/4a50660/react/v16.13.1/react.d.ts"
    import React from "https://dev.jspm.io/[email protected]";
    import { Title } from "./Title.tsx";
    import { List } from "./List.tsx";
    
    export const App = ({ isServer = false }) => {
      if (isServer) {
        return (<>
          <Title />
          <p className="app_loading">Loading Doggos...</p>
        </>);
      }
    
      return (<>
        <Title />
        <React.Suspense fallback={<p className="app_loading">Loading Doggos...</p>}>
          <List />
        </React.Suspense>
      </>);
    };
    
    root compiler hint을 사용하면 React 등 유행 모듈을 위해 지역사회에서 작성한 유형을 사용할 수 있습니다.
    만약 우리가 지금 // @deno-types ... 파일로 돌아간다면, 이것은 응용 프로그램의 주요 입구점이다.만약 파일의 맨 위를 보신다면, 아주 익숙해 보이는 코드를 보실 수 있습니다!
    import { opine, serveStatic } from "../../mod.ts";
    import { join, dirname } from "../../deps.ts";
    import { renderFileToString } from "https://deno.land/x/[email protected]/mod.ts";
    import React from "https://dev.jspm.io/[email protected]";
    import ReactDOMServer from "https://dev.jspm.io/[email protected]/server";
    import { App } from "./components/App.tsx";
    
    /**
     * Create our client bundle - you could split this out into
     * a preprocessing step.
     */
    const [diagnostics, js] = await Deno.bundle(
      "./examples/react/client.tsx",
      undefined,
      { lib: ["dom", "dom.iterable", "esnext"] },
    );
    
    if (diagnostics) {
      console.log(diagnostics);
    }
    
    /**
     * Create our Opine server.
     */
    const app = opine();
    const __dirname = dirname(import.meta.url);
    
    // ... rest of the code
    
    서버 코드가 해야 할 첫 번째 일은 server.tsx 방법으로 하나의 Deno.bundle() 패키지를 만들고 js 파일을 입구점으로 하는 것이다.그런 다음 스크립트에서 JavaScript가 client.tsx 경로로 제공되는 것을 볼 수 있습니다.
    // ... rest of the code
    
    /**
     * Serve our client JS bundle.
     */
    app.get("/scripts/client.js", async (req, res) => {
      res.type("application/javascript").send(js);
    });
    
    // ... rest of the code
    
    만약 당신이 자세히 관찰한다면, 코드가 /scripts/client.js 방법에 추가 파라미터를 전달했다는 것을 이미 알아차렸을 것입니다. 우리는 아직 이 파라미터들을 소개하지 않았습니다!사실이 증명하듯이, 당신은 추가 선택 가능한 매개 변수를 사용할 수 있습니다.
    Deno.bundle(rootName [, sources] [, options])
    
    이 코드 예시는sources 옵션을 사용하지 않았지만, Deno documentation의 작업 원리를 볼 수 있습니다.
    마지막 Deno.bundle() 매개 변수를 제공합니다.이것은 options 유형의 옵션입니다. 이것은 TypeScript 컴파일러 옵션의 하위 집합이며 Deno가 지원하는 옵션을 포함합니다.
    이 프로그램은 Deno.CompilerOptions 옵션을 사용합니다. 이 옵션을 사용하면 컴파일에 포함할 라이브러리 파일 목록을 정의할 수 있습니다.이것은 코드의 특정 대상에 필요한 라이브러리를 정의할 수 있다는 것을 의미합니다. 예를 들어 일반적으로 브라우저에서 다음과 같은 내용을 정의합니다.
    const [diagnostics, emit] = await Deno.bundle(
      "main.ts",
      {
        "main.ts": `document.getElementById("foo");\n`,
      },
      {
        lib: ["dom", "esnext"],
      }
    );
    
    위의 코드 세그먼트에서, 우리는 데노에게 lib이라는 스크립트를 귀속시키라고 알려 주었다. 이 예에서 이 스크립트는 기존 파일이 아니라 main.ts 옵션을 사용하여 정의된 것이다. 그리고 일부 추가 컴파일러 sources은 컴파일러 목표에 DOM 라이브러리와 ESNext 지원이 필요하다는 것을 알려 준다.
    컴파일러 옵션에 대한 자세한 내용은 TypeScript compile options documentation에서 확인할 수 있습니다.

    React 응용 프로그램 실행


    코드의 주요 부분을 소개한 후(read through the rest에 방문하여 어떻게 작동하는지 보십시오!),우리 이 예시를 실행하고 결과를 봅시다!
    우선, 로컬 클론 options에서 재구매해야 합니다. 예를 들면:
    # Using SSH:
    git clone [email protected]:asos-craigmorten/opine.git
    
    # Using HTTPS:
    git clone https://github.com/asos-craigmorten/opine.git
    
    그런 다음 저장소를 현재 작업 디렉토리(예: Opine)로 설정하면 예제 설명 파일에서 사용할 수 있는 명령을 실행할 수 있습니다.
    $ deno run --allow-net --allow-read --unstable ./examples/react/server.tsx
    
    Check ~/opine/examples/react/server.tsx
    Opine started on port 3000
    
    만약 우리가 http://localhost:3000까지 브라우저를 열면, 우리는 우리의 응용 프로그램이 이미 시작되고 성공적으로 실행되었음을 볼 수 있습니다!🎉

    개발자 도구를 열면 네트워크 옵션 카드에서 프로그램이 서버에서 묶인 cd opine 파일을 성공적으로 가져오고 클라이언트에서 React를 실행하는 것을 볼 수 있습니다.

    축하합니다. 상대적으로 복잡한 프로그램을 성공적으로 실행했습니다. (데이터를 얻기 위해 궁금증을 사용합니다!)Deno 및 번들 기능 사용!🎉 🎉
    이 특정 예는 서버가 시작될 때 묶음 프로그램을 실행하는 것을 선택합니다.생산에서, 당신은 컴파일/묶음을 CI/CD의 선결 조건으로 삼을 가능성이 더 높지만, 모든 개념은 우리가 소개한 것과 같다!
    나는 이것이 유용하길 바란다.
    주의해야 할 점은 이 API들이 여전히 불안정으로 표시되어 있기 때문에 한 버전에서 다음 버전 사이에 변경되거나 중단된 것을 발견할 수 있지만 합리적인 양호한 상태이기 때문에 그럴 수 없습니다!신중해야 할 경우 CLI 명령은 안정적이므로 컴파일용 JavaScript 코드가 아닌 client.js을 항상 사용할 수 있습니다.
    클라이언트 코드를 어떻게 관리하고 Deno에 묶는지 보여주세요!다른 일을 하거나 일자리가 좋은 제3자 묶음 프로그램을 찾을까?다음 댓글에서 듣고 싶어요!
    다음까지!🦕

    좋은 웹페이지 즐겨찾기