GithubHelp home page GithubHelp logo

nonzzz / vite-plugin-cdn Goto Github PK

View Code? Open in Web Editor NEW
72.0 72.0 5.0 3.04 MB

replace module with CDN. work with vite.

License: MIT License

JavaScript 1.68% TypeScript 96.55% HTML 1.10% Vue 0.67%
vite-plugin vite-plugin-cdn

vite-plugin-cdn's Introduction

Hi there 👋

  • You can call me Kanno
  • I've been busy recently
  • Learning zig

vite-plugin-cdn's People

Contributors

mengdaoshizhongxinyang avatar nonzzz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

vite-plugin-cdn's Issues

Maximum call stack size exceeded

我在vue2中使用出错了,因为这是旧项目 我不好使用vue3
配置 cdn({
modules: [
{ name: 'axios', relativeModule: './axios.min.js' },
{ name: 'element-ui', relativeModule: './element-ui.min.js', aliases: ['client'] },
],
resolve: {
name: 'resolve:cdnjs',
setup({ extra }) {
const baseURL = 'https://cdnjs.cloudflare.com/ajax/libs/';
const { version, name, relativeModule } = extra;
console.log(relativeModule);
const url = new URL(${name}/${version}/${relativeModule}, baseURL);
console.log(url);
return {
url: url.href,
injectTo: 'head-prepend',
attrs: {},
};
},
},
}),
报错信息:
vite-plugin-cdn2: axios Maximum call stack size exceeded
vite-plugin-cdn2: element-ui Maximum call stack size exceeded

package.json:
"dependencies": {
"@tinymce/tinymce-vue": "2.0.0",
"axios": "0.18.1",
"element-china-area-data": "5.0.2",
"element-ui": "2.15.12",
"js-md5": "0.7.3",
"lodash": "4.17.21",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"path-browserify": "1.0.1",
"path-to-regexp": "2.4.0",
"rollup-plugin-external-globals": "0.9.1",
"sortablejs": "1.13.0",
"tinymce": "^5.0.3",
"vue": "2.6.10",
"vue-cropper": "0.6.4",
"vue-dompurify-html": "2.6.0",
"vue-router": "3.0.6",
"vuedraggable": "2.24.3",
"vuex": "3.1.0",
"vuex-persistedstate": "^4.1.0"
},
"devDependencies": {
"rollup-plugin-visualizer": "5.12.0",
"sass": "1.26.8",
"unplugin-imagemin": "0.5.15",
"vite": "4.3.9",
"vite-plugin-cdn2": "1.1.0",
"vite-plugin-compression2": "0.11.0",
"vite-plugin-html": "3.2.0",
"vite-plugin-image-optimizer": "1.1.7",
"vite-plugin-theme": "0.8.6",
"vite-plugin-vue2": "2.0.3",
"vite-plugin-vue2-svg": "0.4.0",
"vue-template-compiler": "2.6.10"
},

bug: 处理 vue-demi 时构建出错

项目没有直接安装 vue-demi,项目基础框架是 vue + vue-router + pinia

[vite-plugin-cdn] Property name expected type of string but got undefined
file: D:/My Projects/MBDownload/frontend/node_modules/.pnpm/[email protected][email protected]/node_modules/vue-demi/lib/index.mjs
error during build:
TypeError: Property name expected type of string but got undefined
    at validate (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\types\lib\definitions\utils.js:134:13)
    at Object.validate (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\types\lib\definitions\utils.js:188:7)
    at validateField (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\types\lib\validators\validate.js:21:9)
    at validate (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\types\lib\validators\validate.js:15:3)
    at validateNode (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\types\lib\builders\validateNode.js:12:27)
    at Object.identifier (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\types\lib\builders\generated\index.js:411:36)
    at scanNamedExportsWithoutSource (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\v[email protected]\node_modules\vite-plugin-cdn2\dist\chunk-WFIYNUVD.js:89:102)
    at CodeGen.overWriteExportNamedDeclaration (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\v[email protected]\node_modules\vite-plugin-cdn2\dist\chunk-WFIYNUVD.js:104:11)
    at enter (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\v[email protected]\node_modules\vite-plugin-cdn2\dist\chunk-WFIYNUVD.js:223:22)
    at NodePath._call (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\path\context.js:46:20)
    at NodePath.call (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\path\context.js:36:17)
    at NodePath.visit (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\path\context.js:82:31)
    at TraversalContext.visitQueue (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\context.js:86:16)
    at TraversalContext.visitMultiple (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\context.js:61:17)
    at TraversalContext.visit (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\context.js:107:19)
    at traverseNode (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\traverse-node.js:18:17)
    at NodePath.visit (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\path\context.js:88:52)
    at TraversalContext.visitQueue (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\context.js:86:16)
    at TraversalContext.visitSingle (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\context.js:65:19)
    at TraversalContext.visit (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\context.js:109:19)
    at traverseNode (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\traverse-node.js:18:17)
    at traverse (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\@[email protected]\node_modules\@babel\traverse\lib\index.js:49:34)
    at CodeGen.transform (D:\My Projects\MBDownload\frontend\node_modules\.pnpm\v[email protected]\node_modules\vite-plugin-cdn2\dist\chunk-WFIYNUVD.js:198:20)
 ELIFECYCLE  Command failed with exit code 1.

