quasarframework / quasar

Quasar Framework - Build high-performance VueJS user interfaces in record time
https://quasar.dev
MIT License
25.52k stars 3.45k forks source link

[vite] Internal server error: window is not defined #16557

Closed Valgri closed 8 months ago

Valgri commented 8 months ago

What happened?

I'm doing a migration from webpack to vite. I have done all the recommendations for migration. When starting quasar dev

image

package.json

{ "name": "project", "version": "0.0.1", "description": "", "productName": "project", "author": "", "private": true, "scripts": { "lint": "eslint --fix --ext .js,.vue src", "test": "jest --notify -i --no-cache --coverage=\"true\"", "test:debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --watch", "dev:ssr": "yarn && env-cmd -f ./.env.dev quasar dev -m ssr", "dev:spa": "yarn && env-cmd -f ./.env.dev quasar dev", "dev:android": "yarn && quasar dev -m cordova -T android -- --buildConfig=\"../build.cordova.json\"", "dev:ios": "yarn && quasar dev -m cordova -T ios -- --buildConfig=\"../build.cordova.json\"", "dev:electron": "yarn && quasar dev -m cordova -T electron -- --buildConfig=\"../build.cordova.json\"", "build:ssr": "yarn && env-cmd -f ./.env.prod quasar build -m ssr", "build:spa": "yarn && yarn update-top-level-domains && yarn build-banner && yarn supportedBrowsers && env-cmd -f ./.env.prod quasar build ", "build:android": "yarn start && quasar build -m cordova -T android -- --buildConfig=\"../build.cordova.json\"", "build:ios": "yarn start && quasar build -m cordova -T ios -- --buildConfig=\"../build.cordova.json\"", "build:electron": "yarn start && quasar build -m cordova -T electron -- --buildConfig=\"../build.cordova.json\"", "stylelint": "./node_modules/.bin/stylelint \"**/*.{scss,vue}\" --fix", "styleguide": "vue-styleguidist server", "styleguide:build": "vue-styleguidist build", "collect-keys": "node src/server/index.js", "collect-keys-with-check": "node src/server/index.js check", "translate": "node src/server/translations.js", "translate-local": "env-cmd -f ./.env.dev node src/server/translations.js", "clear-translation-cache": "env-cmd -f ./.env.dev node src/server/clear-translation-cache.js", "update-top-level-domains": "node src/server/update-top-level-domains.js", "update-static-data-db": "env-cmd -f ./.env.dev node src/server/update-static-data-db.js", "import-icons": "node src/server/figma-icons-importer.js", "create-component": "hygen create component", "reset-modules": "./node_modules/.bin/rimraf -rf ./node_modules && rm yarn.lock && yarn", "dev-banner": "cd banner && yarn dev", "build-banner": "cd banner && yarn build", "docs": "cd ./node_modules/docs && yarn && yarn dev", "update-static-data-local": "node src/server/update-static-data.js", "update-static-translations-local": "node src/server/update-static-translations-local.js", "run-git-api": "env-cmd -f ./.env.dev node src/server/gitlab.js", "supportedBrowsers": "echo \"window.supportedBrowsers = $(browserslist-useragent-regexp --allowHigherVersions);\" > ./public/supportedBrowsers.js" }, "dependencies": { "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@growthbook/growthbook": "^0.27.0", "@quasar/extras": "^1.16.4", "@stripe/stripe-js": "1.48.0", "@vee-validate/rules": "^4.8.4", "axios": "1.3.4", "body-scroll-lock": "^3.1.5", "browserslist-useragent": "4.0.0", "chart.js": "^3.8.2", "copy-to-clipboard": "^3.3.3", "cross-env": "7.0.3", "date-fns": "2.29.3", "date-fns-tz": "2.0.0", "date-time-format-timezone": "1.0.22", "daterange-picker-for-vue-3": "^0.0.2", "env-cmd": "10.1.0", "file-saver": "2.0.5", "html-entities": "1.3.1", "intersection-observer": "0.12.2", "jsvat": "^2.5.3", "lodash": "^4.17.21", "mapbox-gl": "1.12.0", "md5": "2.3.0", "process": "^0.11.10", "quasar": "^2.6.0", "showdown": "^2.1.0", "shrink-ray-current": "4.1.3", "superstruct": "0.8.3", "vee-validate": "4.8.1", "vue": "^3.0.0", "vue-error-boundary": "2.0.1", "vue-i18n": "9.4.1", "vue-popperjs": "^2.3.0", "vue-router": "4.2.1", "vue-slider-component": "^4.1.0-beta.7", "vue-social-sharing": "4.0.0-alpha4", "vue3-popper": "^1.5.0", "vuex": "^4.0.1", "vuex-persistedstate": "4.1.0", "wallaby-vue-compiler": "^1.0.6" }, "//dependencies": { "daterange-picker-for-vue-3": "TODO::: This package can be replaced with daterange-picker-vue3 after the PR https://github.com/davolcu/vue3-daterange-picker/pull/2" }, "devDependencies": { "@babel/eslint-parser": "^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-optional-chaining": "7.21.0", "@babel/plugin-transform-modules-commonjs": "^7.23.0", "@intlify/vite-plugin-vue-i18n": "^3.3.1", "@intlify/vue-i18n-loader": "^4.2.0", "@originjs/vite-plugin-commonjs": "^1.0.3", "@quasar/app-vite": "^1.3.0", "@vue/compiler-sfc": "3.3.2", "@vue/devtools": "^6.5.1", "@vue/eslint-config-airbnb": "4.0.0", "@vue/test-utils": "^2.0.0-rc.18", "@vue/vue3-jest": "^29.2.4", "autoprefixer": "^10.4.2", "babel-core": "^7.0.0-bridge.0", "babel-jest": "29.5.0", "babel-polyfill": "6.26.0", "browserslist-useragent-regexp": "4.0.0", "core-js": "3.32.0", "dotenv": "^16.0.3", "eslint": "^8.53.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-standard": "^16.0.2", "eslint-plugin-import": "^2.20.1", "eslint-plugin-no-cyrillic-string": "1.0.5", "eslint-plugin-node": "^11.0.0", "eslint-plugin-promise": "^5.1.0", "eslint-plugin-quasar": "^1.0.0", "eslint-plugin-vue": "^9.0.0", "figma-js": "1.16.0", "find-in-files": "0.5.0", "husky": "3.0.9", "hygen": "6.2.11", "identity-obj-proxy": "3.0.0", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "jest-serializer-vue": "3.1.0", "jest-watch-typeahead": "^2.2.2", "lint-staged": "^13.1.2", "node-notifier": "^10.0.1", "pm2": "4.4.0", "postcss": "^8.4.14", "prettier-stylelint": "0.4.2", "rimraf": "4.3.1", "stylelint": "13.13.1", "stylelint-config-recommended-scss": "4.3.0", "stylelint-declaration-block-no-ignored-properties": "2.7.0", "stylelint-declaration-use-variable": "1.7.3", "stylelint-high-performance-animation": "1.8.0", "stylelint-order": "6.0.3", "stylelint-scss": "4.4.0", "svgo": "3.0.2", "vite-plugin-babel": "^1.1.3", "vite-plugin-eslint": "^1.8.1", "vite-plugin-stylelint": "^5.2.0", "vue-styleguidist": "^4.58.0", "vue-template-compiler": "2.7.14" }, "engines": { "node": "^18 || ^16 || ^14.19", "npm": ">= 6.13.4", "yarn": ">= 1.21.1" }, "husky": { "hooks": { "pre-commit": "lint-staged" } }, "// ./src/**/*.+(js|vue)": [ "remove // from the start of key when tests will be fixed and move it back in lint-stage object", "jest --findRelatedTests --coverage=\"false\"", "git add" ], "lint-staged": { "./src/**/*.+(vue|scss)": [ "yarn stylelint", "git add" ], "./src/**/*.+(vue)": [ "yarn collect-keys", "yarn translate-local", "git add" ], "**/*.+(js|vue)": [ "yarn lint", "git add" ] } }

