如何在SvelteKit中引入非NPM JS库?以Blotter.js为例
Blotter.js在SvelteKit中报错
Blotter is not defined的原理与解决方案 问题概述
Blotter.js(液态文字效果库)在普通Svelte项目中可正常运行,但在SvelteKit项目中触发Blotter is not defined报错。测试场景包含两个项目:一个纯客户端Svelte项目(运行正常),一个SvelteKit项目(触发报错)。
原理分析
- SSR环境限制:SvelteKit默认采用服务端渲染(SSR),服务端运行时没有浏览器的DOM、Canvas等API,而Blotter.js依赖这些浏览器专属环境,直接在服务端执行导入或初始化代码会导致未定义错误。普通Svelte是纯客户端渲染,不存在这个问题。
- 模块格式兼容性:Blotter.js采用UMD模块格式,在ES模块优先的SvelteKit环境中,直接按ES模块导入可能无法正确解析导出对象,导致
Blotter变量未被正确赋值。
解决方案
方案1:客户端动态导入+onMount钩子
利用Svelte的onMount钩子(仅在客户端执行),动态导入Blotter.js,确保代码只在浏览器环境运行:
<script> import { onMount } from 'svelte'; onMount(async () => { const Blotter = (await import('blotter')).default; // 引入所需材质(示例为ChannelSplitMaterial) await import('blotter/build/materials/ChannelSplitMaterial.min.js'); // 后续Blotter初始化代码 const material = new Blotter.ChannelSplitMaterial(); material.uniforms.uOffset.value = 0.05; const blotter = new Blotter(material, { texts: { value: 'BLOTTER TEXT' } }); const scope = blotter.forText(document.getElementById('blotter-text')); }); </script> <div id="blotter-text"></div>
方案2:配置Vite忽略SSR处理
在vite.config.js中配置将Blotter列为SSR外部依赖,避免服务端尝试解析该库:
import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vite'; export default defineConfig({ plugins: [sveltekit()], ssr: { external: ['blotter'] } });
然后在src/app.html的<head>中添加CDN脚本引入:
<script src="https://unpkg.com/blotter@0.1.3/build/blotter.min.js"></script> <script src="https://unpkg.com/blotter@0.1.3/build/materials/ChannelSplitMaterial.min.js"></script>
之后即可在组件中直接使用全局的Blotter变量。
方案3:切换为静态适配(无SSR)
如果项目不需要服务端渲染,可切换为@sveltejs/adapter-static:
- 安装适配器:
npm install @sveltejs/adapter-static - 修改
svelte.config.js:
import adapter from '@sveltejs/adapter-static'; export default { kit: { adapter: adapter() } };
此时项目和普通Svelte一样为纯客户端运行,Blotter.js可按普通Svelte的方式导入使用。
Blotter官方使用说明(中文翻译)
使用步骤
- 引入Blotter核心库及材质脚本
可通过CDN或本地文件引入:<script src="https://unpkg.com/blotter@0.1.3/build/blotter.min.js"></script> <script src="https://unpkg.com/blotter@0.1.3/build/materials/ChannelSplitMaterial.min.js"></script>- 创建文本容器元素
<div id="target-text"></div>- 初始化Blotter实例并绑定材质
// 创建材质实例并配置参数 const material = new Blotter.ChannelSplitMaterial(); material.uniforms.uOffset.value = 0.05; // 初始化Blotter,绑定材质与文本内容 const blotter = new Blotter(material, { texts: { value: "你的液态文字内容" } }); // 将渲染结果挂载到容器 const scope = blotter.forText(document.getElementById("target-text"));- 自定义样式与动画
通过CSS调整容器的位置、尺寸,或修改材质的uniform参数来控制动画效果。
内容的提问来源于stack exchange,提问作者Elbong Gearny
相关产品推荐
相关产品推荐

