analogjs / analog

The fullstack meta-framework for Angular. Powered by Vite and Nitro
https://analogjs.org
MIT License
2.48k stars 234 forks source link

SCSS styles are missing in static pages when updating @analogjs/platform@0.2.44 to @analogjs/platform@1.0.0-rc.0 or newer #969

Closed d-koppenhagen closed 5 months ago

d-koppenhagen commented 5 months ago

Please provide the environment you discovered this bug in.

{
  // ...
  "type": "module",
  "engines": {
    "node": ">=20"
  },
  "dependencies": {
    "@analogjs/content": "^1.0.2",
    "@analogjs/router": "^1.0.2",
    "@angular/animations": "^17.3.0",
    "@angular/cdk": "^17.3.0",
    "@angular/common": "^17.3.0",
    "@angular/compiler": "^17.3.0",
    "@angular/core": "^17.3.0",
    "@angular/forms": "^17.3.0",
    "@angular/material": "^17.3.0",
    "@angular/platform-browser": "^17.3.0",
    "@angular/platform-browser-dynamic": "^17.3.0",
    "@angular/platform-server": "^17.3.0",
    "@angular/router": "^17.3.0",
    "@angular/service-worker": "^17.3.0",
    "@angular/youtube-player": "^17.3.0",
    "@fortawesome/angular-fontawesome": "^0.14.1",
    "@fortawesome/fontawesome-free": "^5.15.4",
    "@fortawesome/fontawesome-svg-core": "~1.2.36",
    "@fortawesome/free-brands-svg-icons": "^5.15.4",
    "@fortawesome/free-regular-svg-icons": "^5.15.4",
    "@fortawesome/free-solid-svg-icons": "^5.15.4",
    "@nx/angular": "^18.0.0",
    "angular-twitter-timeline": "^17.0.0",
    "animate.css": "^4.1.1",
    "clipboard": "^2.0.11",
    "feed": "^4.2.2",
    "front-matter": "^4.0.2",
    "marked": "^12.0.1",
    "marked-gfm-heading-id": "^3.1.3",
    "marked-highlight": "^2.1.1",
    "mermaid": "^10.9.0",
    "ngx-sharebuttons": "^13.0.0",
    "prismjs": "^1.29.0",
    "rxjs": "~7.8.1",
    "tslib": "^2.6.2",
    "zone.js": "~0.14.4"
  },
  "devDependencies": {
    "@analogjs/platform": "^1.0.2",
    "@analogjs/vite-plugin-angular": "^1.0.2",
    "@angular-devkit/build-angular": "^17.3.0",
    "@angular-eslint/builder": "17.2.1",
    "@angular-eslint/eslint-plugin": "17.2.1",
    "@angular-eslint/eslint-plugin-template": "17.2.1",
    "@angular-eslint/schematics": "17.2.1",
    "@angular-eslint/template-parser": "17.2.1",
    "@angular/cli": "^17.3.0",
    "@angular/compiler-cli": "^17.3.0",
    "@nx/vite": "^18.0.8",
    "@typescript-eslint/eslint-plugin": "7.2.0",
    "@typescript-eslint/parser": "7.2.0",
    "eslint": "^8.57.0",
    "eslint-plugin-prettier": "^5.1.3",
    "husky": "^9.0.11",
    "jsdom": "^24.0.0",
    "lint-staged": "^15.2.2",
    "nx": "^18.0.8",
    "prettier": "^3.2.5",
    "sass": "^1.72.0",
    "typescript": "~5.3.3",
    "vite": "^5.2.6",
    "vitest": "^1.4.0"
  },
}

Which area/package is the issue in?

platform

Description

I started to migrate my Analog project / static page to version 1.0.0. First it seemed to work and running npm run dev works good without any issues after migration. Now I realized, the production build generated when running npm run build in dist/analog/public seems not to include some styles. It looks like all references SCSS files aren't part of the build when comparing the served version of dist/analog/public and the result of the dev server running npm run dev.

npm run devBildschirmfoto 2024-03-26 um 19 33 39

npm run buildBildschirmfoto 2024-03-26 um 19 34 16

I started to isolate the problem a bit more and I will run only in this issue when updating from @analogjs/platform@0.2.44 to @analogjs/platform@1.0.0-rc.0 or newer. All other analog packages are running perfectly in version 1.0.0 and newer.

The problem can be reproduced by checking out my repository https://github.com/d-koppenhagen/k9n.dev - Branch: analogjs-platform-1.x.x.

Please provide the exception or error you saw

> ng build

TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')

...

✓ built in 45.24s
Building SSR application...
vite v5.2.6 building SSR bundle for production...
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
TypeError: Cannot read properties of undefined (reading 'addWatchFile')
✓ 134 modules transformed.

