본문 바로가기
⚙️ 개발환경설정

Express에 Webpack & Babel 을 이용한 ES6 환경 설정 ( +generator 사용편)

by Tamii 2021. 3. 29.
반응형

브라우저 호환성 ( browser compatibility)

웹브라우저에서는 다양한 브라우저가 사용되고 있으며, 그 안에서 

caniuse.com/

 

Can I use... Support tables for HTML5, CSS3, etc

 

caniuse.com

↑ 브라우저 따른 사용 가능성을 확인할 수 있음

 

 


📌 브라우저 호환성을 높이는 몇가지 방안

🍎 polyfill

특정 기능이 지원되지 않는 브라우저를 위해 사용할 수있는 코드조각 or 플러그인

 

 

ex) bind 의 polyfill

bind는 ES5에서 추가되었는데, 만약 브라우저에 bind 기능이 없다면 , 아래 polyfill기능을 추가해 놓고 

후에 기능 추가가 되면 간단히 삭제하여 관리할 수 있다.

 

bind가 있지 않은 function 이라면? => 아래 코드를적용해라 

bind의 polyfill

출처:developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

 

 

 

🍎 Transpiling ( 트랜스파일 )

소스코드 -> 소스코드 변환

최신사양으로 작성된 코드를  기존 응용프로그램과 호환되는 코드로 변환함으써 오류 없이 작동할 수 있게 하는 활동

ex) Babel , Google Traceur...

 

ex) arrow function

arrow function 은 ES5에서 지원하지 않음

// ES 6
() => {}  

// ES 5
function() { } 

 

이런식으로 지원되지 않는 속성들을 이전 버전으로 변경해줌 

 

 


📌 Babel

하위브라우저가 지원가능하도록 transpiling 해줌

CLI를 지원하고 다양한  플러그인을 통해 브라우저 호환성을 관리할 수있음

 

bundle 파일을 만들어 배포

ES model 방식으로 코딩한 것의 관계를 분석한 후 -> bundel로 만들어줌 

 

Babel 기본 구성

{
  "presets": [
    
    ["@babel/preset-env", {"useBuiltIns":"entry", "corejs":3}],
    
    
    ["@babel/preset-react"]
  ],
  
  
  "plugins": [
    ["styled-jsx/babel", {"optimizeForSpeed": true, "vendorPrefixes": true, "sourceMaps": false}]
  ]
}

 

☻ presets

 

❖ babel/preset-env 타겟 브라우저에 필요한 구문변경, Polyfill을 제공하는 프리셋

  - useBuiltIns :entry (usage)

전체 import를 특정 모듈들의 import로 변경 
❖ babel/preset-react JSX코드를 React.CreateElement 호출 코드로 변환 

☻ Plugin

styled-jsx/babel styled-jsx 문법을 변환해주는 플러그인

 

Babel 설정 개선

 

{
    "presets": [
        [
            "@babel/preset-env",
            {
             "targets" : { 
                 "ie":11
             },
             "useBuiltIns" : "usage",
             "corejs" : {"version": 3, "proposals": true }
            }
        ]
    ],
    "plugins": []
}

@babel/preset-env

자주 사용한는 것들을 set로 만들어서 설정 가능하게 함 

IE 11 버전으로 만들어줘

 

"usage"

필요한 polyfill을 추가해주기 

ex) flat사용 -> 

 

corejs

전역 스코프를 오염시키지 않는 corejs 3 버전

 

 

 


📌 Webpack 

출처: https://webpack.js.org/

JavaScript Application module bundler

한 시스템에는 많은 JavaScript 파일이 존재하는데 이 파일들을 하나의 bundle로 묶어서 관리하게 함 

ex) babel 사용시 - babel을 돌리며 module들을 transpiling하며 읽어줘 bundle로 만듦

ex) 비슷한 도구 :  Browsify(속도 더 느림) , Grunt, Gulp ( dependency 개념 없음)  ...

 

