Contents

Webpack5 μ„€μ •ν•˜κΈ° (ESM)

νšŒμ‚¬μ—μ„œ Javascript 용 μ„œλΉ„μŠ€ SDKλ₯Ό κ°œλ°œν•˜λ©΄μ„œ μ„€μ •ν–ˆλ˜ webpack5 μ„€μ •νŒŒμΌμ„ κΈ°λ‘ν•œλ‹€. μ˜€λž˜μ „μ— 잠깐 μ ‘ν•΄λ³΄μ•˜λ˜κ²Œ webpack2 λ²„μ „μ΄μ—ˆλŠ”λ° μ–΄λŠμƒˆ 5κΉŒμ§€ λ‚˜μ™”λ‹€. μ•Œκ³  μ‚¬μš©ν•˜λŠ”κ²Œ μ•„λ‹ˆλ‹€λ³΄λ‹ˆ μ“°λ©΄μ„œ μ• λ₯Ό λ¨Ήμ—ˆλ‹€…πŸ₯ΊπŸ₯ΊπŸ₯Ί

Webpack5 μ„€μ •ν•˜κΈ° (ESM μ‚¬μš©)

νšŒμ‚¬μ—μ„œ κ°œλ°œν•œ SDKλŠ” CJS(CommonJS)μ—μ„œ ESM(ECMAScript Module) λͺ¨λ“ˆ 방식을 μ‚¬μš©ν•˜μ—¬ κ°œλ°œν–ˆλ‹€. ESM λͺ¨λ“ˆ λ‘œλ” μ‚¬μš©ν•˜κΈ° μœ„ν•΄ package.json에 μ•„λž˜ 섀정을 μΆ”κ°€ν–ˆλ‹€.

package.json

1
"type": "module"

μ•„λž˜ κΈ€μ—μ„œλŠ” CJSκ°€ 기본값이기 λ•Œλ¬Έμ— 라이브러리의 경우 CJS둜 κ°œλ°œν•˜λŠ” 것을 μΆ”μ²œν•˜κ³  μžˆλ‹€.

μ„€μΉ˜ 라이브러리

1
npm install --save-dev webpack webpack-cli webpack-merge webpack-stream
  • webpack-merge
    • μ›ΉνŒ© 섀정을 ν•˜λ‚˜λ‘œ λ³‘ν•©ν•΄μ£ΌλŠ” 라이브러리. μ›ΉνŒ© 섀정을 개발용과 배포용으둜 λ‚˜λˆ„κΈ° μœ„ν•΄ μ μš©ν–ˆλ‹€.
  • webpack-stream
    • νƒœμŠ€ν¬ λŸ¬λ„ˆλŠ” gulpλ₯Ό μ‚¬μš©ν•˜κ³  μžˆλ‹€. gulpμ—μ„œ μ›ΉνŒ©μ„ λͺ¨λ“ˆλ§μž‘업을 μΆ”κ°€ ν•˜κΈ° μœ„ν•΄ μ„€μΉ˜ν–ˆλ‹€.

webpack.config.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import webpack from "webpack";

const webpack5esmInteropRule = {
    test: /\.m?js/,
    resolve: {
        fullySpecified: false
    }
}

const config = {
    target: ['web', 'es5'],
    entry: {
        main: "./entries-webpack.js",
    },
    output: {
        filename: "tychain.min.js"
    },
    resolve: {
        modules: ['node_modules'],
        fallback: {
            assert: false,
            buffer: await Promise.resolve('buffer'),
            console: false,
            constants: false,
            crypto: await Promise.resolve('crypto-browserify'),
            domain: false,
            events: false,
            fs: false,
            http: false,
            https: false,
            os: false,
            path: false,
            punycode: false,
            process: false,
            querystring: false,
            stream: await Promise.resolve('stream-browserify'),
            string_decoder: false,
            sys: false,
            timers: false,
            tty: false,
            url: false,
            util: false,
            vm: false,
            zlib: false,
        }
    },
    module: {
        rules: [
            webpack5esmInteropRule,
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ["@babel/preset-env"],
                        plugins: ["@babel/plugin-proposal-class-properties"]
                    }
                }
            },
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({
           Buffer: ['buffer', 'Buffer'],
           ndcrypto: ['crypto', 'ndcrypto'],

        }),
    ],
    optimization: {
        concatenateModules: true
    }
}
export default config;

target

  • μ›ΉνŒ©μ€ μ—¬λŸ¬ ν™˜κ²½κ³Ό νƒ€μΌ“μœΌλ‘œ 컴파일 ν•  수 μžˆλ‹€.
  • Targets|webpack

