1

Working on a Nuxt 3 SSR application deployed to Azure DevOps + Web App through pipeline and running into the following console error message for every pre-rendered static .js route under /public/_nuxt/.

Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

The error originates in my /public/index.html entry-point on several lines that look like:

<link rel="modulepreload" as="script" crossorigin href="/_nuxt/useExample.37a37e6a.js">

I've tried fiddling with the web.config and nuxt.config.ts which hasn't done much but go one step backwards. Why would my routes either not be resolving correctly or if that isn't the issue, why wouldn't the "text/html" error be fixed by my nitro setting?

web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <defaultDocument>
      <files>
        <clear />
        <add value="public/index.html" />
      </files>
    </defaultDocument>

    <directoryBrowse enabled="true" />

    <rewrite>
      <rules>
        <rule name="Handle History Mode and custom routes" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>

    <staticContent>
      <mimeMap fileExtension=".mjs" mimeType="application/javascript" />
      <mimeMap fileExtension=".js" mimeType="application/javascript;" />
    </staticContent>

    <httpErrors>
      <remove statusCode="404" subStatusCode="-1" />
      <error statusCode="404" path="public/404.html" responseMode="ExecuteURL" />
    </httpErrors>
  </system.webServer>
</configuration>

nuxt.config.ts:

export default defineNuxtConfig({
    ...
    nitro: {
        publicAssets: ['/_nuxt/**/*'],
    },
    ssr: true,
    ...
});

azure-pipeline.yml:

trigger:
- sandbox

pool:
  vmImage: ubuntu-latest

stages:
  - stage: Build
    jobs:
      - job: BuildAndPackage
        steps:
          - task: NodeTool@0
            displayName: Install Node.js
            inputs:
              versionSpec: '18.x'

          - task: Npm@1
            displayName: Install Dependencies
            inputs:
              command: 'ci'

          - script: npm run build
            displayName: Build Nuxt App
          
          - script: npm run generate
            displayName: Generate Static Nuxt App
          
          - task: CopyFiles@2
            displayName: Copy Nuxt Output
            inputs:
              SourceFolder: '.output'
              Contents: '**/*'
              TargetFolder: '$(Build.ArtifactStagingDirectory)/nuxt-output'

          - task: CopyFiles@2
            displayName: Copy essential files to root
            inputs:
              SourceFolder: '$(Build.SourcesDirectory)'
              Contents: |
                package.json
                nuxt.config.ts
                tsconfig.json
                web.config
              TargetFolder: '$(Build.ArtifactStagingDirectory)/nuxt-output'

          - task: PublishBuildArtifacts@1
            displayName: Publish Nuxt Output Artifact
            inputs:
              PathtoPublish: '$(Build.ArtifactStagingDirectory)/nuxt-output'
              ArtifactName: nuxt-output

  - stage: Deploy
    displayName: Deploy to Azure Web App
    dependsOn: Build
    jobs:
    - job: Deploy
      displayName: Deploy Nuxt 3 application
      steps:
      - task: DownloadBuildArtifacts@0
        displayName: Download Nuxt Output Artifact
        inputs:
          artifactName: nuxt-output
          downloadPath: '$(Build.ArtifactStagingDirectory)/nuxt-output'
      - task: AzureWebApp@1
        displayName: 'Deploy to Azure Web App'
        inputs:
          azureSubscription: 'zzz'
          appType: 'webApp'
          appName: 'zzzz'
          slotName: 'zzzzz'
          package: '$(Build.ArtifactStagingDirectory)/nuxt-output/*'

  • Node: ~18
  • NPM: >= 7
  • Nuxt: 3.7.3
  • Azure Web App w/ Windows
  • Azure DevOps w/ Pipeline

Also found this GitHub issue that could be related - https://github.com/nuxt/nuxt/issues/19752