⭐️ bundle 

 : SW와 HW가 함꼐 작동하는데 필요한것을 포함하는 package

 : 각 모듈들의 의존성 관계를 파악하고 어필 

 

 

 

 

🙂 webpack.config.js와 함께보는 webpack구성 

 

☻ entry

dependency 관계를 만들기 위한 input source 

module.exports = {
  entry: './src/app.js'
 }

 

☻ output 

webpack 한 결과물 위치 지정 

const path = require('path');

module.exports = {

  entry: './src/app.js',
  output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'bundle.js',
      
    },

 -> dist 디렉토리에 bundle.js의 이름으로 저장

 

☻ loader

webpack은 원래 javascriptjson 만 이해함

다른 타입의 파일들을 webpack 이 이해하고 처리가능한 모듈로 변환 시킴

 ( import 들을 분석해 .js?변환! )

const path = require('path');

module.exports = {

  entry: './src/app.js',
  
  output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'bundle.js',
    },
  
  
  module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader',
                exclude: /node_modules/
            }, 
            {
                test: /\.css$/i,
                use: ["style-loader", "css-loader"],
            }
            ,
        ]
    },
 };
 
 

.js 파일 : node_modules 제외하고 babel-loader를 이용

.css 파일: style-loader, css-loader를 이용

 

☻ plugin

bundel 된결과 (최종파일)의 후속처리 

주석, 공백, console... 지워주는

모듈의 의존성을 파악해서 모듈방식의 프로그래밍을 더 잘 할 수 잇음

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

  entry: './src/app.js',
  
  output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'bundle.js',
    },
    ...

    plugins: [new HtmlWebpackPlugin(
        {
            template: 'src/app.html' //템플릿 경로 지정
        }
    )]
};

HtmlWebpackPlugin :  HTML 파일로 output (dist/ bundle.js) 에 생성

HTML 파일을 후처리하고 빌드타임의 값을 넣거나 코드를 압축

loaders plugin
파일단위로 해석하고 변환하는 과정에 모듈 처리 bundle된 결과물의 형태를 처리

HtmlWebpackPlugin 외에도 자주 사용하는 플러그인들을 확인하고 사용할 수 있다.

다양한 플러그인 참고 링크 : bogyum-uncle.tistory.com/112

 

 


 

개발환경을 직접 구축해보자❗️ 

* Webpack 구성

* Babel 포함 

* express -generator 사용 

 

local 설치 global 설치 (-g)
Nodejs 프로젝트 하위 > node_modules 설치 계정 하위 APP data에 node_modules 설치
모든 프로젝트에서 공유해 해당 모듈 사용 가능

 

1️⃣ npm 프로젝트 생성  (express-generator 이용)

node_modules , package.json 

sudo npm i -g express-generator //mac 유저라 sudo 권한으로 global 프로그램 설치

// express <프젝name> --view=ejs // 템플릿 엔진 ejs 로 생성 ( --veiw=pug .. 가능)
express testenv --view=ejs 
cd  testenv
npm install
npm run start // 서버 동작 확인 가능 

 

 

 


2️⃣ Babel 설치 

2-1) Babel 설치

babel 필수 모듈 설치

npm install @babel/core @babel/cli @babel/preset-env --save-dev 

2-2) 파일구조 변경 및 app.js 수정 

src/index.html : 웹 화면 구성

public/main.js : main javascript

 

 

 

 

 

 

 

 

 

 

 

 

index.htm예시

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1 class="hi">hello world</h1>
    <div class="wrap">
        <div id="log"></div>
    </div >
    <script src="../dist/bundle.js"></script>
</body>
</html>

main.js 예시

import MainService from './Js/mainService.js';

window.addEventListener("DOMContentLoaded", ()=> {
    const targetEl = document.querySelector("#log");

    const service = new MainService({targetEl})
    const datalist = [1,2,3,4,[5,6,[7]]];
    const subHtml = service.init(datalist);

    targetEl.innerHTML += `datalist is ${subHtml}`;
})

mainService.js 예시