能否提供一下自定义CDN设置的示例?

以下设置 期待实现 CDN 对应的 url:

https://cdn-abc.com/[email protected]
"devDependencies": {
    "vite-plugin-cdn2": "^1.1.0",
}

cdn.js

import { cdn } from "vite-plugin-cdn2";
// import { cdnjs } from "vite-plugin-cdn2/resolver/cdnjs";
import { defineResolve } from "vite-plugin-cdn2/resolve";

// 方法一: 怎么引入需要 cdn 处理的依赖?
export const myResolve = defineResolve({
  name: "resolve:custom",
  setup({ extra }) {
    const baseURL = "https://cdn-abc.com/";
    const { version, name, relativeModule } = extra;
    const url = new URL(`${name}/${version}/${relativeModule}`, baseURL);
    console.log(url);
    return {
      url: url.href,
      injectTo: "head-prepend",
      attrs: {}
    };
  }
});

方法二: 
export function enableCDN(isEnabled) {
  console.log("enableCDN", isEnabled);
  if (isEnabled === "true") {
    return cdn({
      // url 可以更换为私有或其他源
      // url: "https://cdn.jsdelivr.net/npm/",
      // url: "https://unpkg.com/",
      url: "https://cdn-abc.com",
      // modules: ["vue", "vue-demi", "pinia", "axios", "vant", "vue-router"]
      modules: [
        {
          name: "vue",
          relativeModule: "./vue.global.js"
        }
      ]
    });
  }
}

debug模式

pnpm build
> set DEBUG=vite-plugin-cdn2 & vite build

enableCDN true                                                                                15:35:03
  vite-plugin-cdn2 start scanning +0ms
  vite-plugin-cdn2 scanning done Map(0) {} +969ms

 ERROR  vite-plugin-cdn2: vue Maximum call stack size exceeded                                15:35:04

vite v4.5.0 building for production...                                                        15:35:04
✓ 391 modules transformed.                                                                    15:35:08
rendering chunks (3)...  vite-plugin-cdn2 start transformIndexHtml +14s
  vite-plugin-cdn2 transformIndexHtml Done [] +2ms
rendering chunks (3)...  vite-plugin-cdn2 start transformIndexHtml +4s
  vite-plugin-cdn2 transformIndexHtml Done [] +0ms
✓ built in 17.54s                                                                             15:35:21
                                                          

demo
https://github.com/yulimchen/vue3-h5-template

Used but not effective

image
image
Uploading image.png…

According to the document, I used it and confirmed that the package was installed successfully, but the packaging result was not as expected (I added the cdn link for me)
按照文档使用了,并也确认包安装成功,但是打包结果并不是预期那样(帮我加入了cdn链接)

Package subpath './es/components/button/style/css' is not defined by "exports" in D:\cdn\node_modules\element-plus\package.json

自己封装组件库,引用了element-plus,用的unplugin-element-plus自动导入样式,代码编译后,里面有相关代码

import { ElButton } from 'element-plus'
import 'element-plus/es/components/button/style/css'

图片

cdn插件modules加入自己组件,就会报错。

跟踪代码发现是 _import 执行的时候报的这个错误。
重现步骤:
创建一个vite项目,新建 test.cjs 文件,内容如下:

var elementPlus = require('element-plus');
require('element-plus/es/components/button/style/css');
exports.ElButton = elementPlus.ElButton

vite.config.ts 文件里面添加以下代码:

import url from "url";
const modulePath = url.pathToFileURL(
  "D:\\cdn\\test.cjs"
);
const _import = new Function("specifier", "return import(specifier)");
const pkg  = await _import(modulePath);

运行就会报错:Package subpath './es/components/button/style/css' is not defined by "exports"...

图片

删除 require('element-plus/es/components/button/style/css')就正常了。

axios问题

升级0.12.3版本后错误,0.12.2没有问题
image

lodash问题

不使用cdn打包后为

// 导入
const i = e=>(Vue.pushScopeId("data-v-d0fc7832"),
e = e(),
Vue.popScopeId(),
e)
// 使用
const i = Vue.ref();
        e.forEach(["1", "2", "3"], ((e,t)=>{
            i.value = e
        }
        ));

使用cdn后

