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파일(폰트, 아이콘 등)을 사용할 수 있도록 해주는 모듈
- 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;
}
결과물
[ 참고자료 ]
https://webpack.kr/guides/asset-management/#loading-images