Angular 및 .NET 8 배포에서 '예기치 않은 토큰'<' 해결

Angular 및 .NET 8 배포에서 '예기치 않은 토큰'<' 해결
Angular 및 .NET 8 배포에서 '예기치 않은 토큰'<' 해결

디버그에서는 배포가 작동하지만 IIS에서는 실패하는 경우

애플리케이션이 디버그 모드에서는 완벽하게 작동하지만 배포 시 비참하게 실패하는 것을 보고 좌절감을 느낀 적이 있습니까? 😟 이는 최근에 Angular 및 .NET 애플리케이션을 .NET Core 2.1에서 .NET 8로 이동할 때 경험한 것처럼 프로젝트를 마이그레이션할 때 특히 짜증날 수 있습니다. 문제는 수수께끼처럼 보였습니다. 'Uncaught SyntaxError: Unexpected token'

이상한 부분? 배포 파일을 조사한 결과 런타임, 폴리필, 기본 등 일부 스크립트가 JavaScript 대신 HTML 파일로 제공되는 것으로 나타났습니다. 이 동작으로 인해 로컬 `dist` 폴더에 올바른 JS 형식이 표시되었기 때문에 머리가 긁히게 되었습니다. 그러나 IIS 배포에서는 매우 다른 그림이 그려졌습니다.

개발자로서 이러한 불일치에 직면하는 것은 모든 리드가 또 다른 혼란스러운 질문을 열어주는 미스터리를 해결하는 것처럼 느껴집니다. 경로, 명령, 구성을 다시 확인했지만 원인을 즉시 찾아낼 수는 없었습니다. 기한이 다가오면서 이 문제를 해결하는 것이 최우선 과제가 되었습니다. 🕒

이번 포스팅에서는 이 문제의 근본 원인을 자세히 알아보고, 문제 해결 과정에서 배운 교훈을 공유하고, 효과적으로 문제를 해결하는 방법을 안내해 드리겠습니다. 비슷한 시나리오에 직면했다면 계속 지켜봐 주시기 바랍니다. 이 여정에서 여러분은 혼자가 아닐 것이라고 약속드립니다!

명령 사용예
<mimeMap> JavaScript와 같은 파일이 올바른 콘텐츠 유형으로 제공되도록 IIS 구성에서 MIME 유형을 정의하십시오.
ng build --prod --output-hashing=all 캐싱 최적화를 위해 해시된 파일 이름을 사용하여 프로덕션 모드에서 Angular 애플리케이션을 빌드합니다.
fs.lstatSync() 파일 유효성 검사를 위해 Node.js 스크립트 실행 중에 지정된 경로가 디렉터리인지 파일인지 확인합니다.
mime.lookup() 배포 중에 올바른 구성을 확인하기 위해 확장자를 기반으로 파일의 MIME 유형을 검색합니다.
baseHref Angular 애플리케이션의 기본 URL을 지정하여 하위 디렉터리에 배포할 때 적절한 라우팅을 보장합니다.
deployUrl Angular 애플리케이션에 정적 자산이 배포되는 경로를 정의하여 정확한 파일 확인을 보장합니다.
fs.readdirSync() 파일 유효성 검사 스크립트에 유용한 Node.js의 지정된 폴더에서 모든 파일과 디렉터리를 동기식으로 읽습니다.
path.join() 여러 경로 세그먼트를 단일 정규화된 경로 문자열로 결합합니다. 이는 크로스 플랫폼 파일 처리에 중요합니다.
expect() Jest 테스트에서 지정된 조건이 true인지 확인하고 이 컨텍스트에서 배포 정확성을 검증하는 데 사용됩니다.
ng serve --base-href 라우팅 문제의 로컬 테스트를 위한 사용자 정의 기본 URL을 사용하여 Angular 개발 서버를 시작합니다.

Angular 및 .NET 애플리케이션의 배포 오류 이해하기

위에 제공된 스크립트에서 각 솔루션은 Angular 및 .NET 환경에서 배포 문제를 해결하는 특정 측면에 중점을 둡니다. IIS 구성 파일은 다음을 사용합니다. 웹.구성 MIME 유형 불일치를 해결하는 데 중요합니다. '.js'와 같은 파일 확장자를 적절한 MIME 유형(application/javascript)에 명시적으로 매핑함으로써 IIS는 이러한 파일을 브라우저에 올바르게 제공하는 방법을 알고 있습니다. 이는 "예기치 않은 토큰'을 방지합니다.

