How to open a static website in localhost but generated with Vite and without running a server?
Asked Answered
A

2

14

Note: the example I'm using is available on GitHub repository https://github.com/mary-perret-1986/primevue-poc

I created a simple project with Vue.js 3 + Vite + PrimeVue.

So far everything works like a charm when I'm developping and if I'm serving the build (i.e. /dist) with a server.

But I wanted to see if I could open the /dist/index.html directly from my browser... I mean it should be possible, technically-speaking.

Here are below the bits of configuration:

package.json

{
  "name": "my-vue-app",
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite build && vite preview"
  },
  "dependencies": {
    "primeflex": "^2.0.0",
    "primeicons": "^4.1.0",
    "primevue": "^3.2.0-rc.1",
    "vue": "^3.0.5",
    "vue-property-decorator": "^9.1.2",
    "vue-class-component": "^8.0.0-0",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0"
  },
  "devDependencies": {
    "@types/node": "^14.14.37",
    "@vitejs/plugin-vue": "^1.2.1",
    "@vue/compiler-sfc": "^3.0.5",
    "sass": "^1.26.5",
    "typescript": "^4.1.3",
    "vite": "^2.1.5",
    "vue-tsc": "^0.0.15"
  }
}

vite.config.ts:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  server: {
    open: true,
  },
  build: {},
  resolve: {
    alias: [
      { find: '@', replacement: '/src' },
      { find: 'views', replacement: '/src/views' },
      { find: 'components', replacement: '/src/components' },
    ]
  },
  define: {
    'process.env': process.env
  }
})

Install packages work fine:

$ yarn
yarn install v1.22.10
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix 
package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.17s.

Developping as well:

$ yarn dev
yarn run v1.22.10
$ vite
Pre-bundling dependencies:
  vue
  primevue/config
  vuex
  vue-router
  vue-class-component
  (...and 1 more)
(this will be run only when your dependencies or config have changed)

  vite v2.1.5 dev server running at:

  > Network:  http://192.168.0.10:3000/
  > Local:    http://localhost:3000/   
  > Network:  http://172.17.128.1:3000/

  ready in 632ms.

Checking with the preview server the build, works as well:

$ yarn preview
yarn run v1.22.10
$ vite build && vite preview
vite v2.1.5 building for production...
✓ 34 modules transformed.
dist/assets/logo.03d6d6da.png                                   6.69kb
dist/assets/primeicons.7362b83d.eot                             56.21kb
dist/assets/color.473bc8ca.png                                  10.11kb
dist/assets/roboto-v20-latin-ext_latin-regular.b86b128b.woff2   22.11kb
dist/assets/roboto-v20-latin-ext_latin-500.fa074f87.woff2       22.20kb
dist/assets/roboto-v20-latin-ext_latin-700.8d9364a0.woff2       22.19kb
dist/assets/roboto-v20-latin-ext_latin-regular.e70a908b.woff    28.36kb
dist/assets/primeicons.c1e93246.ttf                             56.04kb
dist/assets/roboto-v20-latin-ext_latin-500.d092ad8e.woff        28.39kb
dist/assets/roboto-v20-latin-ext_latin-700.e24c2752.woff        28.41kb
dist/assets/primeicons.3929b551.woff                            56.11kb
dist/assets/primeicons.8f9d2aaf.svg                             229.14kb
dist/index.html                                                 0.47kb
dist/assets/About.17af8924.js                                   0.19kb / brotli: 0.14kb
dist/assets/index.e5d45779.js                                   3.63kb / brotli: 1.52kb
dist/assets/vendor.9f2b5e0c.js                                  90.90kb / brotli: 29.73kb
dist/assets/index.6f411dd0.css                                  226.74kb / brotli: 20.14kb

  vite v2.1.5 build preview server running at:

  > Network:  http://192.168.0.10:5000/
  > Local:    http://localhost:5000/
  > Network:  http://172.17.128.1:5000/

The issue arises when I'm willing to open my build without a server, which by all accounts should be doable, except that when I'm opening the /dist/index.html, the console is shouting at me:

index.html:1 Access to script at 'file:///C:/assets/vendor.9f2b5e0c.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, edge, https, chrome-untrusted.
index.html:9 GET file:///C:/assets/vendor.9f2b5e0c.js net::ERR_FAILED
index.html:1 Access to script at 'file:///C:/assets/index.6aa5dbbe.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, edge, https, chrome-untrusted.
index.html:8 GET file:///C:/assets/index.6aa5dbbe.js net::ERR_FAILED
index.html:10 GET file:///C:/assets/index.96fff16b.css net::ERR_FILE_NOT_FOUND
/C:/favicon.ico:1 GET file:///C:/favicon.ico net::ERR_FILE_NOT_FOUND

