Authoring Libraries

애플리케이션 외에도 JavaScript 라이브러리를 번들링 할 때도 webpack을 사용할 수 있습니다. 아래의 가이드는 번들링 전략을 간소화하려는 라이브러리 작성자를 위한 것입니다.

Authoring a Library

사용자가 1부터 5까지의 숫자를 숫자 표현에서 텍스트로 또는 그 반대로 변환할 수 있는 작은 라이브러리 webpack-numbers를 작성한다고 가정해 보겠습니다. 예. 2 에서 'two'.

프로젝트의 기본 구조는 다음과 같을 것입니다.

project

+ ├── webpack.config.js
+ ├── package.json
+ └── /src
+     ├── index.js
+     └── ref.json

npm을 초기화하고 webpack, webpack-cli, lodash를 설치합니다.

npm init -y
npm install --save-dev webpack webpack-cli lodash

라이브러리에 번들 되는 것을 막고 라이브러리가 비대해지는 것을 방지하기 위해 lodashdependencies 대신 devDependencies로 설치합니다.

src/ref.json

[
  {
    "num": 1,
    "word": "One"
  },
  {
    "num": 2,
    "word": "Two"
  },
  {
    "num": 3,
    "word": "Three"
  },
  {
    "num": 4,
    "word": "Four"
  },
  {
    "num": 5,
    "word": "Five"
  },
  {
    "num": 0,
    "word": "Zero"
  }
]

src/index.js

import _ from "lodash";
import numRef from "./ref.json";

export function numToWord(num) {
  return _.reduce(
    numRef,
    (accum, ref) => (ref.num === num ? ref.word : accum),
    "",
  );
}

export function wordToNum(word) {
  return _.reduce(
    numRef,
    (accum, ref) => (ref.word === word && word.toLowerCase() ? ref.num : accum),
    -1,
  );
}

Webpack Configuration

아래의 기본적인 webpack 설정으로 시작해봅시다.

webpack.config.js

import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "webpack-numbers.js",
  },
};

webpack으로 애플리케이션을 번들해보았다면 익숙할 것입니다. 기본적으로 webpack에게 src/index.jsdist/webpack-numbers.js로 번들하도록 지시합니다.

Adding Source Maps

When bundling a library, it is recommended to generate source maps. Source maps allow consumers of your library to debug your original source code rather than the minified bundle. This can be done using the devtool option:

webpack.config.js

  import path from 'node:path';
  import { fileURLToPath } from 'node:url';

  const __filename = fileURLToPath(import.meta.url);
  const __dirname = path.dirname(__filename);

  export default {
    entry: './src/index.js',
+   devtool: 'source-map',
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'webpack-numbers.js',
    },
  };

Expose the Library

지금까지는 애플리케이션 번들링과 동일하며 다른 점은 output.library 옵션을 통해 엔트리 포인트를 export 해야 합니다.

webpack.config.js

  import path from 'node:path';
  import { fileURLToPath } from 'node:url';

  const __filename = fileURLToPath(import.meta.url);
  const __dirname = path.dirname(__filename);

  export default {
    entry: './src/index.js',
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'webpack-numbers.js',
+     library: 'webpackNumbers',
    },
  };

사용자가 script 태그를 통해 사용할 수 있도록 엔트리 포인트를 webpackNumbers로 export 했습니다.

<script src="https://example.org/webpack-numbers.js"></script>
<script>
  window.webpackNumbers.wordToNum("Five");
</script>

그러나, script 태그를 통해 참조될 때만 작동하며 CommonJS, AMD, Node.js 등과 같은 다른 환경에서는 사용할 수 없습니다.

