FE

webpack

Chars4785 2021. 4. 1. 14:02

정의

웹팩이란 최신 프런트엔드 프레임워크에서 가장 많이 사용되는 모듈 번들러(Module Bundler)입니다. 모듈 번들러란 웹 애플리케이션을 구성하는 자원(HTML, CSS, Javscript, Images 등)을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구를 의미합니다.

Webpack의 두가지 핵심철학:

- 모든것은 module이다.

- JS 파일들은 모듈이 될수 있다.

또한 다른 모든 것들도(html, images,.. )들도 모듈이 될수 있다. 필요한 것 그리고 필요할 때 불러진다. 


필요한 이유

- 파일 단위의 자바스크립트 모듈 관리의 필요성

- 웹 개발 작업 자동화 도구

- 웹 애플리케이션의 빠른 로딩 속도와 높은 성능

npm i webpack webpack-cli webpack-dev-server html-webpack-plugin -D

- webpack

- webpack-dev-server

- html-webpack-plugin-D

- webpack-cli

 

1. webpack

모듈 번들러, 웹 애플리케이션을 구성하는 자원 (html, css, js, image ..등) 을 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구

 

기존의 문제점은 다음 4가지 해결하기 위해 웹팩 필요

  • 자바스크립트 변수 유효 범위
  • 브라우저별 HTTP 요청 숫자의 제약
  • 사용하지 않는 코드의 관리
  • Dynamic Loading & Lazy Loading 미지원

2. webpack-dev-server

번들 파일 만드는것 대신, 메모리에 번들 파일을 만들어 준다. 

3. html-webpack-plugin

script tage 사용하는 body 안에 webpack 포함 시켜주도록 한다.

 


package.json

{
  "name": "test_webpack",
  "version": "1.0.0",
  "description": "it is testing to programe, webpack, babel, setting for react, typeScript etc",
  "main": "index.js",
  "repository": "https://github.com/Chars4785/test_webpack.git",
  "author": "Chars4785 <9105lgm@naver.com>",
  "license": "MIT",
  "scripts": {
    "start": "webpack-dev-server --mode development --open --hot",
    "build": "webpack --mode production"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  },
  "devDependencies": {
    "@babel/core": "^7.14.3",
    "@babel/plugin-proposal-class-properties": "^7.13.0",
    "@babel/plugin-proposal-object-rest-spread": "^7.14.2",
    "@babel/preset-react": "^7.13.13",
    "@babel/preset-typescript": "^7.13.0",
    "@types/react": "^17.0.5",
    "@types/react-dom": "^17.0.4",
    "awesome-typescript-loader": "^5.2.1",
    "babel-core": "^7.0.0-bridge.0",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "html-webpack-plugin": "^4.4.0",
    "rimraf": "^3.0.2",
    "source-map-loader": "^2.0.1",
    "strip-ansi": "^7.0.0",
    "ts-loader": "^9.1.1",
    "typescript": "^4.2.4",
    "webpack": "^4.40.2",
    "webpack-cli": "^3.3.9",
    "webpack-dev-server": "^3.11.0"
  }
}

필요한 것들

  • webpack
  • webpack-dev-server: express 기반으로 되어 있는 web server 이다. 번들 파일을 만드는 것 대신에 (bundle.js) local browser 에서 실행 할수 있게 도와준다.
  • html-webpack-plugin-D bundle한 css,js파일을 각각 html파일에 link 태그와 scripts태그로 추가해줘야 한다. 이걸 자동화 시켜주는 라이브러리다.
  • webpack-cli: 기본 인터페이스 ( webpack이 알아서 설치한다. )
    CLI 및 설정 파일( default: webpack.config.js) 을 통해 옵션을 가져와서 bundle로 제공하기 위해 webpack에 제공한다.
    ex: webpack <--- bundle using webpack.config.js
  • awesome-typescript-loader: 컴파일도구

webpack.config.js

module.exports = {
  entry: './src/index.tsx',
  resolve: {
    extensions: ['.ts', '.tsx', '.js']
  },
  output: {
    publicPath: '/',
    path: path.join(__dirname, '/dist'),
    filename: 'bundle.min.js'
  },
  module: {
    rules: [{
        // Include ts, tsx, js, and jsx files.
        test: /\.(ts|js)x?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: ["style-loader", "css-loader", "sass-loader"]
      },
      {
        test: /\.(png|jpg)$/,
        use: 'file-loader'
      }
    ],
  },
  devtool: 'source-map',
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  devServer: {
    historyApiFallback: true,
  },
}
  • entry : 연결되어 있는 각 파일 중, 제일 처음으로 시작되는 최상위 파일. 해당 최상위 파일부터 각 각 하위로 따라 내려가며 번들화 작업을 한다.( default: ./src/index.js)
  • output: 번들화 된 파일을 export 할 경로와 파일명.
  • __dirname: 현재 실행 중인 파일 경로
  • __filename: 현재 실행 중인 폴더 경로 위의 설정에는, 'src/index.tsx'의 파일이 running 시 동작되는 것 중 제일 처음으로 동작하는 최상위 파일이며, 해당 번들화 된 파일은 루트 경로의 '/dist/bundle.min.js'파일로 추출된다.
  • Loaders: webpack은 오직 js, Json 만 이해하고 있습니다. 다른 형태의 파일을 이해 할 수있도록 변환 시켜줘야 한다.
  • test: 속성을 변환해야 하는 파일
  • use: 속성을 변환을 수행하는데 사용하는 로더 ex:require,import 문 내에서 txt 파일로 확인되는 파일은 번들에 추가하기 전에 "raw-loader"를 사용해줘
