vitejs / vite

Next generation frontend tooling. It's fast!
http://vite.dev
MIT License
68.66k stars 6.2k forks source link

Vite dynamic import is not available on android5/chrome 39 #7266

Closed wzz0720 closed 2 years ago

wzz0720 commented 2 years ago

Describe the bug

router/index.js

import Vue from 'vue'
import Router from 'vue-router'

import IndexPage from '@/views/Index/index.vue'

const ListPage = () => import('@/views/List/index.vue')

Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: '/',
      redirect: 'index',
      component: IndexPage,
      children: [
        {
          path: 'index',
          component: IndexPage,
          name: 'Index',
          meta: {
            title: 'index'
          }
        }
      ]
    },
    {
      path: '/list',
      name: 'List',
      component: ListPage,
      meta: {
        title: 'list'
      }
    }
  ]
})

router.afterEach(function (transition) {
  document.title = transition.meta.title || transition.meta.name || ''
})

export default router

vite.config.js

import path from 'path'
import { defineConfig } from 'vite'
import legacy from '@vitejs/plugin-legacy'
import { injectHtml, minifyHtml } from 'vite-plugin-html'
import externalGlobals from 'rollup-plugin-external-globals'
import ip from 'ip'
const { createVuePlugin } = require('vite-plugin-vue2')

export default ({ mode }) => {
  return defineConfig({
    base: './',
    server: {
      host: '0.0.0.0',
      port: 8080
    },
    plugins: [
      createVuePlugin(),
      injectHtml(),
      legacy({
        targets: ['Android >= 4.4', 'iOS >= 9', 'ie >= 11', 'Chrome>=30'],
        additionalLegacyPolyfills: ['regenerator-runtime/runtime.js']
      })
    ],
    build: {
      rollupOptions: {
        external: ['vue', 'axios', 'vuex', 'vue-router'],
        plugins: [
          externalGlobals({
            vue: 'Vue',
            axios: 'axios',
            'vue-router': 'VueRouter',
            vuex: 'Vuex'
          })
        ]
      }
    }
  })
}

when I use vite dynamic import component,the component dont show on chrome39,I added the compatibility setting in vite.config.js,when I visit the page ,the component legacy js is loaded ,but show nothing, and no error infomation.

render in android5/chrome 39

截屏2022-03-11 下午3 14 43

Reproduction

https://stackblitz.com/edit/vitejs-vite-rxhpjr?file=views/Index/index.vue

System Info

System:
    OS: macOS 12.0.1
    CPU: (4) x64 Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
    Memory: 429.48 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.13.0 - ~/.nvm/versions/node/v12.13.0/bin/node
    npm: 6.12.0 - ~/.nvm/versions/node/v12.13.0/bin/npm
  npmPackages:
    @vitejs/plugin-legacy: ^1.7.1 => 1.7.1 
    vite: ^2.8.6 => 2.8.6

Used Package Manager

npm

Logs

No response

Validations

webaddkevin commented 2 years ago

I also have this problem, could you please help me find some solution?

felran commented 2 years ago

@webaddkevin i also have this problem ,but when i didn't use the cdn module and remove the vite external configs, it works fine. and i also debug the project,dynamic import modules does'nt have the renderer callback function, it render nothing on chrome39. this problem might be the vite-plugin-legacy

sapphi-red commented 2 years ago

The reproduction app was broken (error: Uncaught ReferenceError: store is not defined).

After applying the following changes, I was able to fix it.

// 1. install vuex@3
// -----
// 2. change main.js
import Vue from 'vue';
import App from './App.vue';
import { sync } from 'vuex-router-sync';
import router from './router';
import store from './store';

sync(store, router);
new Vue({
  store,
  router,
  render: (h) => h(App),
}).$mount('#app');

// -----
// 3. add store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({});

But it was not able to reproduce with windows 10 + chrome 39. Is this an android specific problem? Please provide a reproduction which is not broken.

wzz0720 commented 2 years ago

The reproduction app was broken (error: Uncaught ReferenceError: store is not defined).

After applying the following changes, I was able to fix it.

// 1. install vuex@3
// -----
// 2. change main.js
import Vue from 'vue';
import App from './App.vue';
import { sync } from 'vuex-router-sync';
import router from './router';
import store from './store';

sync(store, router);
new Vue({
  store,
  router,
  render: (h) => h(App),
}).$mount('#app');

// -----
// 3. add store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({});

But it was not able to reproduce with windows 10 + chrome 39. Is this an android specific problem? Please provide a reproduction which is not broken.

yes,the problem happend on android5 webview ,the version is chrome 39.And I found that without using CDN there is no problem,only after using CDN and using externalGlobals

sapphi-red commented 2 years ago

Could you paste the config file here? I feel that CDN does not support chrome 39.

wzz0720 commented 2 years ago

Could you paste the config file here? I feel that CDN does not support chrome 39.

vite.config.js

import path from 'path'
import { defineConfig } from 'vite'
import legacy from '@vitejs/plugin-legacy'
import { injectHtml, minifyHtml } from 'vite-plugin-html'
import externalGlobals from 'rollup-plugin-external-globals'
import ip from 'ip'
const { createVuePlugin } = require('vite-plugin-vue2')

export default ({ mode }) => {
  return defineConfig({
    base: './',
    server: {
      host: '0.0.0.0',
      port: 8080
    },
    plugins: [
      createVuePlugin(),
      injectHtml(),
      legacy({
        targets: ['Android >= 4.4', 'iOS >= 9', 'ie >= 11', 'Chrome>=30'],
        additionalLegacyPolyfills: ['regenerator-runtime/runtime.js']
      })
    ],
    build: {
      rollupOptions: {
        external: ['vue', 'vuex', 'vue-router'],
        plugins: [
          externalGlobals({
            vue: 'Vue',
            'vue-router': 'VueRouter',
            vuex: 'Vuex'
          })
        ]
      }
    }
  })
}

index.html

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuex@3.6.2/dist/vuex.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.2/dist/vue-router.min.js"></script>

when I remove the vue-router.min.js cdn in index.html and the vue-router from the externalGlobals configuration, there is no problem

sapphi-red commented 2 years ago

It was because when you use CDN, you don't get Symbol.toStringTag polyfilled which leads this line not to be executed. https://github.com/vuejs/vue-router/blob/9a3c7ec00d7761d75038042de31258a08a1744bd/src/util/resolve-components.js#L24-L26

Closing as this is not a bug.