라이브러리 작성자는 다양한 환경에서 호환되기를 원합니다. 즉, 사용자가 아래 나열된 여러 방법으로 번들 된 라이브러리를 사용할 수 있어야 합니다.

  • CommonJS module require:

    const webpackNumbers = require("webpack-numbers");
    
    // ...
    webpackNumbers.wordToNum("Two");
  • AMD module require:

    require(["webpackNumbers"], (webpackNumbers) => {
      // ...
      webpackNumbers.wordToNum("Two");
    });
  • script tag:

    <!DOCTYPE html>
    <html>
      ...
      <script src="https://example.org/webpack-numbers.js"></script>
      <script>
        // ...
        // 전역 변수
        webpackNumbers.wordToNum("Five");
        // window 객체의 프로퍼티
        window.webpackNumbers.wordToNum("Five");
        // ...
      </script>
    </html>

type'umd'로 설정하여 output.library 옵션을 업데이트해 보겠습니다.

 import path from 'node:path';
 import { fileURLToPath } from 'node:url';

 const __filename = fileURLToPath(import.meta.url);
 const __dirname = path.dirname(__filename);

 export default {
   entry: './src/index.js',
   output: {
     path: path.resolve(__dirname, 'dist'),
     filename: 'webpack-numbers.js',
-    library: 'webpackNumbers',
+    globalObject: 'this',
+    library: {
+      name: 'webpackNumbers',
+      type: 'umd',
+    },
   },
 };

webpack은 라이브러리를 CommonJS, AMD, script 태그에서 사용할 수 있도록 번들할 것입니다.

Externalize Lodash

npx webpack을 실행하면 큰 번들이 생성 된 것을 알 수 있습니다. 파일을 검사하면 lodash가 코드와 함께 번들로 제공되는 것을 볼 수 있습니다. 이 경우 lodashpeer dependency 로 취급하는 것이 좋습니다. 사용자는 이미 lodash가 설치되어 있어야합니다. 따라서 이 외부 라이브러리의 제어권을 라이브러리 사용자에게 넘겨야합니다.

externals 설정을 사용하면 됩니다.

webpack.config.js

  import path from 'node:path';
  import { fileURLToPath } from 'node:url';

  const __filename = fileURLToPath(import.meta.url);
  const __dirname = path.dirname(__filename);

  export default {
    entry: './src/index.js',
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'webpack-numbers.js',
      library: {
        name: 'webpackNumbers',
        type: 'umd',
      },
    },
+   externals: {
+     lodash: {
+       commonjs: 'lodash',
+       commonjs2: 'lodash',
+       amd: 'lodash',
+       root: '_',
+     },
+   },
  };

이는 라이브러리가 사용자 환경에서 lodash라는 종속성을 사용할 수 있다고 예상한다는 것을 의미합니다.

External Limitations

종속성에서 여러 파일을 사용하는 라이브러리의 경우:

import A from "library/one";
import B from "library/two";

// ...

externals에서 library를 지정하여 번들에서 제외할 수 없습니다. 하나씩 또는 정규식을 사용하여 제외해야 합니다.

export default {
  // ...
  externals: [
    "library/one",
    "library/two",
    // "library/"로 시작하는 모든 것
    /^library\/.+$/,
  ],
};

Final Steps

프로덕션 가이드에 언급된 단계에 따라 프로덕션에 맞게 출력을 최적화하세요. 또한 생성된 번들의 경로를 package.jsonmain 필드에 추가하세요.

package.json

{
  ...
  "main": "dist/webpack-numbers.js",
  ...
}

또는 이 가이드에 따라 표준 모듈로 추가하세요.

{
  ...
  "module": "src/index.js",
  ...
}

mainpackage.json의 표준을, module은 JavaScript 생태계 업그레이드가 하위 호환성을 깨지 않고 ES2015 모듈을 사용할 수 있도록 하는 제안[1] [2]을 의미합니다.

이제 사용자에게 배포하기 위해 npm 패키지로 게시하고 unpkg.com에서 찾을 수 있습니다.

Edit this page·

11 Contributors

pksjcejohnstewsimon045angelmarioaccbyzykEugeneHlushkoAnayaDesignchenxsanwizardofhogwartsDebraj2024

Translators