Dico

webpack4 기본 설정 그리고 커스텀

  • Lovefield

안녕하세요 Lovefield 입니다.

이번에 회사에서 webpack을 적용할 일이 생겨서 공부도 해볼 겸 글도 써 볼겸 이것저것 테스트 한 것들을 서술하려 합니다 ㅎㅎ

우선 webpack 은 node.js 환경에서 돌아갑니다.

컴퓨터상에 node가 깔려있지 않으시다면 설치한 후에 사용하시기 바랍니다.

1. webpack 설치

webpack은 webpack4 부터 webpack-cli 와 같이 사용해야 하더군요.

터미널에서 다음과 같이 입력합니다.

npm i -g webpack webpack-cli

i : install의 약어

-g 글로벌 영역으로 설치

설치가 다 되었다면 구동을 위해 필요한 파일을 구성해봅시다.

npm init -y

터미널에서 위의 명령어로 package.json 을 생성해줍니다.

그리고 webpack.config.js 을 생성합니다.

webpack.config.js

const path = require('path');

module.exports = {
    mode : 'production',
    entry : {
        'common' : [
            './src/js/a.js',
            './src/js/b.js',
            './src/js/c.js'
        ]
    },
    output : {
        filename : '[name].js',
        path : path.resolve(__dirname,'common/js')
    }
}

가장 기본적인 구조입니다.

mode :  development 과 production이 있으며 개발용과 배포용입니다.

entry : 합쳐질 파일들의 경로를 입력하는 곳입니다.

output : 합쳐진 파일을 저장할 옵션들을 지정합니다.
 - filename :  저장할 파일 이름을 지정합니다, [name]을 사용시 위의 entry의 오브젝트 네임을 가져옵니다.

 - path : 저장할 파일의 경로를 지정합니다.

폴더구조

dir
 ㄴ common
 ㄴ node_modules
 ㄴ src

    ㄴ js

      - a.js

      - b.js

      - c.js

 - package.json

 - webpack.config.js

자 이제 터미널에서 webpack 을 치면 현재 폴더의 src/js 에 있는 a.js, b.js, c.js가 합쳐져서 common/js 폴더에 common.js 로 저장이 됩니다.

여기까지만 하면 정말 간단하게 webpack이 구동됩니다.

하지만 저는 css도 압축해야 했고, 폴더별로 관리도 되어야 했으며, output이 버전별로 나와야 했습니다.

2. css 추가하기

우선 css를인식하는 데 필요한 패키지들을 다운받는다.

npm i mini-css-extract-plugin css-loader 

그리고 webpack.config.js를 다음과 같이 수정합니다.

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode : 'production',
    entry : {
        'common' : [
            './src/js/a.js',
            './src/js/b.js',
            './src/js/c.js',
            './src/css/a.css',
            './src/css/b.css'
        ]
    },
    output : {
        filename : '[name].js',
        path : path.resolve(__dirname,'common')
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/[name].css'
        })
    ],
    module : {
        rules : [
            {
                test : /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                    ]
            }
        ]
    }
}

자 이제 터미널에서 webpack 을 실행하면 짜잔~ 하고 에러가 납니다.

망할 windows 같으니라고.

아마 webpack 모듈을 찾을 수 없다고 나올텐데요.

npm link webpack

터미널에서 위의 명령어를 이용해 모듈을 해당 폴더에 링크시킵니다.

상세한 설명은 다음 링크를 참조해주세요.

https://docs.npmjs.com/cli/link

그 외에도 오류가 나는 유형이 조금 많습니다.

원인을 찾지 못한 경우도 많아서 제가 적을 수가 없었는데요.

계속 모듈을 찾을 수 없다고 나오는 경우가 있습니다.

그럴 경우 저는 그냥 포기하고 처음부터 차근차근 다시 했습니다..

3. 폴더단위로 사용하기

폴더 단위로 사용하기 위해서는 glob 페키지가 필요합니다.

npm i glob

터미널에서 위의 명령어로 glob을 설치해줍니다.

이미 위에서 npm link webpack 을 쓰셨다면 위치가 변경되어 install이 정상적이지 않을 겁니다.