Looking at the context of the newly built /dist/index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  <script type="module" crossorigin src="/assets/index.7ed2b14a.js"></script>
  <link rel="modulepreload" href="/assets/vendor.9f2b5e0c.js">
<link rel="stylesheet" href="/assets/style.5b5d95b2.css">
</head>
  <body>
    <div id="app"></div>
    
  </body>
</html>

I've checked this part of the Vite documentation https://vitejs.dev/guide/static-deploy.html, but still can't manage to have a real old-fashioned build that doesn't require a server.

Any idea?

Ahron answered 10/4, 2021 at 6:3 Comment(6)
Read books about HTTP. You need some server. You could code one with some HTTP server library like libonionEmbay
@BasileStarynkevitch based on what premise? Didn't need one with angular, why would that be the case with a simple static output?Ahron
@BasileStarynkevitch I managed to make it work, fyi, my solution is below.Ahron
Similar questions for self contained embeddings in the 'ghost' CMSBahaism
@Bahaism at the time of writing this comment, my question was asked 2 years and 1 month ago, the question you're mentioning was asked 12 months. It seems I have somehow some sort of precedence over it and not the other way around (if that's what you were implying).Ahron
@NataliePerret No offense, I mentioned them to link this canonical post. :-)Bahaism
A
12

Alright so I managed to make it work (repository has been updated accordingly).

All I needed was to actually inline the css and js, in order to achieve that I leveraged this bit here: https://www.npmjs.com/package/vite-plugin-singlefile.

I created another config dedicated to the inlined stuffery:

vite.config.inlined.ts:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { viteSingleFile } from "vite-plugin-singlefile"

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), viteSingleFile()],
    build: {
        cssCodeSplit: false,
        assetsInlineLimit: 100000000,
        rollupOptions: {
            output: {
                manualChunks: () => "everything.js",
            },
        },
    },
  resolve: {
    alias: [
      { find: '@', replacement: '/src' },
      { find: 'views', replacement: '/src/views' },
      { find: 'components', replacement: '/src/components' },
    ]
  },
  server: {
    open: true,
  },
  define: {
    'process.env': process.env
  }
})

and updated my package.json accordingly:

{
  "name": "my-vue-app",
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite build && vite preview",
    "inlined-build": "vite build --config vite.config.inlined.ts",
    "inlined-preview": "vite build --config vite.config.inlined.ts && start ./dist/index.html"
  },
  "dependencies": {
    "primeflex": "^2.0.0",
    "primeicons": "^4.1.0",
    "primevue": "^3.2.0-rc.1",
    "vue": "^3.0.5",
    "vue-class-component": "^8.0.0-0",
    "vue-property-decorator": "^9.1.2",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0"
  },
  "devDependencies": {
    "@types/node": "^14.14.37",
    "@vitejs/plugin-vue": "^1.2.1",
    "@vue/compiler-sfc": "^3.0.5",
    "sass": "^1.26.5",
    "typescript": "^4.1.3",
    "vite": "^2.1.5",
    "vite-plugin-singlefile": "^0.5.1",
    "vue-tsc": "^0.0.15"
  }
}

and "voila":

$ yarn inlined-preview
yarn run v1.22.10
$ vite build --config vite.config.inlined.ts && start ./dist/index.html
vite v2.1.5 building for production...
✓ 34 modules transformed.
dist/assets/primeicons.8f9d2aaf.svg   229.14kb
dist/index.html                       845.29kb
dist/assets/style.d35cde0e.css        741.65kb / brotli: skipped (large chunk)
dist/assets/index.dbc56441.js         103.16kb / brotli: 37.49kb
Done in 6.63s.

Note: I'm actually pleasantly surprised so far, assets like pics and icons still working just fine.

Ahron answered 10/4, 2021 at 6:53 Comment(0)
B
1

To do this with vite on-board tools set

base: "./"

in your vite config or build with

 vite build --base="./"

base

Type: string Default: /

Base public path when served in development or production. Valid values include:

  • Absolute URL pathname, e.g. /example/

  • Full URL, e.g. https://example.com/

  • Empty string or ./ (for embedded deployment)

Public Base Path​

If you are deploying your project under a nested public path, simply specify the base config option and all asset paths will be rewritten accordingly. This option can also be specified as a command line flag, e.g. vite build --base=/my/public/path/.

JS-imported asset URLs, CSS url() references, and asset references in your .html files are all automatically adjusted to respect this option during build.

The exception is when you need to dynamically concatenate URLs on the fly. In this case, you can use the globally injected import.meta.env.BASE_URL variable which will be the public base path. Note this variable is statically replaced during build so it must appear exactly as-is (i.e. import.meta.env['BASE_URL'] won't work).

Related: Asset Handling

Bahaism answered 30/5, 2023 at 5:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.