그만큼 각도 빌드 명령 (ng 빌드 --prod) 애플리케이션이 프로덕션에 최적화되었는지 확인합니다. `--output-hashing=all` 매개변수는 파일 이름을 해시하므로 브라우저가 실수로 오래된 버전을 사용하지 않고 파일을 캐시할 수 있습니다. 이는 사용자가 애플리케이션을 자주 다시 방문하는 실제 배포에서 특히 중요합니다. `angular.json`에서 `baseHref` 및 `deployUrl`을 구성함으로써 하위 디렉터리나 CDN에서 호스팅되는 경우에도 라우팅 및 자산 로딩이 원활하게 작동하도록 보장합니다. 이러한 단계를 통해 애플리케이션이 일반적인 배포 문제에 대한 탄력성을 갖게 되어 사용자 경험과 안정성이 모두 향상됩니다.

위에 제공된 Node.js 스크립트는 `dist` 디렉토리를 스캔하여 파일의 무결성을 확인함으로써 또 다른 디버깅 계층을 추가합니다. `fs.readdirSync` 및 `mime.lookup`과 같은 명령을 사용하여 스크립트는 배포 전에 각 파일이 올바른 MIME 유형을 가지고 있는지 확인합니다. 이 사전 조치는 생산 과정에서 잠재적인 오류가 발생하기 전에 이를 포착하여 시간을 절약하고 불만을 줄이는 데 도움이 됩니다. 예를 들어, 배포 중 이 스크립트는 구성 문제로 인해 JSON 파일이 잘못된 MIME 유형으로 제공된다는 사실을 깨닫는 데 도움이 되었습니다. 🔍

마지막으로 Jest 테스트 스크립트는 주요 배포 측면의 자동 검증을 보장합니다. `dist` 폴더에 `runtime.js` 및 `main.js`와 같은 중요한 파일이 있는지 확인합니다. 이는 특히 여러 개발자가 참여하는 팀 환경에서 배포 중에 간과되는 오류를 방지합니다. 이러한 테스트를 통합함으로써 철저하게 검증된 애플리케이션을 자신있게 배포할 수 있습니다. 이러한 솔루션을 함께 사용하면 배포 문제를 해결하고 원활한 프로덕션 릴리스를 보장하기 위한 강력한 프로세스가 생성됩니다.

'예기치 않은 토큰' 해결

이 솔루션은 IIS의 서버측 구성과 파일 매핑을 사용하여 JavaScript 파일에 대한 적절한 MIME 유형을 보장합니다.

<!-- web.config solution to fix MIME type issues in IIS -->
<configuration>
  <system.webServer>
    <staticContent>
      <mimeMap fileExtension=".*" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".js" mimeType="application/javascript" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
    </staticContent>
  </system.webServer>
</configuration>

Angular 애플리케이션 재구축 및 배포 경로 확인

이 솔루션에는 Angular 빌드 프로세스가 올바르게 구성되고 배포 경로가 정확한지 확인하는 작업이 포함됩니다.

// Angular CLI commands to rebuild the application
ng build --prod --output-hashing=all
// Ensure deployment paths in angular.json are set correctly
{
  "outputPath": "dist/my-app",
  "baseHref": "/",
  "deployUrl": "/"
}
// Copy contents of dist folder to IIS hosted directory

Dist 폴더의 파일 형식을 확인하는 Node.js 스크립트

이 스크립트는 배포된 파일의 무결성을 검증하여 디버깅을 위해 Node.js에서 올바른 MIME 유형으로 제공되는지 확인합니다.

// Node.js script to check MIME types of files in the dist folder
const fs = require('fs');
const path = require('path');
const mime = require('mime-types');
// Directory to check
const distDir = path.join(__dirname, 'dist');
// Function to validate file types
function validateFiles(dir) {
  fs.readdirSync(dir).forEach(file => {
    const fullPath = path.join(dir, file);
    if (fs.lstatSync(fullPath).isDirectory()) {
      validateFiles(fullPath);
    } else {
      const mimeType = mime.lookup(fullPath);
      console.log(`File: ${file}, MIME Type: ${mimeType}`);
    }
  });
}
validateFiles(distDir);

배포를 위한 단위 테스트

이는 Jest를 사용하여 Angular 애플리케이션용 배포 패키지를 검증하는 단위 테스트 설정을 보여줍니다.

// Jest test to validate Angular dist folder integrity
const fs = require('fs');
const path = require('path');
test('All JavaScript files should exist and be served correctly', () => {
  const distDir = path.join(__dirname, 'dist');
  const requiredFiles = ['runtime.js', 'polyfills.js', 'main.js'];
  requiredFiles.forEach(file => {
    const filePath = path.join(distDir, file);
    expect(fs.existsSync(filePath)).toBe(true);
  });
});

배포 시 정적 파일 구성의 중요성 이해