entry

  • entryλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ²ˆλ“€λ¦¬ν•  λ•Œ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹œμž‘ν•  지점이닀.
  • Entry and Context|webpack

output

  • output은 컴파일 된 λ²ˆλ“€νŒŒμΌκ³Ό λ¦¬μ†ŒμŠ€λ₯Ό μ–΄λŠ κ²½λ‘œμ— μ–΄λ–€ μ΄λ¦„μœΌλ‘œ 생성할지 지정할 수 μžˆλ‹€. entryλŠ” μ—¬λŸ¬ 지점이 μžˆμ„ 수 μžˆμ§€λ§Œ output은 ν•˜λ‚˜μ˜ κ΅¬μ„±λ§Œ 지정할 수 μžˆλ‹€.
  • Output|webpack

resolve

  • resolve μ˜΅μ…˜μ€ λͺ¨λ“ˆμ„ ν•΄μ„ν•˜λŠ” 방식을 지정할 수 μžˆλ‹€.

resolve.modules

  • λͺ¨λ“ˆμ„ 해석할 λ•Œ 검색할 디렉터리λ₯Ό μ›ΉνŒ©μ— μ•Œλ €μ€€λ‹€. μƒλŒ€κ²½λ‘œλŠ” nodeκ°€ ν˜„μž¬ 디렉터리와 μƒμœ„ 디렉터리λ₯Ό 톡해 node_modeulsλ₯Ό κ²€μƒ‰ν•˜λŠ” 방법과 μœ μ‚¬ν•˜κ²Œ κ²€μƒ‰λ˜λ©°, μ ˆλŒ€κ²½λ‘œλŠ” 였직 주어진 λ””λ ‰ν„°λ¦¬μ—μ„œλ§Œ κ²€μƒ‰ν•œλ‹€.

webpack.config.js

1
2
3
4
5
6
module.exports = {
  //...
  resolve: {
    modules: ['node_modules'],
  },
};

webpack.config.js

1
2
3
4
5
6
7
8
const path = require('path');

module.exports = {
  //...
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
  },
};

resolve.fallback

webpack5μ—μ„œλŠ” Node.js μ½”μ–΄ λͺ¨λ“ˆμ— λŒ€ν•΄ μžλ™ polyfill을 μ œκ³΅ν•˜μ§€ μ•ŠλŠ”λ‹€. κ·ΈλŸ¬λ―€λ‘œ λΈŒλΌμš°μ €μ—μ„œ μ‹€ν–‰λ˜λŠ” μ½”λ“œμ—μ„œ μ‚¬μš©ν•˜λŠ” 경우 npm λͺ¨λ“ˆμ„ 직접 μ„€μΉ˜ν•˜κ³  포함해야 ν•œλ‹€.

λ‹€μŒμ€ webpack 5 이전에 webpack이 μ‚¬μš©ν•œ polyfill λͺ©λ‘μ΄λ‹€. νšŒμ‚¬μ—μ„œλŠ” λͺ¨λ“  μ„€μ •νŒŒμΌλ„ ESM λ°©μ‹μœΌλ‘œ webpack.conf.js 파일 λ˜ν•œ ESM으둜 μž‘μ„±λ˜μ—ˆλ‹€. ESM의 경우 μ•„λž˜μ™€ 같이 μ„€μ •ν•œλ‹€.

1
crypto: await Promise.resolve('crypto-browserify'),
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
resolve: {
    fallback: {
      assert: require.resolve('assert'),
      buffer: require.resolve('buffer'),
      console: require.resolve('console-browserify'),
      constants: require.resolve('constants-browserify'),
      crypto: require.resolve('crypto-browserify'),
      domain: require.resolve('domain-browser'),
      events: require.resolve('events'),
      http: require.resolve('stream-http'),
      https: require.resolve('https-browserify'),
      os: require.resolve('os-browserify/browser'),
      path: require.resolve('path-browserify'),
      punycode: require.resolve('punycode'),
      process: require.resolve('process/browser'),
      querystring: require.resolve('querystring-es3'),
      stream: require.resolve('stream-browserify'),
      string_decoder: require.resolve('string_decoder'),
      sys: require.resolve('util'),
      timers: require.resolve('timers-browserify'),
      tty: require.resolve('tty-browserify'),
      url: require.resolve('url'),
      util: require.resolve('util'),
      vm: require.resolve('vm-browserify'),
      zlib: require.resolve('browserify-zlib'),
    },
},

To Do

  • CJS, ESM

Reference