...

dist/ssr/main.server.js                                                    1,771.95 kB
✓ built in 15.20s
Prerendering static pages...
Building Server...
TypeError: The URL must be of scheme file
    at new NodeError (node:internal/errors:406:5)
    at fileURLToPath (node:internal/url:1393:11)
    at fileURLToPath (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:1976:25)
    at pathToFileURL (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:1979:26)
    at _resolve (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2113:10)
    at resolveSync (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2116:10)
    at resolvePathSync (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2126:24)
    at resolvePath (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2130:28)
    at _resolve (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/nitropack/dist/nitro.mjs:421:22)
    at Object.resolveId (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/nitropack/dist/nitro.mjs:457:29) {
  code: 'ERR_INVALID_URL_SCHEME'
}
TypeError: The URL must be of scheme file
    at new NodeError (node:internal/errors:406:5)
    at fileURLToPath (node:internal/url:1393:11)
    at fileURLToPath (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:1976:25)
    at pathToFileURL (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:1979:26)
    at _resolve (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2113:10)
    at resolveSync (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2116:10)
    at resolvePathSync (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2126:24)
    at resolvePath (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2130:28)
    at _resolve (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/nitropack/dist/nitro.mjs:421:22)
    at Object.resolveId (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/nitropack/dist/nitro.mjs:457:29) {
  code: 'ERR_INVALID_URL_SCHEME'
}
TypeError: The URL must be of scheme file
    at new NodeError (node:internal/errors:406:5)
    at fileURLToPath (node:internal/url:1393:11)
    at fileURLToPath (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:1976:25)
    at pathToFileURL (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:1979:26)
    at _resolve (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2113:10)
    at resolveSync (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2116:10)
    at resolvePathSync (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2126:24)
    at resolvePath (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/mlly/dist/index.mjs:2130:28)
    at _resolve (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/nitropack/dist/nitro.mjs:421:22)
    at Object.resolveId (file:///Users/dannykoppenhagen/dev/k9n.dev/node_modules/nitropack/dist/nitro.mjs:457:29) {
  code: 'ERR_INVALID_URL_SCHEME'
}
Building Sitemap...
Writing sitemap at /Users/dannykoppenhagen/dev/k9n.dev/dist/analog/public/sitemap.xml

The '@analogjs/platform' server has been successfully built.

Other information

No response

I would be willing to submit a PR to fix this issue

d-koppenhagen commented 5 months ago

This is how my vite.config.ts looks like:

import analog, { PrerenderContentFile } from '@analogjs/platform';
import angular from '@analogjs/vite-plugin-angular';
import { PostAttributes } from 'src/app/types';
/// <reference types="vitest" />

import { defineConfig } from 'vite';

function transFormContentDirRoute(file: PrerenderContentFile, base: string) {
  const attributes = file.attributes as PostAttributes;
  // do not include files marked as draft in frontmatter
  if (attributes.draft) {
    return false;
  }
  // use the slug from frontmatter if defined, otherwise use the files basename
  const slug = attributes.slug || file.name;
  return `/${base}/${slug}`;
}

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => ({
  publicDir: 'src/assets',
  build: {
    target: ['es2020'],
  },
  resolve: {
    mainFields: ['module'],
  },
  plugins: [
    angular({
      inlineStylesExtension: 'scss',
    }),
    analog({
      prerender: {
        routes: [
          '/api/rss.xml',
          '/',
          '/blog',
          '/contact',
          '/imprint',
          '/projects',
          '/recruitment',
          {
            contentDir: '/src/content/blog',
            transform: (file: PrerenderContentFile) =>
              transFormContentDirRoute(file, 'blog'),
          },
          {
            contentDir: '/src/content/projects',
            transform: (file: PrerenderContentFile) =>
              transFormContentDirRoute(file, 'projects'),
          },
          {
            contentDir: '/src/content/talks',
            transform: (file: PrerenderContentFile) =>
              transFormContentDirRoute(file, 'talks'),
          },
        ],
        postRenderingHooks: [
          async (route) => {
            if (route.route.endsWith('.xml')) {
              return;
            }
            const gTag = `<script>
            (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
              (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
              m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
              })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
              ga('create', 'UA-XXXXXXXXX-1', 'auto');
              ga('send', 'pageview');
            </script>`;
            route.contents = route.contents?.concat(gTag);
          },
        ],
        sitemap: {
          host: 'https://k9n.dev/',
        },
      },
    }),
  ],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['src/test.ts'],
    include: ['**/*.spec.ts'],
    reporters: ['default'],
  },
  define: {
    'import.meta.vitest': mode !== 'production',
  },
}));
brandonroberts commented 5 months ago

