vikejs / vike

🔨 Flexible, lean, community-driven, dependable, fast Vite-based frontend framework.
https://vike.dev
MIT License
4.35k stars 350 forks source link

Error [ERR_REQUIRE_ESM]: require() of ES Module dist\frontend\server\pageFiles.mjs not supported. #1057

Closed pmsmanishchauhan closed 1 year ago

pmsmanishchauhan commented 1 year ago

Description

On running npm run serve I am getting following 404 error and following error in terminal.

Error [ERR_REQUIRE_ESM]: require() of ES Module D:\self\jhattse-consumer\dist\frontend\server\pageFiles.mjs not supported.
Instead change the require of D:\self\jhattse-consumer\dist\frontend\server\pageFiles.mjs to a dynamic import() which is available in all CommonJS modules.   
    at D:\self\jhattse-consumer\dist\frontend\server\importBuild.cjs:30:68
    at async Promise.all (index 0)
    at async loadImportBuild (D:\self\jhattse-consumer\node_modules\vite-plugin-ssr\dist\cjs\node\runtime\globalContext\loadImportBuild.js:18:57)
    at async initGlobalContext (D:\self\jhattse-consumer\node_modules\vite-plugin-ssr\dist\cjs\node\runtime\globalContext.js:72:30)
    at async renderPageAndPrepare (D:\self\jhattse-consumer\node_modules\vite-plugin-ssr\dist\cjs\node\runtime\renderPage.js:79:9)
    at async renderPage_wrapper (D:\self\jhattse-consumer\node_modules\vite-plugin-ssr\dist\cjs\node\runtime\renderPage.js:32:24)
    at async renderPage (D:\self\jhattse-consumer\node_modules\vite-plugin-ssr\dist\cjs\node\runtime\renderPage.js:53:50)

I am attaching my configuration

\\ vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { viteCommonjs } from '@originjs/vite-plugin-commonjs'
import UnoCSS from 'unocss/vite'
import tsconfigPaths from 'vite-tsconfig-paths';
import Pages from 'vite-plugin-pages'

import type { UserConfig } from "vitest/config";

// @ts-ignore
import ssr from 'vite-plugin-ssr/plugin';

const test = {
    globals: true,
    environment: "jsdom",
    setupFiles: ["src/__tests__/setupTests.ts"],
    threads: false,
    watch: false,
} as UserConfig["test"];

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [Pages({ dirs: 'src/pages', routeStyle: 'next' }), ssr(), viteCommonjs(),
    UnoCSS(), react(), tsconfigPaths()],
    server: { port: 3000 },
    build: {
        minify: false,
        rollupOptions: {
            output: {
                format: "es",
            },
            external: [
                "react", // ignore react stuff
                "react/jsx-runtime",
                "react-dom",
                "recoil",
                "@chakra-ui/react",
                "react-icons",
                "react-icons/fa",
                "react-icons/md",
                "swiper/react",
                "react-helmet-async"
            ],
        },
        // commonjsOptions: { include: [], transformMixedEsModules: true, },
    },
    // optimizeDeps: {
    //     disabled: 'build'
    // },
    resolve: {
        alias: {
            "#api": "/api",
            "#components": "/src/client/components",
            "#recoil": "/src/client/recoil",
            "#core": "/src/client/core",
            "#renderer": "/src/client/renderer",
        },
        preserveSymlinks: true
    },
    root: "",
    // @ts-ignore
    test,
});
\\ tsconfig.js