// 配置
cdn({
    modules: [
      { name: 'lodash', relativeModule: 'lodash.js' }
    ]
  })
// 导入 (正常)
const u = e=>(Vue.pushScopeId("data-v-132f7d04"),
e = e(),
Vue.popScopeId(),
e)
// 使用 (不正常)
__wrapped__.forEach(["1", "2", "3"], ((e,t)=>{}
        ));

会不会是其他插件问题?cdn插件我已放在最后面

引入报错

index-bae519ee.js:1 Uncaught TypeError: Cannot read properties of undefined (reading 'BaseTransition')
at index-bae519ee.js:1:1435305
image

希望增加备用方案

由于cdn可能存在访问失败的问题。

希望增加备用方案。
通过属性配置是否开启 开启后不会排除使用了cdn的资源
并且 如果cdn超时未加载成功。还是使用项目资源进行加载

不知道方案是否可行

[求助]尝试ECharts的CDN导入

配合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/[email protected]/dist/index.css',
              'https://unpkg.com/[email protected]/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,但是图表却正常的渲染了,奇怪了~

[求助]element-plus的CSS如何CDN加载?

感谢作者的无私付出,有两个小疑问。

[1] 我想在项目中,让element-plus的css能够像在https://www.npmjs.com/package/vite-plugin-cdn-import 这个库中一样cdn加载,如何实现?

[2] 这个库 https://github.com/posva/unplugin-vue-router ,不知道作者清楚不?文件自动路由,但是配合当前vite-plugin-cdn2,即使设置了'vue-router' cdn加载,依旧在打包之后,会把vue-router打包进项目。

@nonzzz

Feat: support auto add esm importmap

Now many packages is only support esm cdn, the package should support what auto add importmap when scan external.

<script type="importmap">
  {
    "imports": {
      "shiki": "https://cdn.jsdelivr.net/npm/shiki@~1.2.0/+esm"
    }
  }
</script>

highlight.js 编译失败

首先感谢作者的无私奉献。