module: { 
	rules: [{ test: /\.txt$/, use: 'raw-loader' }], 
},
  • Plugins: loaders는 어떤 모듈의 변경이라면, plugins은 번들 최적화, asset managemnet, 환경 변수 주입 등.. ex:

plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })]

application 을 위해 발생되는 모든 bundles에 자동으로 "html-webpack-pulgin" 이 주입하게 됩니다.

플러그인 목록

https://webpack.js.org/plugins/

module.exports = {
	mode: 'production', 
};

development: process.env.NODE_ENV 에 대한 DefinePlugin 값 development 모듈을 사용합니다.

나머지 동일

devtool: 개발을 용이하게 하기 위한 소스맵을 제공하는 옵션

  1. eval: 
  2. eval-source-map
  3. cheap-eval-source-map
  4. cheap-module-eval-source-map
  5. source-map: 원본 코드와 빌드된 코드를 매핑 해주는 방법, 소스맵 생성, 고르 디버깅 가능
  6. inline-source-map: 소스맵- 미생성하고 로그 디버깅이 가능하다.
  7. cheap-source-map
  8. cheap-module-source-map

비교표

https://webpack.js.org/configuration/devtool/#devtool

tsconfig.json

{
  "compilerOptions": {
    "sourceMap": true,
    "noImplicitAny": false,
    "module": "commonjs",
    "target": "es6",
    "lib": [
      "es2015",
      "es2017",
      "dom"
    ],
    "removeComments": true,
    "allowSyntheticDefaultImports": false,
    "jsx": "react",
    "allowJs": true,
    "baseUrl": "./",
    "paths": {
      "components/*": [
        "src/components/*"
      ],
    }
  }
}

tsconfig.json: 프로젝트를 컴파일 하는데 필요한 루트 파일과 컴파일러 옵션을 지정합니다.

typeScript or javaScript project 설정을 합니다.

  • "compilerOptions": 속성은 생략될 수 있으며 생략하면 컴파일러의 기본 값이 사용됩니다.
  • "sourceMap": true

tsc vs babel


how to convert from TypeScript to JavaScript

  • Is your build output mostly the same as your source input files? Use tsc
  • Do you need a build pipeline with multiple potential outputs? Use babel for transpiling and tsc for type checking

바벨을 사용해야 하는 이유


바벨7 이전

TS > TS compiler > JS > Babel > JS 순서

웹팩은 두개의 컴파일러를 함께 사용하기 위해 사용된다. ( babel, tsc ) 웹팹 설정을 비틀어 *.ts 를 타입스크립트로 입력한 다음 결과를 바벨에 제공한다. 웹팩의 탑이스크립트 로더에는 ts-loader, awesome-typscript-loader 가 있는데 awe~ 일부 작업의 부하로 컴파일 속도가 느리며, ts-loader는 많은 복잡한 캐시 로더를 함께 설정하여 사용해야 하는 불편함이 있다.

바벨7 이후

바벨은 타입스크립트를 우선 js로 변경한다.

  • 바벨 + 타입스크립트코드는 느린 컴파일 시간 개선
  • 준비가 되었을 때만 타입 오류를 확인하라 ( js로 우선 안정성 검사 하지 않고 컴파일한 다음 코드 실험이 끝나고 타입 검사를 진행한다. )
  • TypeScript는 전체 프로젝트를 컴파일 하지만 Babel은 한번에 하나의 파일만 컴파일 한다.
{
	"compilerOptions": {
		// Target latest version of ECMAScript.
		"target": "esnext",
		// Search under node_modules for non-relative imports.
		"moduleResolution": "node",
		// Process & infer types from .js files.
		"allowJs": true,
		// Don't emit; allow Babel to transform files.
		"noEmit": true,
		// Enable strictest settings like strictNullChecks & noImplicitAny.
		"strict": true,
		// Disallow features that require cross-file information for emit.
		"isolatedModules": true,
		// Import non-ES modules as default imports.
		"esModuleInterop": true
	},
	"include": [
		"src"
	]
}

Error

  • [webpack] TypeError: Cannot read property 'tap' of undefined

npm i -D html-webpack-plugin@4.4.0 webpack@4.40.2 webpack-cli@3.3.9

5버전대 webpack 이 충돌이 일어 날수 있다.

 

 


참고 사이트

 

joshua1988.github.io/webpack-guide/webpack/what-is-webpack.html#%EC%9B%B9%ED%8C%A9%EC%9D%B4%EB%9E%80

imranhsayed.medium.com/webpack-dev-server-b1010d01dba5

 

Webpack Dev Server

So what is webpack dev server? Webpack dev server is a web server based on express.

imranhsayed.medium.com

 

geojson.io/#map=2/20.0/0.0