{
    "compilerOptions": {
        "allowJs": true,
        "alwaysStrict": true,
        "allowSyntheticDefaultImports": true,
        "baseUrl": ".",
        "paths": {
            "#components/*": [
                "src/client/components/*"
            ],
            "#components": [
                "src/client/components"
            ],
            "#core/*": [
                "src/client/core/*"
            ],
            "#core": [
                "src/client/core"
            ],
            "@db": [
                "src/client/db"
            ],
            "@db/*": [
                "src/client/db/*"
            ],
            "@public/*": [
                "public/*"
            ],
            "@public": [
                "public"
            ],
            "#renderer/*": [
                "src/client/renderer/*"
            ],
            "#renderer": [
                "src/client/renderer"
            ],
            "@styles/*": [
                "src/client/styles/*"
            ],
            "@styles": [
                "src/client/styles"
            ],
            "#recoil/*": [
                "src/client/recoil/*"
            ],
            "#recoil": [
                "src/client/recoil"
            ],
            "#api": [
                "api"
            ],
            "#api/*": [
                "api/*"
            ]
        },
        "checkJs": true,
        "declaration": true,
        "declarationMap": true,
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "incremental": true,
        "jsx": "react-jsxdev",
        "lib": [
            "DOM",
            "DOM.Iterable",
            "ESNext"
        ],
        "strict": true,
        "outDir": "dist/frontend",
        "module": "ES2020",
        "moduleResolution": "Node",
        "skipLibCheck": true,
        "sourceMap": true,
        "target": "ES6"
    },
    "include": [
        "src/**/*",
        "api/**/*",
        "types/*",
        "node_modules/vite/types/*"
    ],
    "exclude": [
        "node_modules",
    ],
    "ts-node": {
        "esm": true,
        "transpileOnly": true,
        "compilerOptions": {
            "module": "ES2020"
        }
    },
    "lib": ["esnext"]
}
\\ package.json
{
  "name": "consumer",
  "version": "1.0.1",
  "private": true,
  "type": "module",
  "description": "Boilerplate for a modern web stack",
  "repository": {
    "type": "git",
    "url": "https://github.com/jonluca/vite-typescript-ssr-react"
  },
  "author": "JonLuca DeCaro",
  "license": "MIT",
  "scripts": {
    "dev:server": "nodemon --watch src/server --exec 'ts-node-esm src/server/index.ts'",
    "dev:client": "cross-env NODE_ENV=development yarn build:client && vite --config vite.config.ts dev",
    "build": "rimraf dist/frontend && tsc -p tsconfig.prod.json && yarn build:client && yarn build:server && yarn copy-files",
    "build:client": "vite build --outDir dist/frontend --ssrManifest --debug",
    "build:server": "vite build --ssr --outDir dist/frontend",
    "test": "vitest",
    "test:watch": "vitest --watch",
    "coverage": "vitest --coverage",
    "typecheck": "tsc --noEmit",
    "serve": "yarn build && cross-env NODE_ENV=production yarn ts-node-esm src/server/index.ts",
    "serve:local": "vite serve",
    "clean": "rimraf dist/frontend/",
    "copy-files": "copyfiles static/* dist/assets && copyfiles index.html dist/frontend && copyfiles -f dist/frontend/assets/* dist/assets",
    "format": "prettier --write ."
  },
  "dependencies": {
    "@chakra-ui/react": "^2.8.0",
    "@react-oauth/google": "^0.11.1",
    "@typescript-eslint/eslint-plugin": "^5.59.0",
    "@typescript-eslint/parser": "^5.59.0",
    "antd": "^5.7.3",
    "axios": "^1.4.0",
    "compression": "1.7.4",
    "cross-env": "^7.0.3",
    "cross-fetch": "^4.0.0",
    "dexie": "^3.2.4",
    "express": "4.18.2",
    "geolib": "^3.3.4",
    "gsap": "^3.12.2",
    "html5-qrcode": "^2.3.8",
    "js-cookie": "^3.0.5",
    "moment": "^2.29.4",
    "nodemon": "^2.0.22",
    "react": "^18.2.0",
    "react-countdown": "^2.3.5",
    "react-dom": "^18.2.0",
    "react-helmet": "^6.1.0",
    "react-helmet-async": "^1.3.0",
    "react-icons": "^4.10.1",
    "react-infinite-scroll-component": "^6.1.0",
    "react-intersection-observer": "^9.5.2",
    "react-markdown": "^8.0.7",
    "react-moment": "^1.1.3",
    "react-router-dom": "^6.10.0",
    "react-social-icons": "^5.15.0",
    "react-web-share": "^2.0.2",
    "recoil": "^0.7.7",
    "sass": "^1.64.1",
    "serve-static": "^1.15.0",
    "swiper": "^10.0.4",
    "ts-node": "^10.9.1",
    "urql": "^4.0.5",
    "uuid": "^9.0.0",
    "vite-plugin-pwa": "^0.16.4",
    "vite-plugin-ssr": "^0.4.133"
  },
  "devDependencies": {
    "@originjs/vite-plugin-commonjs": "^1.0.3",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^14.0.0",
    "@types/compression": "1.7.2",
    "@types/concurrently": "6.4.0",
    "@types/eslint": "8.37.0",
    "@types/express": "^4.17.17",
    "@types/js-cookie": "^3.0.3",
    "@types/node": "18.15.12",
    "@types/react": "^18.0.37",
    "@types/react-dom": "^18.0.11",
    "@types/react-helmet": "^6.1.6",
    "@types/react-router-dom": "^5.3.3",
    "@typescript-eslint/eslint-plugin": "^5.59.0",
    "@typescript-eslint/parser": "^5.59.0",
    "@vitejs/plugin-react": "^4.0.0",
    "concurrently": "8.0.1",
    "copyfiles": "^2.4.1",
    "eslint": "^8.38.0",
    "eslint-config-prettier": "^8.8.0",
    "eslint-config-standard": "^17.0.0",
    "eslint-plugin-react": "^7.32.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "jsdom": "^21.1.1",
    "prettier": "^2.8.7",
    "rimraf": "^5.0.0",
    "typescript": "5.0.4",
    "unocss": "^0.53.6",
    "vite": "^4.4.8",
    "vite-plugin-pages": "^0.31.0",
    "vite-tsconfig-paths": "^4.2.0",
    "vitest": "^0.30.1"
  },
  "imports": {
    "#components": "/src/client/components",
    "#recoil": "/src/client/recoil",
    "#core": "/src/client/core",
    "#renderer": "/src/client/renderer",
    "#api": "/api"
  }
}