quasar.config.js

`/ eslint-env node /

/*

// Configuration for your app // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js const md5 = require('md5'); const { join } = require('path'); const fs = require('fs'); const { configure } = require('quasar/wrappers'); // helper to get a better IDE autocomplete experience (through Typescript) require('dotenv').config();

/ eslint func-names: 0 / / eslint global-require: 0 /

const hash = md5(Date.now());

module.exports = configure((ctx) => ({ eslint: { fix: true, // include: [], // exclude: [], // rawOptions: {}, warnings: ctx.dev, errors: ctx.prod, },

// https://v2.quasar.dev/quasar-cli-vite/prefetch-feature preFetch: true,

// app boot file (/src/boot) // --> boot files are part of "main.js" // https://v2.quasar.dev/quasar-cli-vite/boot-files boot: [ // { path: 'env', client: false }, 'env', 'ua-polyfills', 'extend-lib-components', // { path: 'ssr-translations', client: false }, 'global', 'user-storage', 'i18n', 'translation', 'interceptors-api', 'shopify-redirect', { path: 'goto', client: false }, 'router', 'vee-validate', { path: 'persist-state-client', server: false }, 'source-data', 'static-data', 'growthbook', ],

// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css css: [ 'app.scss', 'global/_mixins.scss', 'global/_variables.scss', ],

// https://github.com/quasarframework/quasar/tree/dev/extras extras: [ // 'ionicons-v4', // 'mdi-v5', // 'fontawesome-v6', // 'eva-icons', // 'themify', // 'line-awesome', // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!

'roboto-font', // optional, you are not bound to it
'material-icons', // optional, you are not bound to it

],

// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer devServer: { // https: true open: false, // opens browser window automatically hmr: { overlay: false }, before: (app) => { app.use('/static_translations', (req, res) => { res.setHeader('Content-Type', 'application/json'); const data = fs.readFileSync(./src/statics/static_translations/${req.params.file}); res.end(data); });

  app.use('/static_data', (req, res) => {
    res.setHeader('Content-Type', 'application/json');
    const data = fs.readFileSync(`./src/statics/static_data/${req.params.file}`);
    res.end(data);
  });
},
proxy: {
  '/cms': {
    target: 'http://test-api.my-app.online',
    changeOrigin: true,
  },
  '/img': {
    target: 'http://test-api.my-app.online',
    changeOrigin: true,
  },
  '/downloads': {
    target: 'http://test-api.my-app.online',
    changeOrigin: true,
  },
},

},

// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build build: { target: { browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'], node: 'node16', }, afterBuild: () => { const pathToSPA = './dist/spa'; // added to insert "FE_FULL_DOMAIN" instead of / in index.html file ( ...<base href=/ ... ) // needed for prerender deploys fs.readFile(${pathToSPA}/index.html, 'utf-8', (err, mainHtml) => { if (err) { console.warn(err); } else { const envVar = 'FE_FULL_DOMAIN'; const newHtml = mainHtml.replace( /((.|\n))(base href=\/)((.|\n))/, // split html file over 'base href=/' $1base href="${envVar}"$4, // $1 - before searched text, $4 - everything after it ); // make sure we just changed / to "FE_FULL_DOMAIN" in base.href // we should substract envVar.length + 2 (quots) - 1 ( / was initially ) if (mainHtml.length === newHtml.length - envVar.length - 1) { fs.writeFileSync(${pathToSPA}/index.html, newHtml); console.log(${envVar} has been added to ${pathToSPA}/index.html); } else { console.warn(${envVar} was not added to ${pathToSPA}/index.html); } } });

  // prevent errors if SPA is not built
  if (!fs.existsSync(pathToSPA)) return;

  fs.writeFileSync(`${pathToSPA}/hash.json`, JSON.stringify({ hash }));
  fs.writeFileSync(`${pathToSPA}/env.json`, JSON.stringify({
    API_URL: process.env.API_URL,
    GOOGLE_API_KEY: process.env.GOOGLE_API_KEY,
    SHOW_CHARTS_LINK: process.env.SHOW_CHARTS_LINK,
    MAP_BOX_KEY: process.env.MAP_BOX_KEY,
    ENABLE_NEW_RELIC: process.env.ENABLE_NEW_RELIC,
    ENABLE_DEVICE_INDENT: process.env.ENABLE_DEVICE_INDENT,
    DEVICE_INDENT_SNIPPET_ID: process.env.DEVICE_INDENT_SNIPPET_ID,
    DEVICE_INDENT_SUBDOMAIN: process.env.DEVICE_INDENT_SUBDOMAIN,
  }, null, 4));
},

vueRouterMode: 'history', // available values: 'hash', 'history'
// vueRouterBase,
// vueDevtools: true,
vueOptionsAPI: true,

// rebuildCache: true, // rebuilds Vite/linter/etc cache on startup

// publicPath: '/',
analyze: process.argv.includes('--analyze'),
env: {
  BUILD_HASH: hash,
  API_URL: process.env.API_URL,
  GOOGLE_API_KEY: process.env.GOOGLE_API_KEY,
  DOMAIN_NAME: process.env.DOMAIN_NAME,
  BACKEND_DOMAIN: process.env.BACKEND_DOMAIN,
  MAP_BOX_KEY: process.env.MAP_BOX_KEY,
  ADMIN_TOKEN: process.env.ADMIN_TOKEN,
  FE_FULL_DOMAIN: process.env.FE_FULL_DOMAIN,
  FB_APP_ID: process.env.FB_APP_ID,
  SHOW_CHARTS_LINK: process.env.SHOW_CHARTS_LINK,
  ENABLE_NEW_RELIC: process.env.ENABLE_NEW_RELIC,
  ENABLE_DEVICE_INDENT: process.env.ENABLE_DEVICE_INDENT,
  DEVICE_INDENT_SNIPPET_ID: process.env.DEVICE_INDENT_SNIPPET_ID,
  DEVICE_INDENT_SUBDOMAIN: process.env.DEVICE_INDENT_SUBDOMAIN,
},
// rawDefine: {}
// ignorePublicFolder: true,
minify: 'terser',
// polyfillModulePreload: true,
// distDir
extendViteConf(viteConf, { isClient }) {
  viteConf.resolve.alias.styles = join(__dirname, './src/css');
  viteConf.resolve.alias.public = join(__dirname, './public');

  // TODO: need figure-out is this need for vite
  // if (viteConf.mode === 'production') {
  //   const imgRule = viteConf.module.rules.find((e) => e.test.toString().includes('png'));
  //   const imgLoader = imgRule.use.find((e) => e.loader === 'url-loader');
  //
  //   imgLoader.options.name = 'images/[name].[ext]';
  // }

  if (isClient) {
    viteConf.build = {
      rollupOptions: {
        external: ['lodash'],
        output: {
          manualChunks: {
            mapbox: ['mapbox-gl'],
            vueSliderComponent: ['vue-slider-component'],
            dateTimeFormatTimeZone: ['date-time-format-timezone'],
            intersectionObserver: ['intersection-observer'],
          },
        },
      },
    };
  }
},
// viteVuePluginOptions: {},

vitePlugins: [
  ['vite-plugin-babel', {
    babelConfig: {
      babelrc: false,
      configFile: false,
      presets: [
        '@babel/preset-env',
        '@quasar/babel-preset-app',
      ],
      plugins: [
        '@babel/plugin-proposal-optional-chaining',
        '@babel/plugin-proposal-nullish-coalescing-operator',
        '@babel/plugin-transform-modules-commonjs',
        'lodash',
      ],
    },
  }],
  ['vite-plugin-stylelint', {
    fix: true,
  }],
  // ['@intlify/vite-plugin-vue-i18n', {
  //   // if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
  //   // compositionOnly: false,
  //
  //   // if you want to use named tokens in your Vue I18n messages, such as 'Hello {name}',
  //   // you need to set `runtimeOnly: false`
  //   // runtimeOnly: false,
  //
  //   // you need to set i18n resource including paths !
  //   include: path.resolve(__dirname, './src/i18n/**'),
  // }],
],

},

// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework framework: { config: { loadingBar: { color: 'primary', // hint: if changed here - should be also changed in index.html styles }, }, cssAddon: false, // iconSet: 'material-icons', // Quasar icon set // lang: 'en-US', // Quasar language pack

// For special cases outside of where the auto-import strategy can have an impact
// (like functional components as one of the examples),
// you can manually specify Quasar components/directives to be available everywhere:
//
components: ['QBtn', 'QIcon', 'QList', 'QItem', 'QItemSection',
  'QItemLabel', 'QTooltip', 'QImg', 'QVirtualScroll', 'QForm', 'QToolbar',
  'QPageContainer', 'QPage', 'QDialog', 'QInput', 'QLayout', 'QHeader',
  'QAvatar', 'QMenu', 'QSeparator', 'QToolbarTitle', 'QSpace', 'QBadge', 'QMarkupTable',
  'QDrawer', 'QScrollArea', 'QCard', 'QCardSection', 'QToggle', 'QNoSsr',
  'QSelect', 'QCardActions', 'QDate', 'QCheckbox', 'QRadio', 'QPopupProxy', 'QTime', 'QTable',
  'QTh', 'QTr', 'QTd', 'QExpansionItem', 'QPagination', 'QSpinner', 'QSpinnerGrid', 'QSplitter', 'QTabPanels',
  'QTabPanel', 'QTabs', 'QTab', 'QFooter', 'QBreadcrumbs', 'QBreadcrumbsEl', 'QStepper', 'QStep', 'QTimeline',
  'QTimelineEntry', 'QInfiniteScroll', 'QChip', 'QRadio', 'QBtnDropdown', 'QOptionGroup', 'QSkeleton',
  'QLinearProgress', 'QTree', 'QCarousel',
],

directives: ['Ripple', 'ClosePopup'],

// Quasar plugins
plugins: ['Cookies', 'Notify', 'LoadingBar', 'LocalStorage', 'Dialog', 'Meta'],

},

// animations: 'all', // --- includes all animations // https://v2.quasar.dev/options/animations animations: ['headShake', 'slideInDown', 'pulse'],

// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#property-sourcefiles // sourceFiles: { // rootComponent: 'src/App.vue', // router: 'src/router/index', // store: 'src/store/index', // registerServiceWorker: 'src-pwa/register-service-worker', // serviceWorker: 'src-pwa/custom-service-worker', // pwaManifestFile: 'src-pwa/manifest.json', // electronMain: 'src-electron/electron-main', // electronPreload: 'src-electron/electron-preload' // },

// https://v2.quasar.dev/quasar-cli-vite/developing-ssr/configuring-ssr ssr: { // ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name! // will mess up SSR

// extendSSRWebserverConf (esbuildConf) {},
// extendPackageJson (json) {},
pwa: false,

// manualStoreHydration: true,
// manualPostHydrationTrigger: true,

// prodPort: 3000, // The default port that the production server should use
// (gets superseded if process.env.PORT is specified at runtime)

// middlewares: [
//   'render', // keep this as last one
// ],

},

// https://v2.quasar.dev/quasar-cli-vite/developing-pwa/configuring-pwa pwa: { // workboxMode: 'generateSW', // or 'injectManifest' // injectPwaMetaTags: true, // swFilename: 'sw.js', // manifestFilename: 'manifest.json', // useCredentialsForManifestTag: false, // useFilenameHashes: true, // extendGenerateSWOptions (cfg) {} // extendInjectManifestOptions (cfg) {}, extendManifestJson(json) { return { ...json, name: 'my-app', short_name: 'my-app', display: 'standalone', background_color: '#ffffff', theme_color: '#ffffff', icons: [ { src: 'icons/android-chrome-192x192.png', sizes: '192x192', type: 'image/png', }, { src: 'icons/android-chrome-512x512.png', sizes: '512x512', type: 'image/png', }, ], }; }, // extendPWACustomSWConf (esbuildConf) {} },

// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-cordova-apps/configuring-cordova cordova: { // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing },

// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor capacitor: { hideSplashscreen: true, },

// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron electron: { // extendElectronMainConf (esbuildConf) // extendElectronPreloadConf (esbuildConf)

// specify the debugging port to use for the Electron app when running in development mode
inspectPort: 5858,

bundler: 'packager', // 'packager' or 'builder'

packager: {
  // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options

  // OS X / Mac App Store
  // appBundleId: '',
  // appCategoryType: '',
  // osxSign: '',
  // protocol: 'myapp://path',

  // Windows only
  // win32metadata: { ... }
},

builder: {
  // https://www.electron.build/configuration/configuration

  // appId: 'my-app',
},

},

// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex bex: { contentScripts: [ 'my-content-script', ],

// extendBexScriptsConf (esbuildConf) {}
// extendBexManifestJson (json) {}

}, })); `

Help please, I've given up hope of understanding the cause. Perhaps it can be learnt somehow interleaved debug.

The project starts, but as soon as I try to open it in browser I get this. If you need any more information, please let me know, thanks

What did you expect to happen?

Project is runned

Reproduction URL

/

How to reproduce?

create empty project with https://quasar.dev/quasar-cli-vite/convert-to-quasar-cli-with-vite

Flavour

Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)

Areas

Quasar CLI Commands/Configuration (@quasar/cli | @quasar/app-webpack | @quasar/app-vite), SPA Mode

Platforms/Browsers

Chrome

Quasar info output

No response

Relevant log output

No response

Additional context

No response

github-actions[bot] commented 8 months ago

Hi @Valgri! 👋

It looks like you provided an invalid or unsupported reproduction URL. Do not use any service other than Codepen, jsFiddle, StackBlitz, Codesandbox, and GitHub. Make sure the URL you provided is correct and reachable. You can test it by visiting it in a private tab, another device, etc. Please edit your original post above and provide a valid reproduction URL as explained.

Without a proper reproduction, your issue will have to get closed.

Thank you for your collaboration. 👏