ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Instagram] Header(1) - 공통 Layout 및 Import
    Clone Coding/Instagram 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/

    댓글

Designed by Tistory.