You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在SvelteKit中同时使用外部模块CDN与npm包的更优方案

在SvelteKit中实现客户端CDN加载依赖、服务端复用npm包的简洁方案需求

我在SvelteKit项目里有可前后端复用的通用JS文件,这类文件依赖moment.js(实际项目用date-fns,此处仅作示例)。希望实现:客户端通过CDN加载该依赖模块,服务端则使用npm包,避免把依赖打包进前端产物里。

原实现(存在依赖被打包的问题)

通用JS文件

import moment from 'moment';

export const mylib = () => {
  return moment().format();
};

Svelte页面代码

<script>    
    import moment from 'moment';
</script>
<div>
    {moment().format()}
</div>

这个实现能正常运行,但moment.js会被打包进前端产物,不符合需求。

我尝试的繁琐实现(虽生效但代码冗余、存在问题)

  1. 在app.html中引入CDN并添加加载回调:
<script async defer src="https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js" onload="momentLoad()"></script>
<script>
    window.momentWaits = [];
    const momentLoad = () => {
        for(const momentWait of window.momentWaits){
            momentWait();
        }
        delete window.momentWaits;
    };
</script>
  1. 将moment从devDependencies移至dependencies:
{
    "dependencies": {
        "moment": "^2.29.4"
    }
}
  1. 在vite.config.js中配置外部依赖:
export default defineConfig({
    build: {
        rollupOptions: {
            external: ['moment']
        }
    },
});
  1. 修改通用JS文件,区分环境获取moment实例:
let moment = null;
if(typeof window == 'undefined') {
  (async () => import('moment').then((res) => moment = res.default))();
}else {
  // eslint-disable-next-line no-undef
  const w = window;

  if(w.moment){
    moment = w.moment;
  }else{
    w.momentWaits.push(() => {
      moment = w.moment;
    });
  }
}

export const mylib = () => {
  if(!moment){
    console.log('not yet.');
    return;
  }
  return moment().format();
};

这里用typeof window == 'undefined'判断环境时构建会报错,改用$app/environment的browser变量可以解决,但这个通用JS文件需要在非Svelte环境运行,所以没采用。

  1. 修改Svelte页面,在onMount中处理moment加载逻辑:
<script>
    import { onMount } from 'svelte';

    let moment = null;
    onMount(async () => {

        if(window.moment){
            moment = window.moment;
        }else{
            window.momentWaits.push(() => {
                moment = window.moment;
            });
        }

    });
</script>
<div>
    {#if moment}
        {moment().format()}
    {:else}
        wait...
    {/if}
</div>

这个实现不仅代码冗余,还存在构建报错、CDN加载时机等问题。

需求

希望找到更简洁的实现方式,比如是否有构建时忽略特定错误的配置,或者更合适的事件替代onMount来处理CDN加载逻辑。

内容的提问来源于stack exchange,提问作者enoeht

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 07:15:06