그럴 경우 node 관련 파일만 지우고 처음부터 다시 해주시면 됩니다.

그리고 webpack.config.js 를 다음과 같이 수정합니다.

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const glob = require('glob');

let jsSrc = glob.sync('./src/js/*.js');
let cssSrc = glob.sync('./src/js/*.css');
let fileSrc = jsSrc.concat(cssSrc);

module.exports = {
    mode : 'production',
    entry : {
        'common' : fileSrc
    },
    output : {
        filename : 'js/[name].js',
        path : path.resolve(__dirname,'common')
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/[name].css'
        })
    ],
    module : {
        rules : [
            {
                test : /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            }
        ]
    }
}

glob.sync 가 배열로 넘겨주기 때문에 두 타입의 배열을 받아 합쳐준후에 entry에 넣어줍니다.

자 이제 webpack 을 돌리면 폴더 내의 모든 js, css 파일이 압축되는걸 보실 수 있습니다.

4. command line 명령어 추가

사실 지금까지의 작업은 전부 작업된 폴더 내에서만 명령어가 먹습니다.

하지만 하위에 사이트 폴더가 여려 개 있다는 가정하에 webpack.config.js 을  일일히 수정해가면서 webpack 명령어를 치게되면 굉장히 불편하겟죠?

그래서 저는 command line에 명령어를 추가했습니다.

먼저 build.js 를 생성합니다.

const { spawn } = require('child_process');

var proc_webpack = spawn('webpack.cmd', [], {env:{'WP_DIRECTORY': process.argv[2]}});
proc_webpack.stdout.on('data', (str) => {
    console.log(''+str);
});
proc_webpack.stderr.on('data', (data) => {
    console.log(`stderr: ${data}`);
});

node 명령어를 실행할 때 뒤에 인자를 받아서 env에 저장합니다.

webpack.config.js 에서는 다음처럼 사용합니다.

let jsSrc = glob.sync(`${process.env.WP_DIRECTORY}/src/js/*.js`);
let cssSrc = glob.sync(`${process.env.WP_DIRECTORY}/src/css/*.css`);
let fileSrc = jsSrc.concat(cssSrc);

output : {
    path : path.resolve(process.env.WP_DIRECTORY,'common')
}

자 이제 명령어를 칠 차례입니다.

node build.js './site01'

위의 명령어를 치게되면,

site01 폴더 내에 있는 src/js 내의 모든 JS와

src/css 내의 모든 css를 합쳐서 

common 내의 각각 js, css 에 각각 common.js, common.css 파일이 생성됩니다.

5. output 버전 추가

사실 규정된 버저닝 관리는 없었습니다.

그냥 뒤에 날짜만 조금 붙일 뿐이었죠.

이글에 서술된 것처럼 날짜만 붙이거나, 위의 4번 항목처럼 command line 명령어에서 인자를 받아 쓸 수 있을 것 같습니다.

우선 날짜는 node에서 제공하는 dateformat 패키지를 사용했습니다.

npm i dateformat

터미널에서 위의 명령어로 설치한 후에 다음과 같이 사용할 수 있습니다.

const dateFormat = require('dateformat');
dateFormat(date,'yyyy-mm-dd HH:MM:ss')

출력 양식은 다음 링크를 참조해주세요.

https://www.npmjs.com/package/dateformat

6.minify 하기

webpack 에서 기본적으로 js 파일은 minify가 되지만 css는 그렇지 않습니다.

그래서 저는 css minify를 추가할 필요가 있었지요.

npm i uglifyjs-webpack-plugin optimize-css-assets-webpack-plugin

위의 명령어로 해당 패키지를 설치합니다.

webpack.config.js 에 다음과 같이 추가합니다.

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

optimization : {
    minimizer : [
        new UglifyJsPlugin({
            cache: true,
            parallel: 4
        }),
        new OptimizeCSSAssetsPlugin({})
    ]
}

해당 패키지 기능 들은 webpack4 에서  optimization으로 옮겨졋다고 하네요.

parallel 은 CPU 사용 수를 나타냅니다 :)