배포 중에 종종 간과되는 중요한 측면 중 하나는 정적 파일 처리의 적절한 구성입니다. Angular 및 .NET 애플리케이션의 경우 애플리케이션이 작동하려면 JavaScript 및 CSS 파일과 같은 정적 자산이 올바르게 제공되어야 합니다. 서버의 부적절한 MIME 유형 설정은 악명 높은 "Uncaught SyntaxError: Unexpected token'과 같은 오류로 이어질 수 있습니다.정적 콘텐츠 IIS 구성에서는 이러한 파일이 올바르게 해석되도록 보장합니다. 이러한 서버 수준 구성은 런타임 문제를 방지하는 데 필수적입니다. 🚀

탐구해야 할 또 다른 각도는 잘못된 라우팅 구성의 영향입니다. Angular 애플리케이션은 클라이언트측 라우팅을 사용하는데, 이는 사전 정의된 엔드포인트를 기대하는 서버 설정과 종종 충돌합니다. 모든 요청을 'index.html'로 리디렉션하는 등 서버 구성에 대체 경로를 추가하면 애플리케이션이 중단되지 않습니다. 예를 들어, IIS에서는 `` 일치하지 않는 모든 요청을 Angular 진입점으로 라우팅하는 규칙입니다. 이 간단하면서도 강력한 단계를 통해 디버깅 시간을 절약하고 애플리케이션의 견고성을 향상시킬 수 있습니다. 🛠️

마지막으로 빌드 시간 최적화의 역할을 고려하세요. `--aot` 및 `--optimization`과 같은 프로덕션 플래그가 포함된 Angular의 `ng build` 명령은 더 나은 성능을 위해 앱을 컴파일하고 축소합니다. 그러나 이러한 최적화가 배포 환경에 부합하는지 확인하는 것이 중요합니다. 예를 들어 초기 배포 중에 소스 맵을 활성화하면 나중에 비활성화하여 보안을 손상시키지 않고 프로덕션에서 문제를 디버그하는 데 도움이 될 수 있습니다. 이러한 모범 사례를 통해 배포를 더욱 예측 가능하고 효율적으로 만들 수 있습니다.

Angular 및 IIS 배포 오류에 대해 자주 묻는 질문

  1. JavaScript 파일에서 "예기치 않은 토큰 '<'" 오류가 발생하는 이유는 무엇입니까?
  2. 이는 서버가 잘못 구성되어 잘못된 MIME 유형으로 JavaScript 파일을 제공하기 때문에 발생합니다. 다음을 사용하여 MIME 유형을 구성합니다. <mimeMap> IIS에서.
  3. 배포된 파일에 올바른 MIME 유형이 있는지 어떻게 확인할 수 있나요?
  4. 다음과 같은 명령을 사용하여 Node.js 스크립트를 작성할 수 있습니다. mime.lookup() 배포하기 전에 `dist` 폴더에 있는 각 파일의 MIME 유형을 확인합니다.
  5. Angular 배포에서 baseHref의 역할은 무엇입니까?
  6. 그만큼 baseHref 애플리케이션의 기본 경로를 지정하여 특히 하위 디렉터리에서 호스팅되는 경우 자산과 경로가 올바르게 확인되도록 합니다.
  7. IIS에서 라우팅 문제를 어떻게 처리합니까?
  8. 일치하지 않는 모든 요청을 다음으로 리디렉션하려면 IIS 구성에 다시 쓰기 규칙을 추가하세요. index.html. 이렇게 하면 클라이언트 측 라우팅이 원활하게 작동합니다.
  9. 중요한 배포 파일의 유효성 검사를 자동화할 수 있습니까?
  10. 예, Jest와 같은 테스트 프레임워크를 사용하여 runtime.js 배포 패키지의 기타 주요 파일.

배포 과제 마무리

Angular 및 .NET 애플리케이션의 배포 문제를 해결하려면 서버 구성과 디버깅 도구가 함께 사용되는 경우가 많습니다. MIME 유형 불일치와 같은 근본 원인을 식별하는 것은 오류를 효과적으로 해결하고 앱이 의도한 대로 실행되도록 하는 데 중요합니다. 💻

파일 유효성 검사 및 대체 경로 구성과 같은 모범 사례를 적용하면 배포 문제를 피할 수 있습니다. 숨겨진 문제를 조기에 발견하려면 여러 환경에서 테스트하여 사용자에게 원활한 경험을 제공하고 스스로 마음의 평화를 누리도록 하세요. 😊

배포 문제 해결을 위한 소스 및 참조
  1. Angular 배포를 위해 IIS에서 MIME 유형을 구성하는 방법에 대한 자세한 설명: Microsoft IIS 설명서
  2. Angular 배포 전략 및 빌드 최적화에 대한 종합 가이드: Angular 공식 문서
  3. 파일 시스템 및 MIME 검증을 위한 Node.js API 참조: Node.js 문서
  4. 웹 서버의 정적 파일 구성 문제 해결 및 유효성 검사에 대한 모범 사례: MDN 웹 문서
  5. .NET 애플리케이션의 배포 오류 처리에 대한 실제 통찰력: 스택 오버플로 토론