部分依赖在油猴的环境中直接简单地用 @require 引入会产生冲突
bzy-nya opened this issue · 19 comments
例如
// @require https://unpkg.com/vue@3.2.37//dist/vue.global.prod.js
// @require https://unpkg.com/element-plus@2.2.9//dist/index.full.js // element-plus 依赖 vue
vue.js 会导出一个变量 Vue
,element 会寻找 this.Vue
当成依赖,但是在油猴的环境中 this 被重定向到了 window 的一个 proxy(@grant none
就会指向空对象),所以就会发生报错说 vue is not found
,即使 vue 变量已经在环境中了。
所以能不能提供一个自定义依赖引入的方法呢?
如何提供 自定义依赖引入
?
动态添加 script 吗?把 cdn 添加到宿主环境会污染 宿主window 属性,如果宿主使用了 cdn ,两个不同版本的 cdn 导出了同样的变量,宿主的 cdn 会被覆盖,或者其他的方法?
如何提供
自定义依赖引入
? 动态添加 script 吗?把 cdn 添加到宿主环境会污染 宿主window 属性,如果宿主使用了 cdn ,两个不同版本的 cdn 导出了同样的变量,宿主的 cdn 会被覆盖,或者其他的方法?
用 get + eval 或者 remote import ?
react-dom 依赖 react,但是它在油猴扩展内正常加载
虽然没有处理好还是会报错,但是在函数之前加上 var process = {env:{NODE_ENV:'production'}};
之后它就能正常运行
react-dom 依赖 react,但是它在油猴扩展内正常加载
因为 vue.js 是直接
var Vue = {
...
}
但是 react.js 里是
factory(global.React = {}) // global = this || self
然后这样的话油猴里 this.Vue 访问不到,但是 this.React 可以访问。
然后 element-plus 在 require 阶段就会报错(虽然咱感觉这个锅得油猴背)。
react-dom 依赖 react,但是它在油猴扩展内正常加载
虽然没有处理好还是会报错,但是在函数之前加上
var process = {env:{NODE_ENV:'production'}};
之后它就能正常运行
fixed -> https://github.com/lisonge/vite-plugin-monkey/blob/v1.1.2/CHANGELOG.md#112
Vue 的 cdn 使用 iife 格式, element-plus 的 cdn 使用 umd 格式,油猴脚本的环境不支持两者混用
解决方式1: 叫他们同时提供 iife 和 umd 的格式,或者像react/react-dom一样统一umd
解决方式2: 自己下载这些库统一编译输出格式,然后通过 // require http://cdn.jsdelivr.net/gh/
引用自己仓库的文件
解决方式3: 不使用 cdn,尽量按需引入
Vue 的 cdn 使用 iife 格式, element-plus 的 cdn 使用 umd 格式,油猴脚本的环境不支持两者混用
解决方式1: 叫他们同时提供 iife 和 umd 的格式,或者像react/react-dom一样统一umd 解决方式2: 自己下载这些库统一编译输出格式,然后通过
// require http://cdn.jsdelivr.net/gh/
引用自己仓库的文件 解决方式3: 不使用 cdn,尽量按需引入
嗯嗯,谢谢了喵,这个 bug(or feature) 咱也给 TamperMonkey 那边提了 issues 但是没人回复所以就来这边了qwq
对于方式2,可以直接用现有的 vite 做
// vite.config.ts
import { defineConfig } from 'vite';
// https://vitejs.dev/config/
export default defineConfig({
build: {
lib: {
name: 'ElementPlus',
entry: './node_modules/element-plus',
formats: ['iife'],
},
rollupOptions: {
external: ['vue'],
output: {
globals: {
vue: 'Vue',
},
exports: 'named',
},
},
},
});
can be fixed by manual build library
突发奇想找到了一个解决方法,那就是在 库加载之前使用 @require 插入自定义代码
// ==UserScript==
// @name dev:example
// @namespace https://github.com/lisonge
// @version 1.0.1
// @require https://unpkg.com/vue@3.2.37//dist/vue.global.prod.js
// @require https://raw.githubusercontent.com/lisonge/src/main/js/monkey.js
// @require https://unpkg.com/element-plus@2.2.9//dist/index.full.js
// ==/UserScript==
// @grant none // 在此环境下也可行
console.log(`cdn load ok`);
https://raw.githubusercontent.com/lisonge/src/main/js/monkey.js
try{
this.Vue = this.Vue ?? Vue
}catch{}
try{
window.Vue = window.Vue ?? Vue
}catch{}
console.log({this:this, window, globalThis});
草,确实可以这样
我会在配置里扩展一下 build.externalGlobals
的 value
,让其支持多条 url
可以直接使用 dataurl 无需额外上传 cdn ,Tampermonkey ,Violentmonkey 我已测试过,均可行
{
vue: cdn.jsdelivr('Vue', 'dist/vue.global.prod.js').concat(
'data:application/javascript,' +
encodeURIComponent(
`;window.Vue=Vue;`,
),
)
}
可以直接使用 dataurl 无需额外上传 cdn ,Tampermonkey ,Violentmonkey 我已测试过,均可行
{ vue: cdn.jsdelivr('Vue', 'dist/vue.global.prod.js').concat( 'data:application/javascript,' + encodeURIComponent( `;window.Vue=Vue;`, ), ) }
可以直接使用 dataurl 无需额外上传 cdn ,Tampermonkey ,Violentmonkey 我已测试过,均可行
{ vue: cdn.jsdelivr('Vue', 'dist/vue.global.prod.js').concat( 'data:application/javascript,' + encodeURIComponent( `;window.Vue=Vue;`, ), ) }
好的,没注意到下面的内容。。