esbuild 사용해보자! (+ yarn berry)

Bard·2022년 1월 23일
2
post-thumbnail

시작한 계기

RisingStars 에서 Esbuild 를 접하고 흥미가 생겼다

RisingStars

프로젝트 시작

프로젝트 파일 생성

mkdir apple-store

프로젝트 파일 생성

cd apple-store

yarn 버전 변경

yarn set version berry

packageManager 초기화

yarn init -y

esbuild 번들러 추가

yarn add -D esbuild

의존성 추가

yarn add react react-dom

개발 의존성 추가

yarn add -D @types/react @types/react-dom typescript

tsc 초기화

tsc --init

index.html 추가

mkdir public
touch public/index.html

index.html 수정

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="bundle.js"></script>
  </body>
</html>

src 및 App.tsx 추가

mkdir src
touch src/App.tsx

App.tsx 수정

import React, { useCallback, useState } from "react";
import ReactDOM from "react-dom";

const App = (props: { message: string }) => {
  const [count, setCount] = useState(0);
  const increment = useCallback(() => {
    setCount((count) => count + 1);
  }, [count]);

  return (
    <>
      <h1>{props.message}</h1>
      <h2>Count: {count}</h2>
      <button onClick={increment}>Increment</button>
    </>
  );
};

ReactDOM.render(<App message="Hello" />, document.getElementById("root"));

이때 나오는 에러는 아래 방법을 통해 해결

  1. vscode extention ZipFS 추가
  2. yarn dlx @yarnpkg/sdks vscode
  3. ctrl+shift+p
  4. "Typescript: Select Typescript Version"
  5. Pick "Use Workspace Version"
  6. tsconfig - "jsx": "react" 추가

YARN 공식문서

스크립트 추가

{
	...,
	"scripts": {
	    "build": "yarn build"
	}
}

스크립트 파일 추가

mkdir scripts
touch scripts/esbuild.config.js

스크립트 파일 수정

import { build } from "esbuild";

build({
  bundle: true,
  minify: true,
  platform: "node",
  entryPoints: ["./src/App.tsx"],
  outfile: "./public/bundle.js",
  target: "es2020",
});

yarn build

1. 에러

> yarn build
(node:20154) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Volumes/workspace/test/scripts/esbuild.config.js:1
import { build } from "esbuild";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:1001:16)
    at Module._compile (internal/modules/cjs/loader.js:1049:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.external_module_.Module._load (/Volumes/workspace/test/.pnp.cjs:9924:14)
    at Function.moduleExports.runMain (/Volumes/workspace/test/.pnp.cjs:10125:31)
    at internal/main/run_main_module.js:17:47

안내에 나온대로 package.json "type": "module" 추가

2. 에러

> yarn build
internal/process/esm_loader.js:74
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'esbuild' imported from /Volumes/workspace/test/scripts/esbuild.config.js
Did you mean to import esbuild-npm-0.14.13-30b05edbe8/node_modules/esbuild/lib/main.js?
    at packageResolve (internal/modules/esm/resolve.js:650:9)
    at moduleResolve (internal/modules/esm/resolve.js:691:18)
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:805:11)
    at Loader.resolve (internal/modules/esm/loader.js:88:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:241:28)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:72:40)
    at link (internal/modules/esm/module_job.js:71:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

esbuild 가 yarn berry 방식의 의존성 패키지 관리 방식을 이해하기 위해 플러그인 추가

yarn add -D @yarnpkg/esbuild-plugin-pnp
import { build } from "esbuild";
import { pnpPlugin } from "@yarnpkg/esbuild-plugin-pnp";

build({
  bundle: true,
  minify: true,
  platform: "node",
  entryPoints: ["./src/App.tsx"],
  outfile: "./public/bundle.js",
  target: "es2020",
  sourcemap: true,
  plugins: [pnpPlugin()],
});

다시 build

확인

open public/index.html
  • 에러 확인
index.js:3 Uncaught ReferenceError: process is not defined
    at index.js:3:5
    at bundle.js:1:250
    at App.tsx:1:46
let definePlugin = {
  name: 'auto-node-env',
  setup(build) {
    const options = build.initialOptions
    options.define = options.define || {}
    options.define['process.env.NODE_ENV'] =
      options.minify ? '"production"' : '"development"'
  },
}

define 옵션 추가
참고

완성

후기

만들어진 Boilerplate 에서 작업하다가 처음부터 하려니까 생각보다 시간이 소요됐다

추가로 esbuild 를 활용하는 vite 라는 프레임워크를 사용해도 괜찮을 거 같다

vite

profile
영차영차🐢

0개의 댓글