4
  • First host your web app on a local IIS machine, halfblood.pro/… and then you can migrate to Azure. Skipping the local test isn't good, as you can make typical mistakes. Commented Oct 30, 2023 at 22:11
  • could you please check console log for more detail. Make sure that the URLs in the modulepreload links are correct and that the JavaScript files are actually being served at those URLs. You can check this by trying to access the URLs directly in your browser or using a tool like curl.Make sure that the JavaScript files are being served with the correct MIME type (application/javascript). You can check this using the browser's network tab. check JavaScript files and the "Content-Type" header in the response. Commented Oct 31, 2023 at 6:15
  • @JalpaPanchal I do see that the JS file links look good and are returning 200 OK, but the Content-Type is text/html; charset=utf-8. Not sure how to fix that to be application/javascript. My guess would be somewhere in my web.config file. Commented Oct 31, 2023 at 14:59
  • update your condif file with this code: <staticContent> <remove fileExtension=".js" /> <mimeMap fileExtension=".js" mimeType="application/javascript" /> </staticContent> clear browser cache and try again to access the site Commented Nov 1, 2023 at 6:59

2 Answers 2

0

I created one sample NUXT SSR app and added the nitro configuration in my nuxt.config.js like below and it the Web app ran successfully like below:-

nuxt.config.js:-

export default {
  // Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    title: 'nuxtappsid',
    htmlAttrs: {
      lang: 'en'
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' },
      { name: 'format-detection', content: 'telephone=no' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },

  // Global CSS: https://go.nuxtjs.dev/config-css
  css: [
  ],

  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
  ],

  // Auto import components: https://go.nuxtjs.dev/config-components
  components: true,

  // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
  buildModules: [
    // https://go.nuxtjs.dev/typescript
    '@nuxt/typescript-build',
  ],

  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
  ],

  // Build Configuration: https://go.nuxtjs.dev/config-build
  build: {
  },
  nitro: {
    publicAssets: ['/_nuxt/**/*'],
    dynamicRoutes: {
        enabled: true,
        exclude: ['/public/**/*']
    }
},
}

Also, Try adding all your .js and .js extension in publicAsset section of nuxt.config.js file like below:-

publicAssets: ['/_nuxt/**/*', '.js', '.mjs'],

As per the suggestion by Jalpa Panchal try to Edit your web.config like below:-

<staticContent>
  <remove fileExtension=".js" />
  <mimeMap fileExtension=".js" mimeType="application/javascript" />
  <mimeMap fileExtension=".mjs" mimeType="application/javascript" />
</staticContent>

In your web.config try adding cache control like below to resolve your issue:-

<staticContent>
  <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
</staticContent>

Check that your deployment to Azure DevOps is correctly moving the produced JavaScript files to the correct locations. This error can occur if the files are not deployed or are in the incorrect directory.

One more alternative is to check Diagnose and Solve Problem tab in your Azure web app and get insight in your issue:-

enter image description here

Try the below DevOps yaml pipeline for your Nuxt App deployment:-

trigger:
- master

variables:

  
  azureSubscription: 'xxxxx7439c'

  # Web app name
  webAppName: 'valleywebapp980'

  # Environment name
  environmentName: 'valleywebapp980'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)

    steps:
    - task: NodeTool@0
      inputs:
        versionSpec: '10.x'
      displayName: 'Install Node.js'

    - script: |
        npm install
        npm run build --if-present
        npm run generate
        npm run test --if-present
      displayName: 'npm install, build and test'

    - task: ArchiveFiles@2
      displayName: 'Archive files'
      inputs:
        rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
        includeRootFolder: false
        archiveType: zip
        archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
        replaceExistingArchive: true

    - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
      artifact: drop

- stage: Deploy
  displayName: Deploy stage
  dependsOn: Build
  condition: succeeded()
  jobs:
  - deployment: Deploy
    displayName: Deploy
    environment: $(environmentName)
    pool:
      vmImage: $(vmImageName)
    strategy:
      runOnce:
        deploy:
          steps:
          - task: AzureWebApp@1
            displayName: 'Azure Web App Deploy: valleywebapp980'
            inputs:
              azureSubscription: $(azureSubscription)
              appType: webAppLinux
              appName: $(webAppName)
              runtimeStack: 'NODE|10.10'
              package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
              startUpCommand: 'npm run start'

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

0

I solved my problem by making sure my web.config's rewrite matching pattern didn't match my JavaScript file's name. My rewrite pattern was for 'Edit(or)?'. I basically wanted any request with this pattern to rewrite to another url. The problem was my JavaScript file was named 'newsEditor.js'. This caused my html page to search for the JavaScript file at the wrong URL.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.