개요

  • webpack을 통해 번들링 하는 과정에서 css내의 url()로 이미지를 불러오는 부분이 작동을 안함

문제 정의

  • 현재 상태
    • css는 sass를 번들링 하기위한 플러그인사용
      • sass의 url()을 통해 이미지를 불러오는데 번들링 이후에도 잘 작동을 함
    • 이미지도 번들링하기 위해 file-loader/url-loader를 사용
      • sass의 url()의 이미지 불러오기도 같이 작동하면서 이미지를 불러오지 못함
      • 번들된 해당 이미지도 이미지가 아니게 됨
  • css내의 url(경로)이 file-loader/url-loader를 사용하는 순간 작동을 안하고 이미지 파일이 다른 파일로 변환됨

과정

기본 webpack.config.js

  • 전체 webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HTMLWebpackPlugin = require('html-webpack-plugin');

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const FaviconsWebpackPlugin = require('favicons-webpack-plugin')

const dotenv = require("dotenv");
dotenv.config({//env가져오기
    path: path.resolve(//경로찾기
        process.cwd(),//현재경로 + 
        process.env.NODE_ENV == "production" ? "env/.production.env" : "env/.development.env"//실제는 .env, 개발은 .env.dev사용
    ),
    });
console.log(process.env.IP)

module.exports = {
    // enntry file
    // - sass가 존재할경우 entry: ['@babel/polyfill', './main.js', './main.scss'],
    entry: ['@babel/polyfill', './src/main.js', './sass/main.scss'],
    // 컴파일 + 번들링된 js 파일이 저장될 경로와 이름 지정
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/bundle.js',
        publicPath: process.env.IP
    },
    devServer: {
        contentBase: "dist",
        overlay: true,
        // 웹팩의 상태값에 색상을 부여한다.
        stats: {
          colors: true
        },
        // hot 프로퍼티를 true로 설정!
        hot: true
      },
    plugins: [
        // 컴파일 + 번들링 CSS 파일이 저장될 경로와 이름 지정
        new MiniCssExtractPlugin({ filename: 'css/style.css' }),
        new webpack.DefinePlugin({
            'process.env.IP': JSON.stringify(process.env.IP), // env에서 읽은 ip를 저장
            'process.env.API_IP': JSON.stringify(process.env.API_IP), //
            'process.env.PORT': JSON.stringify(process.env.PORT),
            'process.env.DUMMY': JSON.stringify(process.env.DUMMY),
        }),
        new HTMLWebpackPlugin({
            template: "./views/index.html"
          }),
        new FaviconsWebpackPlugin({
            logo: './public/favicon.ico',
        }),
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                include: [
                    path.resolve(__dirname, 'src/js')
                ],
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                        plugins: ['@babel/plugin-proposal-class-properties']
                    }
                }
            },
            {
                test: /\.scss$/,
                use: [ 
                    MiniCssExtractPlugin.loader,            
                    "css-loader", // translates CSS into CommonJS
                    "sass-loader", // compiles Sass to CSS, using Node Sass by default
                ],
                exclude: /node_modules/
            },            
        ]
    },
    devtool: 'source-map',
    // https://webpack.js.org/concepts/mode/#mode-development
    mode: 'development'
};
  • scss에서 이미지 불러오는 부분
.select_form:after {
    background-image:url(../src/assets/free-icon-arrow-down-sign-to-navigate-32195.png);
}
  • 번들된 이미지
    • 결과
    • 해당 이미지
  • 해당 이미지를 잘 불러오는 모습
    • 잘불러옴
    • 출력도잘됨

수정 webpack.config.js

  • 이미지 처리를 위한 file-loader와 url-loader를 사용시 발생 문제
    • file-loader추가
  • 수정된 webpack.config.js
module.exports = {
module: {
    rules: [
        ...
    {
        test: /\.(png|jpe?g|gif|svg|webp)$/i,
        loader: 'file-loader',
        options:{
            publicPath: '',
            // name: 'images/[name].[ext]',
            name: '[name].[ext]?[hash]'
        }
    }
    ]
}
}
  • 이미지가 변형된 모습
    • 번들 결과
      • 두개의 이미지 283f85a9c419b660f8d7.png,free-icon-arrow-down-sign-to-navigate-32195가 나온다.
    • 이미지파일이 아니게됨
      • 내용은 export default __webpack_public_path__ + "free-icon-arrow-down-sign-to-navigate-32195.png?0beda3df974b74fa82c5d4eb79d63a5a";
      • js에서 볼 내용이 작성되어있다.
    • file-loader의 이미지
      • 정상적인 이미지도 같이 나온다.
  • 번들된것은 이미지 파일이 아닌것을 나타내고있다.
    • 안열리는 이미지를 경로로 하는중
    • 출력이 안된 모습

해결 방안

  • 안돼서 그냥 외부 링크(http://외부.png)로 사용…
    • 문제 해결 안됨…

참고

  • 일반적인 이미지 등록 방식
    • https://develoger.kr/frontend/webpack-%ec%9d%b4%eb%af%b8%ec%a7%80-%ea%b2%bd%eb%a1%9c-%ec%b2%98%eb%a6%ac/