Clone Coding/Instagram

[Instagram] Header(1) - 공통 Layout 및 Import

고코모옹 2021. 7. 17. 23:32

 

 

Logo 이미지

  • webpack 5 이전에는 파일을 출력하기 위해 file-loader 설치 필요
  • webpack 5 부터 내장된 Asset Modules를 사용
    • Asset Module은 loader를 추가로 구성하지 않아도 Asset파일(폰트, 아이콘 등)을 사용할 수 있도록 해주는 모듈

  • loader를 대체하기 위해서 Asset Module에 4개의 새로운 모듈 유형 추가
    • asset/resource: 별도의 파일을 내보내고 URL 추출. 이전에는 file-loader를 사용하여 처리
    • asset/inline: Asset의 data URI를 내보낸다. 이전에는 url-loader를 사용하여 처리
    • asset/source: Asset의 소스 코드를 내보낸다. 이전에는 raw-loader를 사용하여 처리
    • asset: data URI와 별도의 파일 내보내기 중에서 자동으로 선택. 이전에는 Asset 크기 제한이 있는 url-loader 사용

  • webpack 5의 Asset Module과 함께 이전 Asset loader를 사용할 때 Asset Module이 Asset을 중복으로 처리하지 않도록 할 수 있다. Asset Module type을 'javascript/auto' 로 설정하여 적용 가능하다.

 

- webpack.config.js에 Asset Modules 설정

  • asset/resource 설정
  • Custom output filename
    • 파일을 출력 디렉터리로 내보낼 때 asset/resource 모듈은 기본적으로 [hash][ext][query] 파일명 사용
    • output.assetModuleFilename을 설정하여 템플릿을 수정할 수 있다.
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
    assetModuleFilename: 'assets/[hash][ext][query]',
    clean: true, // 재빌드 시, 필요없는 파일들 제거
  },
  module: {
    rules: [
      {
        test: /\.s?css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
      },
      {
        test: /\.js$/,
        use: ['babel-loader'],
      },
      {
        test: /\.html$/i,
        loader: 'html-loader',
      },
      {
        test: /\.(png|jpe?g|gif|webp)$/,
        type: 'asset/resource',
      },
    ],
  },
  resolve: {
    extensions: ['.wasm', '.mjs', '.js', '.jsx', '.ts', '.tsx', '.json'],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/html/index.html',
      favicon: './src/assets/favicon.ico',
    }),
  ],
  devServer: {
    host: 'localhost',
  },
};

 

  • 빌드 시, 아래와 같이 생성

빌드 시, 파일 구조


공통 Layout

  • header.js 파일 생성 및 공통 로직 구현

프로젝트 파일 구조

// header.js
import '../../scss/header.scss';
import logo from '../../assets/logo.png';

const header = `
  <div class="logo">
    <a href="/" tabIndex="0">
      <img alt="logo" />
    </a>
  </div>
  <div class="search">Search</div>
  <div class="icons">Icon</div>
`;

const headerEl = document.querySelector('#header .container');
headerEl.innerHTML = header;

const logoEl = document.querySelector('img');
logoEl.src = logo;
// header.scss
#header {
  height: 54px;
  background-color: #fff;
  border-bottom: 1px solid #dbdbdb;

  .headerWrap {
    position: fixed;
    top: 0;
    width: 100%;
    height: 54px;
    z-index: 3;

    .container {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0 20px;
      height: 54px;

      .logo {
        width: 103px;
        min-width: 40px;
        margin-top: 7px;
        transition: opacity 0.1s ease-out;

        img {
          max-height: 100%;
          max-width: 100%;
          object-fit: contain;
        }

        a {
          text-decoration: none;

          &:visited {
            color: #00376b;
          }
        }
      }
    }
  }
}
// index.js
import '../scss/common.scss';
import './layout/header';

bootstrap container max width customize

  • 인스타그램을 아무리 확대해도 header 영역 넓이는 최대 945px로 설정되어 있음
  • bootstrap containers 속성 기본값을 override 해서 최대 945px까지만 커지도록 설정
  • 576px 보다 작을 경우에는 전체 영역으로 보이도록 하기 위해 container-md 사용
// index.html
<!DOCTYPE html>
<html lang="ko">
  <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>Instagram</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css"
    />
  </head>
  <body>
    <nav id="header">
      <div class="headerWrap">
        <div class="container container-md"></div>
      </div>
    </nav>
  </body>
</html>
// common.scss

// Default variable overrides
$container-max-widths: (
  lg: 975px,
  xl: 975px,
  xxl: 975px,
);

// Required
@import '../../node_modules/bootstrap/scss/functions';
@import '../../node_modules/bootstrap/scss/variables';
@import '../../node_modules/bootstrap/scss/mixins';

@import '../../node_modules/bootstrap/scss/bootstrap';

body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

Bootstrap Containers


결과물


[ 참고자료 ]

https://webpack.kr/guides/asset-management/#loading-images

https://webpack.kr/guides/asset-modules/

https://getbootstrap.com/docs/5.0/layout/containers/