혼자 적어보는 노트

[Netlify+Javascript] 배포하며 겪은 시행 착오들 본문

Javascript

[Netlify+Javascript] 배포하며 겪은 시행 착오들

jinist 2022. 9. 6. 02:04

 

 

 

Vanilla JS로 작업한 프로젝트를 netlify에 배포를 하려던 중

API의 env설정을 위해 webpack을 사용하여 처리를 해보기로 했지만

꽤나 오랜 시간 삽질을 해서 기록을 하기로 했다.

 

 

1. Build setting

그냥 Javascript 파일을 등록할 땐 build setting 부분을 빈 값으로 해도 되지만

build를 진행할 것이기 때문에 build setting을 해주어야 했다.

 

 배포 폴더는 public으로 지정했다.

 

 

2. failed된 결과는 배포되지 않음

처음 배포를 했을 때는 build과정 없이 진행했고 정상적으로 나타났었고

webpack 및 package.json 설정을 하고 push를 했는데 제대로 나타나길래 나는 정상적으로 잘 한줄 알았다..ㅎ

 

하지만 deploys에서 로그를 보면 failed처리 되어있었고 failed처리 된 것은 배포가 되지 않는다.

==> 이전에 정상적으로 처리된 것이 배포 사이트에 나타남

 

 

3. 윈도우는 대소문자를 구분하지 않음

Field 'browser' doesn't contain a valid alias configuration

build된 커밋의 로그를 보니 에러가 발생했었고 나는 경로를 못읽어서 이렇게 나타나는 건가 해서

webpack에 alias설정을 해보기도 하고 경로들을 다시 확인하는 등등 삽질을 했는데

알고보니 import를 잘못했다.

 

import PostPage from 'components/postPage.js'; // 실제 파일명:PostPage.js

파일명의 첫 글자가 대문자인데 import 할 때 소문자로 입력했다..

로컬에서는 에러가 없었어서 이 부분을 완전 예상 못했었는데 임시팀을 함께했었던 분이 매의 눈으로 캐치해주셨다..🙏

윈도우는 대소문자를 구분하지 않아서 에러가 안난걸로..

 

 

4. Failed to load resource: the server responded with a status of 404 ()

deploy failed는 해결 했지만 배포 사이트에서 css파일과 js파일을 불러오지 못하는 에러가 생겼다😅

 

 

✅ index.js 불러오기

// webpack.config.js

output: {
      filename: 'index.js',
      path: path.resolve(__dirname, 'public'),
      publicPath: '/',
    },

 

output부분의 pubilcPath를 테스트하는 과정에서 '/public/' 으로 변경했었는데

이 부분 때문에 안된거였고 '/'로 변경하니 index.js는 불러올 수 있게 되었다.

 

 

✅ css 불러오기 

현재 프로젝트에는 2개의 css파일을 사용 중인데

아래와 같이 index.html 파일의 head부분에 직접 지정을 해두었었다.

<!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" />
    <link href="/src/style.css" rel="stylesheet" type="text/css" />
    <link href="/src/normalize.css" rel="stylesheet" type="text/css" />

    <title>Notion Cloning</title>
  </head>
  <body>
    <main id="app"></main>
    <script src="https://kit.fontawesome.com/6a8569f533.js" crossorigin="anonymous"></script>
  </body>
</html>

이 파일이 build 시에 그대로 /src/를 참조하기 때문에 불러오지 못하는 것 같았다.

 

검색해서 찾아보니 import 방식을 사용해야 한다고 해서 index.js 파일에서 import를 하는 방식으로 변경했다.

// index.js

import App from 'components/App.js';
import Style from '../src/style.css';
import Normalize from '../src/normalize.css';

const $app = document.querySelector('#app');

new App({ $target: $app });

 

// webpack.config.js

module: {
      rules: [
        // 생략
        {
          test: /\.css$/,
          use: ['style-loader', 'css-loader'],
        },
      ],
    },

css-loader: 내부에 import한 다른 css파일을 json 파일로 로드하고 style-loader에 전달한다.

style-loader: json을 가지고와서 style태그를 추가하고 index.html 파일 안에 태그를 삽입한다.

 

 

head를 살펴보면 style 태그가 추가된 것을 확인할 수 있었다.

 

 

5. process is not defined

 

