nonzzz / vite-plugin-cdn

replace module with CDN. work with vite.
MIT License
73 stars 5 forks source link

[求助]尝试ECharts的CDN导入 #32

Closed toimc closed 7 months ago

toimc commented 7 months ago

配合vue-charts第三方插件,结合typescript按需引入,最终目标是cdn加载echarts,动态加载charts中的components及charts类型,参考代码。

项目配置:

cdn({
        modules: [
          'vue',
          'vue-demi',
          'pinia',
          'vue-router',
          {
            name: 'element-plus',
            aliases: ['lib', 'es'],
            spare: [
              'https://unpkg.com/element-plus@2.4.2/dist/index.css',
              'https://unpkg.com/element-plus@2.4.2/theme-chalk/dark/css-vars.css'
            ]
          },
          {
            name: 'echarts',
            aliases: ['core', 'renderers', 'components', 'features', 'charts']  // 这一行是出问题的部分
          }
        ]
      })

ECharts的项目中的引用:

import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import * as Charts from 'echarts/charts'
import * as ChartsComponents from 'echarts/components'
import * as ChartsFeatures from 'echarts/features'
import VChart from 'vue-echarts'

最小示例项目:

https://github.com/toimc/vite-vue-cdn-demo

错误问题:

image

尝试排查问题: 打开sourceMap,定位到是use方法出现问题,发现...Array.from(new Set(deps)).map((o) => ChartsComponents[o]),这个部分是空,全是undefined,开发模式是正常的,说明在线上的时候,

echarts/components应该是没有正常的被加载,所以对应的方法是空的,如何解决?

======= PS:即使上面的代码出现了Bug,但是图表却正常的渲染了,奇怪了~

toimc commented 7 months ago

离了个大谱,我看了一下源码:我直接把onBeforeMounted的所有代码注释掉,表格正常注册,全局导入了echarts之后,可以这么玩。https://github.com/ecomfe/vue-echarts/blob/a2f8f0010aa1717e2c1f620cbcf6b353740e81ef/src/ECharts.ts#L205C9-L205C13

这里使用了echarts的init方法,该方法是核心库导出的,所以只用传option就可以了,不知道对后续的使用有没有影响。

nonzzz commented 7 months ago

首先aliases并不是万能的逃生舱。vite社区偏爱esm。插件的作用是尽可能的把一个可能的模块转成iife或者umd导入。而我不确定echarts他在esm上的具体表现如何。比如你使用React在18还是17以后会有个jsx/runtime但是它不属于umd的那部分因此就不需要设置aliases.我觉得你可以在本地安装vite-plugin-inspect进行排查。通常来说我以我司项目为例我们大量使用了echarts因此按需还是全量并无差别。所以 import * as echarts from 'ecahrts'能被很好的处理。

nonzzz commented 7 months ago

这个插件的设计初衷不是为了把所有模块都换成iife或者umd。因为一些足够小的包并不需要使用外部化的方式去解决。而是把一些占比大头比如可视化渲染,UI。以及更多复杂的东西提出去。一切都外部化反而会适得其反。

toimc commented 7 months ago

首先aliases并不是万能的逃生舱。vite社区偏爱esm。插件的作用是尽可能的把一个可能的模块转成iife或者umd导入。而我不确定echarts他在esm上的具体表现如何。比如你使用React在18还是17以后会有个jsx/runtime但是它不属于umd的那部分因此就不需要设置aliases.我觉得你可以在本地安装vite-plugin-inspect进行排查。通常来说我以我司项目为例我们大量使用了echarts因此按需还是全量并无差别。所以 import * as echarts from 'ecahrts'能被很好的处理。

明白了,这个插件可以设置script标签的扩展属性吗?比如defer或者async?还有如何调整link,script的位置?

nonzzz commented 7 months ago

可以设置。在transform这个钩子里面。比如你是script你只需要实现一个script的方法。然后 通过script你可以拿到对应name的url。然后填充你想要的属性进去即可

toimc commented 7 months ago

已经解决了,非常感谢~~

transform: () => {
          return {
            script: (scriptNode) => {
              const { tag, name } = scriptNode
              if (tag === 'script' && ['xxxx'].includes(name)) {
                 // 设置扩展的script属性
                 scrIptNode.defer = true
              }
            }
          }
        }

送给有缘人