rix*_*ixo 40
代码拆分实际上是动态导入的一个奇特名称。下面是如何使用 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)
})
Run Code Online (Sandbox Code Playgroud)
请注意,动态导入是原生 ES 功能,就像普通导入一样。这意味着它们由非过时的浏览器原生支持。
Rollup 一段时间以来一直支持“从动态导入中拆分代码”(请参阅文档)。
所以,如果你想在你的项目中进行代码拆分,主要是配置 Rollup 以便它对动态导入进行分块(另一种选择是解析和内联它们,这不会导致代码拆分)。
以下是执行此操作的步骤,从 Svelte 的官方模板 开始。
output.format为'es'output.file为output.dir(例如'public/build')<script>标记更改index.html为指向新的入口点/build/main.js,并使用type="module"output.format和output.dir并非所有 Rollup 中可用的输出格式都支持动态导入。默认来自 Svelte 模板,iife没有,所以我们需要改变。
output.format: 'es'不会重写import代码中的语句。这意味着我们将依赖浏览器的本机模块加载器。现在所有浏览器都支持 ESimport或动态import(...),并且可以对旧版浏览器进行 polyfill。
另一种选择可能是,例如output.format: 'system',对于SystemJS,但这需要我们从除了我们的代码出货第三方模块加载。
我们还需要更改output.file为,output.dir因为代码拆分不会产生单个bundle.js文件,而是多个块。(并且您不能将单独的文件写入单个文件,显然......)
所以,现在是我们的 Rollup 配置的相关部分:
input: 'src/main.js', // not changed
output: {
format: 'es',
dir: 'public/build/',
},
Run Code Online (Sandbox Code Playgroud)
如果此时运行yarn build(或npm run build),您将看到您的应用程序现在被拆分为.js`/public/build/ 目录中的多个文件。
我们现在需要更改<script>我们的标签index.html(位于 Svelte 模板中的 `public/index.html)以使用它。
<script defer type="module" src="/build/main.js"></script>
Run Code Online (Sandbox Code Playgroud)
首先,我们需要将srcfrom bundle.js(这是我们的旧output.file)更改为我们应用程序的新入口点。由于我们在 Rollup 配置 ( input) 中src/main.js的入口点是 ,我们的应用程序的主要入口点将被写入main.js(可使用 Rollup 的entryFileNames选项进行配置)。
由于我们的代码现在充满了 ESimport语句(因为我们正在使用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))
Run Code Online (Sandbox Code Playgroud)
这将导致 Rollup 创建一个Foo-[hash].js块(可通过chunkFileNames选项配置),并且可能创建另一个块用于Foo.svelte与其他组件共享的依赖项。
在浏览器中,只有import('./Foo.svelte')在代码中遇到该语句时才会加载此文件(延迟加载)。
(请注意,在瀑布中,页面加载后很长一段时间内如何加载Foo和Cmp- 一个共同的部门 - 由垂直红色条指示。)
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>
Run Code Online (Sandbox Code Playgroud)
瞧。完全成熟的代码拆分。(比你想象的要简单,不是吗?)
这是一个完整的示例,实现了此答案中涵盖的所有不同位。您可能对此提交特别感兴趣。
注意力!请注意,该示例example-code-splitting位于存储库的分支上,而不是master. 如果您克隆 repo,您将需要检出正确的分支!
用法示例:
# 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5754 次 |
| 最近记录: |