请教一下关于如何加载 highlight.js

      modules: [
        'vue',
        'highlight.js',
      ...

错误日志:

vite-plugin-cdn2: highlight.js try resolve file failed.

使用vite-plugin-cdn2 v0.15.4构建echarts提示失败

问题描述

在 vite5.1.5 中使用 vite-plugin-cdn2 v0.15.4 构建 echarts 提示:echarts try resolve file failed。

但是,其他的包都正常构建。

image

环境

macOS:14.3.1 (23D60)
cpu:m3 max
vite:5.1.5

配置截图

image

resolve 方法,是一个将 cdnjs 资源地址拼接完整的方法,不过,当我手动补全的时候,也是无效的。

vite-plugin-cdn2: xxx try resolve file failed.

demo
https://github.com/yulimchen/vue3-h5-template

package.json

"dependencies": {
    "axios": "^1.6.2",
    "normalize.css": "^8.0.1",
    "nprogress": "^0.2.0",
    "pinia": "^2.1.7",
    "vant": "^4.7.3",
    "vconsole": "^3.15.1",
    "vue": "^3.3.4",
    "vue-router": "^4.2.5"
  },
"devDependencies": {
    "vite-plugin-cdn2": "^1.1.0",
  }

cdn.js

export function enableCDN(isEnabled) {
  console.log("enableCDN", isEnabled);
  if (isEnabled === "true" || isEnabled === true) {
    console.log("enableCDN", isEnabled);
    return cdn({
      modules: [
        {
          name: "axios",
          aliasName: "axios.min.js"
        },
        "normalize.css",
        // {
        //   name: "normalize.css",
        //   spare: ["https://unpkg.com/[email protected]/normalize.css"]
        // },
        "nprogress",
        {
          name: "vue",
          aliasName: "vue.global.js"
        },
        "vue-demi",
        {
          name: "vue-router",
          aliasName: "vue-router.global.js"
        },
        {
          name: "pinia",
          aliasName: "pinia.iife.js"
        },
        {
          name: "vant",
          aliasName: "vant.min.js"
        },
        // {
        //   name: "vconsole",
        //   aliasName: "vconsole.min.js"
        // }
        "vconsole"
      ],
      resolve: {
        name: "resolve:custom",
        setup({ extra }) {
          const { name, aliasName, relativeModule, version } = extra;
          let url = "";
          if (name && aliasName) {
            const baseURL = "https://cdn-anc.com";
            url = new URL(`${aliasName}`, baseURL);
          } else {
            const baseURL = "https://unpkg.com/";
            url = new URL(`${name}/${version}/${relativeModule}`, baseURL);
          }
          console.log("url", url);
          return {
            url: url.href,
            injectTo: "head-prepend",
            attrs: {}
          };
        }
      }
    });
  }
}

 ERROR  vite-plugin-cdn2: normalize.css try resolve file failed.                                10:59:12
 ERROR  vite-plugin-cdn2: nprogress try resolve file failed.                                    10:59:12
 ERROR  vite-plugin-cdn2: vconsole try resolve file failed. 

image

使用unpkg.com错误

cdn({
url: 'https://unpkg.com',
modules: ['vue', 'vue-demi', 'vue-router'],
resolve: (base, { name, version }) => {
return ${base}/${name}@${version}
}
})

打包后为下面所示,是link 标签而不是script标签

<link href="https://unpkg.com/vuexxx...
<link href="https://unpkg.com/vue-demixxx...
<link href="https://unpkg.com/vue-routerxxx...

看源码是判断了下面的返回值后缀是否带.js,只有带了才是script. 但是我不想去带上.js
resolve: (base, { name, version }) => {
return ${base}/${name}@${version}
}

vite-plugin-cdn2: vue Maximum call stack size exceeded

cdn({
	modules: [{ name: "vue", relativeModule: "vue.global.prod.min.js" }, "vue-router", "vue-demi", "pinia", "axios" ],
	resolve: defineResolve({
		name: "resolve:custom",
		setup({ extra }) {
			const baseURL = "https://cdn.staticfile.net/";
			const { version, name, relativeModule } = extra;
			const url = new URL(`${name}/${version}/${relativeModule}`, baseURL);
			return {
				url: url.href,
				injectTo: "head-prepend",
				attrs: {
					crossOrigin: 'anonymous'
				},
			};
		},
	})
})

And there is no vue in output:

<script crossOrigin="anonymous" src="https://cdn.staticfile.net/vue-router/4.2.0/dist/vue-router.global.js"></script>
<script crossOrigin="anonymous" src="https://cdn.staticfile.net/vue-demi/0.14.6/lib/index.iife.js"></script>
<script crossOrigin="anonymous" src="https://cdn.staticfile.net/pinia/2.1.7/dist/pinia.iife.js"></script>
<script crossOrigin="anonymous" src="https://cdn.staticfile.net/axios/1.5.0/dist/axios.min.js"></script>

Maximum call stack size exceeded

配置: cdn({
modules: [
{ name: 'axios', relativeModule: './axios.min.js' },
{ name: 'element-ui', relativeModule: './element-ui.min.js', aliases: ['client'] },
],
resolve: {
name: 'resolve:cdnjs',
setup({ extra }) {
const baseURL = 'https://cdnjs.cloudflare.com/ajax/libs/';
const { version, name, relativeModule } = extra;
console.log(relativeModule);
const url = new URL(${name}/${version}/${relativeModule}, baseURL);
console.log(url);
return {
url: url.href,
injectTo: 'head-prepend',
attrs: {},
};
},
},
}),

ERROR vite-plugin-cdn2: axios Maximum call stack size exceeded
ERROR vite-plugin-cdn2: element-ui Maximum call stack size exceeded
我在vue2的版本上使用然后报错了 是我的配置不对吗

cdnjs.com 引入错误

  cdn({
                modules: ["react","axios"],
                url: "https://cdnjs.cloudflare.com/ajax/libs/",
 }),
// 404

能自定义 URL 吗?

就像:

import VitePluginCdn from 'vite-plugin-cdn';

export default {
  plugins: [
    VitePluginCdn({
      esm: true,
      modules: [
        {
          name: 'vue',
          url: 'https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.esm-browser.prod.js',
        },
      ],
    }),
  ],
};

比如 URL 参数我提供个 https://cdn.bootcdn.net/ajax/libs/vue/{{ version }}/vue.esm-browser.prod.js,然后插件会自动解析 {{ version }} 并改为本地 node_modules 里安装的版本。

1.0.0和1.1.0版本引入时ts报错

感谢您的无私奉献
当我尝试使用1.1.0和1.0.0时我的ts类型报错Cannot find module 'vite-plugin-cdn2' or its corresponding type declarations.
image
降级到0.16.0后报错消失

我使用vite-plugin-cdn2/index 的引入方式ts类型报错消失
image
但是vite报错Cannot find module 'xxx/node_modules/vite-plugin-cdn2/index'
image

希望优先使用用户自定义配置

在获取x的时候 x = b || p || i; i在前面优先使用用户配置的relativeModule

  let { name: s, relativeModule: i, aliases: a, ...n } = r;
  try {
    let o = W.resolve(s), c = k(o, "package.json"), u = await F.readFile(c, "utf8"), f = JSON.parse(u), {
      version: d,
      name: l,
      unpkg: p,
      jsdelivr: b
    } = f, g = Object.create(null), x = b || p || i;
    if (!x) throw new Error("try resolve file failed.");
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.