gpt4 book ai didi

svelte - 如何在没有 Sapper 的情况下使用 Svelte 进行代码拆分

转载 作者:行者123 更新时间:2023-12-02 11:23:26 26 4
gpt4 key购买 nike

您如何使用 Svelte 进行代码拆分?

(我知道您可以使用 Sapper 来完成,但我不想依赖节点后端)

最佳答案

代码拆分实际上是动态导入的一个奇特名称。下面是如何使用 Rollup 做到这一点(在此过程中,您还将获得杀手级的摇树!)。

关于动态导入的提醒:

// "normal" static ES import
//
// - statically analytisable
// - must be called at top level
// - will be greedily resolved (and most often inlined) by your bundler
//
import Foo from './Foo.svelte'

// dynamic import
//
// - called like a function
// - returns a promise
// - default export is accessible on key `default` of the result
// - will be bundled into its own chunk by your bundler (hence code splitting)
//
import('./Foo.svelte').then(module => {
const cmp = module.default
console.log(module.myNamedExport)
})

请注意,动态导入是原生 ES 功能,就像普通导入一样。这意味着它们由非过时的浏览器原生支持。

Rollup 一直支持“从动态导入中拆分代码”(参见 docs)。

所以,如果你想在你的项目中进行代码拆分,主要是配置 Rollup 以便它对动态导入进行分块(另一种选择是解析和内联它们,这不会导致代码拆分)。

以下是执行此操作的步骤,从 Svelte 的 official template 开始.
  • output.format'es'
  • output.fileoutput.dir (例如 'public/build')
  • 更改 <script>标签在 index.html指向新的入口点 /build/main.js ,并使用 type="module"
  • 用动态导入编写一些代码
  • 添加对旧浏览器的支持

  • 汇总配置: output.formatoutput.dir
    并非所有 Rollup 中可用的输出格式都支持动态导入。 Svelte 模板中的默认值, iife没有,所以我们需要改变。
    output.format: 'es'不会重写 import代码中的语句。这意味着我们将依赖浏览器的 native 模块加载器。所有浏览器都支持 ES import或动态 import(...)如今,旧版浏览器可以使用 polyfill。

    例如,另一个选项可以是 output.format: 'system' , 为 SystemJS ,但这将要求我们除了我们的代码之外还运送第三方模块加载器。

    我们也需要改 output.fileoutput.dir因为代码拆分不会产生单个 bundle.js文件,但有多个块。 (并且您不能将单独的文件写入单个文件,显然......)

    所以,现在是我们的 Rollup 配置的相关部分:

      input: 'src/main.js', // not changed
    output: {
    format: 'es',
    dir: 'public/build/',
    },

    如果您运行 yarn build (或 npm run build )此时,您会看到您的应用程序现在被拆分为多个 .js `/public/build/目录中的文件。

    索引.html

    我们现在需要更改 <script>我们的标签 index.html (位于 Svelte 模板中的 `public/index.html 中)来使用它。

        <script defer type="module" src="/build/main.js"></script>

    首先,我们需要更改 src来自 bundle.js (这是我们旧的 output.file )到我们应用程序的新入口点。由于我们在 Rollup 配置( input )中的入口点是 src/main.js ,我们应用的主入口点将被写入 main.js (可使用 Rollup 的 entryFileNames 选项进行配置)。

    由于我们的代码现在全是 ES import语句(因为我们使用的是 output.format='esm' ),我们还需要更改脚本的类型 script (默认)到 module通过添加 type="module"属性到我们的脚本标签。

    这就是现代浏览器的全部内容,您现在拥有完全可用的代码拆分支持!

    实际上拆分您的应用程序

    代码拆分支持不足以获得实际的代码拆分。它只是使它成为可能。您仍然需要将动态块与应用程序的其余部分(主要)分开。

    您可以通过在代码中编写动态导入来做到这一点。例如:

    import('./Foo.svelte')
    .then(module => module.default)
    .then(Foo => { /* do something with Foo */ })
    .catch(err => console.error(err))

    这将导致 Rollup 创建一个 Foo-[hash].js块(可配置 chunkFileNames 选项),可能还有另一个块用于依赖 Foo.svelte与其他组件共享。

    在浏览器中,只有在 import('./Foo.svelte') 时才会加载这个文件。在您的代码中遇到语句(延迟加载)。

    enter image description here

    (注意,在瀑布中, FooCmp——一个常见的 dep——在页面加载后很长时间才被加载,由垂直的红色条指示。)

    旧版浏览器

    Edge(在最近成为 Chrome 之前)不支持动态导入。正常的 ES 导入,是的,但是是动态的 import(...)没有。这通常就是为什么你必须为过时的浏览器包含一些 polyfill。

    一种解决方案,如 rollup-starter-code-splitting例如,是在浏览器中使用第三方模块加载器(例如 SytemJS)。

    目前可用的另一个可能更简单的解决方案是使用 dimport 包。它根据主机浏览器的需要填充对 ES 导入和动态导入的支持。

    为了使用它,我们正在替换我们的 <script>标签在 index.html具有以下内容:

        <script defer type="module" src="https://unpkg.com/dimport?module"
    data-main="/build/main.js"></script>
    <script defer type="nomodule" src="https://unpkg.com/dimport/nomodule"
    data-main="/build/main.js"></script>

    瞧。完全成熟的代码拆分。 (比你想象的要简单,不是吗?)

    完整示例

    这是一个 complete example实现此答案中涵盖的所有不同位。您可能对 this commit 特别感兴趣.

    注意!请注意该示例位于 example-code-splitting存储库的分支,而不是 master .如果您克隆 repo,您​​将需要 check out 正确的分支!

    用法示例:

    # install
    npx degit rixo/svelte-template-hot#example-code-splitting svelte-app
    cd svelte-app
    yarn # or npm install

    # dev
    yarn dev

    # build
    yarn build
    # serve build
    yarn start

    关于svelte - 如何在没有 Sapper 的情况下使用 Svelte 进行代码拆分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60024414/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com