loader란


로더는 파일을 다른언어(예:TypeScript)에서 javascript로 변환하거나 인라인 이미지를 데이터 URL로 로드할 수 있습니다. 로더를 사용하면 import javascript 모듈에서 직접 CSS, HTML 파일과 같은 작업을 수행할 수 있습니다.


loader의 기능


  • 로더는 Node.js에서 실행되며, 가능한 모든 작업을 수행할 수 있습니다.
  • 로더를 연결할 수 있으며, 체인의 각 로더는 처리된 리소스에 변환을 적용합니다. 체인은 역순으로 실행됩니다. 첫 번째 로더의 결과를 다음 로더에 전달하는 식으로 진행합니다. webpack은 마지막 로더가 Javascript로 변환할 것으로 예상합니다.
  • 플러그인로더에게 더 많은 기능을 제공합니다.


loader의 사용


애플리케이션에서 로더를 사용하는 방법은 두 가지 방법이 있습니다.

  1. Configuration(권장) : webpack.config.js 파일에 로더를 지정합니다.
  2. Inline : 각 import문에 명시적으로 지정합니다.

webpack에서 권장하는 1번 방법만 포스팅하였습니다.


Configuration(권장) 작성 방법


  • module.rules(배열)로 webpack 구성 내에서 여러 로더를 지정할 수 있습니다. 이 방법은 로더를 표시하는 간결한 방법이고 깨끗한 코드를 유지하는데 도움이 됩니다.
  • 로더는 오른쪽에서 왼쪽으로(또는 아래에서 위로) 실행됩니다. 즉, 역순으로 실행됩니다

예시 :

    module.exports = {
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: [
                    // 세 번쨰로 실행됩니다.
                    { loader: 'style-loader' },
                    // 두 번쨰로 실행됩니다.
                    {
                        loader: 'css-loader',
                        options: {
                        modules: true
                        }
                    },
                    // 첫 번쨰로 실행됩니다.
                    { loader: 'sass-loader' }
                    ]
                }
            ]
        }
    };

    module.exports = {
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: [
                        'style-loader', // 세 번쨰로 실행됩니다.
                        'css-loader', // 두 번쨰로 실행됩니다.
                        'sass-loader' // 첫 번쨰로 실행됩니다.
                    ]
                }
            ]
        }
    };


작성 TIP


  1. loader들을 단순하게 유지
  2. 체이닝을 활용,
  3. 모듈식 출력으로 내보내야 합니다. 로더 생성 모듈은 일반 모듈과 동일한 설게 원칙을 준수해야 합니다.
  4. 프로젝트의 루트가 이동할 때 해싱을 중단하므로 모듈 코드에 절대경로를 삽입하지 마세요.


로더의 동작원리를 이해하기 위해 직접 만들어보기


로더에 사용되는 모듈형식은 표준 모듈 시스템이 아닌 webpack에서 사용하는 모듈을 사용합니다.

webpack.config.js에서

test는 로딩에 적용할 파일 확장자를 지정합니다. .js 확장자를 갖는 파일을 모두 처리합니다.
usetest에서 적용한 파일들을 처리할 로드를 설정합니다. 방금 만든 myloader를 지정합니다.

로더는 .js를 갖는 모든 파일을 읽어 함수 인자 content로 전달됩니다.
전달받은 content에는 무엇이 있는지 확인해보기 위해 console.log를 찍어보겠습니다.

    module.exports = function myloader(content){
        console.log('content 시작');
        console.log(content);
        console.log('content 종료');
        console.log('\n');
        return content;
    }
    const path = require('path');

    module.exports = {
        mode : 'development',
        entry : {
            main : './src/app.js'
        },
        output : {
            path : path.resolve('./dist'),
            filename : '[name].js'
        },
        module : {
            rules : [{
                test: /\.js$/,
                use: [path.resolve('./myloader.js')]
            }]
        }
    }
    import * as math from './math.js'

    console.log(math.sum(1, 2));
    export function sum(a, b){
        return a + b;
    }
    <!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>
        <script src="./dist/main.js"></script>
    </body>
    </html>


webpack build :

  • webpackbuild 할 때 모든 .js 파일을 로드하여 myloader 모듈에 넘겨 변환 합니다.
  • 첫 번쨰로, app.js를 content로 넘겨받아 리턴
  • 두 번쨰로 math.js를 content로 넘겨받아 리턴
    > npm run build

   > webpack-demo@1.0.0 build
    > webpack

    content 시작
    import * as math from './math.js'

    console.log(math.sum(1, 2));
    content 종료


    content 시작
    export function sum(a, b){
        return a + b;
    }
    content 종료


    asset main.js 4.09 KiB [compared for emit] (name: main)
    runtime modules 670 bytes 3 modules
    cacheable modules 113 bytes
    ./src/app.js 65 bytes [built] [code generated]
    ./src/math.js 48 bytes [built] [code generated]
    webpack 5.65.0 compiled successfully in 277 ms


[.js] 소스코드 변환해보기

  • "console.log(" -> "alart(" 로 수정하여 알람창이 뜨게 수정해봅시다.
    module.exports = function myloader(content){
        console.log('content 시작');
        console.log(content);
        console.log('content 종료');
        console.log('\n');
        return return content.replace("console.log(", "alert(");
    }

결과 :

image