local에서는 제대로 적용되던 env가 배포환경에서는 제대로 동작하지 않았다.

netlify의 deploy 설정에서 환경 변수 설정도 해놓은 상태인데 적용이 안되었다.

 

🤔 이전 코드

// webpack.config.js

plugins: [
      new HtmlWebpackPlugin({ template: './index.html' }),
      new MiniCssExtractPlugin({ filename: 'style.css' }),
      new webpack.EnvironmentPlugin(Object.keys(dotenv.parsed || {})),
    ],

 

이 부분에 문제가 있는 듯 하여 다른 방법을 찾아보았다.

 

참고한 블로그 : 웹팩(Webpack) DefinePlugin, EnvironmentPlugin 사용법

 

 

✅ DefinePlugin 사용

 

DefinePlugin: 모든 자바스크립트 코드에서 접근이 가능한 전역 변수를 선언하기 위해서 사용되는 플러그인

plugins: [
      new HtmlWebpackPlugin({ template: './index.html' }),
      new MiniCssExtractPlugin({ filename: 'style.css' }),
      new webpack.DefinePlugin({
        'process.env': JSON.stringify(dotenv.parsed),
        'process.env.NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production'),
        'process.env.BASE_URL': JSON.stringify(process.env.BASE_URL),
      }),
      new webpack.EnvironmentPlugin(['BASE_URL']),
    ],

전역 변수로 사용할 변수명을 지정하고  dotenv에서 꺼내서 사용하게끔 설정하여 해결했다 🙌

 

 

6. Page Not Found

SPA에서 URL 이동 후 새로고침을 할 경우 자주 보는 에러여서 _redirects 파일을 만들어주면

해결되는 것으로 알고 있었는데 파일 위치가 조금 헷갈렸다.

 

build과정이 없다면 root 경로에 _redirects 파일을 넣어두면 된다고 하지만

build 과정이 있다면 public 파일에 넣어주어야 한다.

 

다른 경로에 넣어놓는다면 deploy log 에서 아래와 같이 친절하게 다시 알려준다.

 

❗ 그런데 public에 넣어두었는데도 적용이 안되는 문제가 발생했다.

 

 

✅ 해결

// webpack.config.js

    entry: './src/index.js',
    output: {
      filename: 'index.js',
      path: path.resolve(__dirname, 'public'),
      publicPath: '/',
      // clean: true,
    },

clean 옵션을 true로 설정해 두어서 _redirects 파일이 빌드될 때 삭제되는 듯 하여

해당 옵션을 지우고 확인하니 새로고침을 해도 정상적으로 나타났다  🙌

 


 

그렇게 완성된 webpack.config

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const dotenv = require('dotenv').config();

module.exports = (_, argv) => {
  const isDevelopment = argv.mode !== 'production';

  return {
    entry: './src/index.js',
    output: {
      filename: 'index.js',
      path: path.resolve(__dirname, 'public'),
      publicPath: '/',
    },
    resolve: {
      alias: {
        components: path.resolve(__dirname, 'src/components'),
        util: path.resolve(__dirname, 'src/util'),
      },
      extensions: ['.js'],
    },
    devServer: {
      static: './',
      port: 3000,
      hot: true,
      historyApiFallback: {
        index: '/index.html',
      },
    },
    devtool: 'inline-source-map',
    module: {
      rules: [
        {
          test: /\.(js)$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true,
              cacheCompression: false,
              compact: !isDevelopment,
            },
          },
        },
        {
          test: /\.css$/,
          use: ['style-loader', 'css-loader'],
        },
      ],
    },
    plugins: [
      new HtmlWebpackPlugin({ template: './index.html' }),
      new MiniCssExtractPlugin({ filename: 'style.css' }),
      new webpack.DefinePlugin({
        'process.env': JSON.stringify(dotenv.parsed),
        'process.env.NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production'),
        'process.env.BASE_URL': JSON.stringify(process.env.BASE_URL),
      }),
      new webpack.EnvironmentPlugin(['BASE_URL']),
    ],
    performance: {
      hints: false,
    },
  };
};

 

아무래도 초반에 지식이 부족해서 조금 낑낑댔지만 결국은 해결했고

이번 기회에 webpack에 대해 조금은 이해하게 되었다.👍

Comments