export default class MainService  {
    constructor({targetEl}) {
        this.targetEl = targetEl;
        this.dataList = "";
    }

    init(dataList) {
        this.dataList = dataList.flat(2).join('');
        return this.render(this.dataList);
    }

    render(data) {
        return `<span>${data}</span>`
    }

}

 

2-3) babel.config.json  파일 생성

IE 11 에서 지원가능 하도록 transpiling

presets(plugin의 집합) , plugin 

// 1) 타깃브라우저에 필요한 플러그인만 삽입하도록 설정하는 옵션
{
  "presets": [
    ["@babel/preset-env", {
      "targets": "> 0.25%, not dead"
    }],
  ]
}


//2) 타겟 브라우저 설정하는 버전 
{
    "presets": [
        [
            "@babel/preset-env",
            {
             "targets" : { 
                 "ie":11
             },
             "useBuiltIns" : "usage",
             "corejs" : {"version": 3, "proposals": true }
            }
        ]
    ],
    "plugins": []
}

targets:  원하는 브라우저 범위 설정 가능

npx babel public/javascripts/main.js //babel 변환 여부 확인

 

Polyfill 설정

npm install --save core-js@3

 

 

 

 

 


3️⃣ webpack 설치 

--save-dev --save (-S)
package.json 의 devDependencies에 포함
개발시에만 포함되고 배포시 publishing에 포함되지 않음 
package.json의 dependencies에 포함
배포시점에 함께 publishing 됨 
npm install webpack webpack-cli --save-dev
npx webpack//아직은 오류

webpack 은 서버를 실행시키는 것은 아님

단, 연동해줄 수 있는 방법이 있음 

 

3-1) webpack.config.js  파일 생성

const path = require('path');

module.exports = {
    mode: "development",//개발모드
    entry: ['./public/main.js', './public/style/index.css' ],//entry point(분석할 진입점)
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js",
    },
    
  }
//웹팩 첫 실행 
npx webpack -w 

dist/디렉토리에 bundle.js 파일 생성 확인 

 

app.js에  추가

app.use(express.static(path.join(__dirname, 'dist')));

 

3-2) Webpack에 Babel연동 

webpack 에 바벨을 load 해서 사용해야 함

npm install babel-loader --save-dev

webpack.config.js 에 module 항목과 rule 추가.

const path = require('path');


module.exports = {
    mode: "development",
    entry: ['./public/main.js', './public/style/index.css' ],
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js",
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader',
                exclude: /node_modules/
            }, 
            {
                test: /\.css$/i,
                use: ["style-loader", "css-loader"],
            }
            ,
        ]
    },
    
 };

test 가 .js로 긑나면 바벨 로더가 처리

node_modules 제외 htmlwebpackplugin

 

css 변환을 위한 loader 추가 

npm i --save-dev css-loader
npm i --save-dev stylep-loader

 

3-3) webpack 에 plugin 추가

npm install --save-dev html-webpack-plugin
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');


module.exports = {
    mode: "development",
    entry: ['./public/main.js', './public/style/index.css' ],
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js",
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader',
                exclude: /node_modules/
            }, 
            {
                test: /\.css$/i,
                use: ["style-loader", "css-loader"],
            }
            ,
        ]
    },
    plugins: [new HtmlWebpackPlugin(
        {
            template: 'src/index.html'
        }
        
    )]
}

+ devtool추가를 통한 크롬 디버거 사용 가능

module.exports = {
    mode: "development",
    entry: ['./public/main.js', './public/style/index.css' ],
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js",
    },
    devtool: 'inline-source-map',
    module: { ...

위와 같이 devtool을 추가하게 되면 

크롬개발자도구 - Sources - . 디렉토리에서  bundle 되기전 코드를 이용하여 디버깅이 가능하다.

 

 

4️⃣ Package.json 수정

 

이처럼 scripts 를 설정한 뒤 

실행 시 두 명령어를 실행시키면  web이 나타나게 된다! 

 

 

npm run start // express 서버 실행
npm run build // wepback 실행

 

댓글