and src/server/index.ts

\\ src/server/index.ts
import express from 'express'
import { renderPage } from 'vite-plugin-ssr/server'
import path from 'path';
import { fileURLToPath } from 'url';

const isProduction = process.env.NODE_ENV === 'production'
console.log(process.env.NODE_ENV)

const __filename = fileURLToPath(import.meta.url);

const __dirname = path.dirname(__filename);
const root = `${__dirname}/..`

startServer()

async function startServer() {
  // Create an Express.js server
  const app = express()

  // Vite integration
  if (!isProduction) {
    // We instantiate Vite's development server and integrate its middleware to our server.
    // ⚠️ We instantiate it only in development. (It isn't needed in production and it
    // would unnecessarily bloat our server in production.)
    const vite = await import('vite')
    const viteDevMiddleware = (await vite.createServer({
      root,
      server: { middlewareMode: true }
    })).middlewares
    app.use(viteDevMiddleware)
  } else {
    // In production, we need to serve our static assets ourselves.
    // (In dev, Vite's middleware serves our static assets.)
    app.use(express.static(`${root}/dist/assets`))
  }

  // ...
  // Other middlewares (e.g. some RPC middleware such as Telefunc)
  // ...

  // Vite-plugin-ssr middleware. It should always be our last middleware (because it's a
  // catch-all middleware superseding any middleware placed after it).
  app.get('*', async (req, res, next) => {
    const pageContextInit = { urlOriginal: req.originalUrl }
    const pageContext = await renderPage(pageContextInit)
    if (pageContext.httpResponse === null) return next()
    const { body, statusCode, contentType } = pageContext.httpResponse
    res.status(statusCode).type(contentType).send(body)
  })

  const port = 3000
  app.listen(port)
  console.log(`Server running at http://localhost:${port}`)
}

What is possibly wrong with this configuration?

brillout commented 1 year ago

The best would be a reproduction. It can but doesn't have to be minimal.

brillout commented 1 year ago

Actually, it's probably due to ts-node-esm. If you use something else, does it work then?

brillout commented 1 year ago

Moving to discussion because it's most likely due to ts-node-esm. I doesn't seem like a vite-plugin-ssr bug.