I've tracked down the TypeError: The URL must be of scheme file error to a change that happened between nitropack 2.9.4 and 2.9.5. Maybe @pi0 has some insight there. May be related to this PR https://github.com/unjs/nitro/pull/2289

A workaround is to pin nitropack to 2.9.4 in your package.json

Not sure where the addWatchFile error is coming from. We only use that in watch mode.

brandonroberts commented 5 months ago

Pinning Vite to ~5.0.0 also fixes the styles issue when doing the build and the addWatchFile error

d-koppenhagen commented 5 months ago

Thanks @brandonroberts this will fix my issues for now. Should I let this issue open to track the dependency issues? Probably @analogjs/platform should define a peerDependency config to prevent users for accidentally updating vite to a newer minor version and rollback nitropack to 2.9.4.

pi0 commented 5 months ago

Hi. Checking this, is there a hope you can make a more minimal reproduction i can check? 🙏🏼

brandonroberts commented 5 months ago

Hi. Checking this, is there a hope you can make a more minimal reproduction i can check? 🙏🏼

Thanks @pi0, here's a reproduction - https://github.com/brandonroberts/analog-nitro-295

Steps to reproduce

  1. npm create analog@latest analog-app
  2. cd analog-app
  3. npm install
  4. npm run build

The build finishes but the error messages are logged.

Running npm list nitropack shows the version at 2.9.5. Pinning to 2.9.4 doesn't log any errors.

The two files it throws the error on is dist/analog/client/index.html and dist/analog/client/assets/index-[hash].css. We use the index.html in the runtime renderer

https://github.com/analogjs/analog/blob/beta/packages/vite-plugin-nitro/src/lib/runtime/renderer.ts#L6

brandonroberts commented 5 months ago

Thanks @brandonroberts this will fix my issues for now. Should I let this issue open to track the dependency issues? Probably @analogjs/platform should define a peerDependency config to prevent users for accidentally updating vite to a newer minor version and rollback nitropack to 2.9.4.

Vite is already included as a peer dependency with the Angular CLI, so we don't want to create a conflicting one that results in install errors. We'll make the nitropack dependency version less permissive for now and validate against newer versions in the future

pi0 commented 5 months ago

Thanks for the nice reproduction. The fix (https://github.com/unjs/nitro/pull/2321) is marged and testable via nightly channel. i likely make a patch release today. (Note: it only removes the unwanted console error, i expect rest of the nitro behavior is same).

brandonroberts commented 5 months ago

@d-koppenhagen I figured out the addWatchFile also, and it's due to how we extract the vite:css plugin during the build. Its being called without the correct scope.

There was a change in Vite 5.1 that surfaced this behavior. Will land a fix for this also which will allow you to go back to the latest release of Vite

d-koppenhagen commented 5 months ago

Awesome! Great that you found it out. And thanks a lot for your support and time invested!

damilolaadebowale commented 1 month ago

this is still happening on the latest version

{
  "name": "faverites",
  "version": "0.0.0",
  "type": "module",
  "engines": {
    "node": ">=18.19.1"
  },
  "scripts": {
    "ng": "ng",
    "dev": "ng serve",
    "start": "npm run dev",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@analogjs/content": "^1.5.0",
    "@analogjs/router": "^1.5.0",
    "@angular/animations": "^18.0.0",
    "@angular/common": "^18.0.0",
    "@angular/compiler": "^18.0.0",
    "@angular/core": "^18.0.0",
    "@angular/forms": "^18.0.0",
    "@angular/platform-browser": "^18.0.0",
    "@angular/platform-browser-dynamic": "^18.0.0",
    "@angular/platform-server": "^18.0.0",
    "@angular/router": "^18.0.0",
    "front-matter": "^4.0.2",
    "marked": "^5.0.2",
    "marked-gfm-heading-id": "^3.1.0",
    "marked-highlight": "^2.0.1",
    "marked-mangle": "^1.1.7",
    "primeng": "^17.18.1",
    "prismjs": "^1.29.0",
    "rxjs": "~7.8.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.14.3"
  },
  "devDependencies": {
    "@analogjs/platform": "^1.5.0",
    "@analogjs/vite-plugin-angular": "^1.5.0",
    "@angular-devkit/build-angular": "^18.0.0",
    "@angular/cli": "^18.0.0",
    "@angular/compiler-cli": "^18.0.0",
    "autoprefixer": "^10.4.14",
    "jsdom": "^22.0.0",
    "postcss": "^8.4.21",
    "tailwindcss": "^3.3.1",
    "typescript": "~5.4.2",
    "vite": "~5.2.11",
    "vite-tsconfig-paths": "^4.2.0",
    "vitest": "^1.3.1"
  }
}
damilolaadebowale commented 1 month ago

but i notice if switch browser or open a new profile it works again