three.js 在 cdn 上使用 svelte 或 react
three.js over cdn using svelte or react
有没有什么方法可以构建我的 svelte 或 React 应用程序,three.js 模块(我通常使用 npm 导入)将被声明为脚本标签,该标签将从加速网络?我想保留框架的优势,但也能够减少我的最终包大小,因为我的大部分包都包含三个代码。
谢谢你的智慧
是的,您可以执行以下操作:
在您的“index.html”文件中,您可以按如下方式从 CDN 导入 js 文件:
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
然后,在你想要使用它的文件中,例如 React 组件,你可以执行以下操作:
const THREE = window.THREE;
这将替换您的导入语句,它本来是 import * as THREE from "three";
或 import THREE from "three";
有两种方法可以实现减小捆绑包大小的目标:
- 从 CDN 导入(您的建议)
- 代码拆分
从 CDN 导入
为了保持 ESModules 的语义,您可以简单地将当前的 three.js
导入替换为来自 npm CDN 的 URL,例如 unpkg
:
Pros
Cons
No extra configuration needed
Slower to load, as browser needs to spin up new connections to access third-party CDN
异步
<script>
// App.svelte
import('https://unpkg.com/three@0.133.1/build/three.min.js').then(({ default: THREE }) => {
// your code here
});
</script>
同步
Note: Importing like this blocks the rest of your script from loading while three.js
is downloading, which defeats the purpose of the whole shebang. It's just here for completeness
<script>
// App.svelte
import { default as THREE } from 'https://unpkg.com/three@0.133.1/build/three.min.js';
// your code here
</script>
代码拆分
此方法利用了您已经在使用捆绑器这一事实(可能 rollup
、vite
或 webpack
)。这个答案将集中在 rollup
上,因为它是 svelte
示例中使用的默认值。
Pros
Cons
Faster to load, as browser can use existing connections to access first-party resources
More complicated to get set up
异步
在您的 rollup.config.js
文件中,确保 output.format
设置为 'esm'
并且设置 output.dir
而不是 output.file
// rollup.config.js
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/index.js',
output: {
sourcemap: !production,
format: 'esm',
name: 'app',
dir: 'public',
},
plugins: {
// your plugins
svelte({
compilerOptions: {
dev: !production,
},
}),
postcss({
extract: 'bundle.css',
}),
resolve({
browser: true,
dedupe: ['svelte'],
}),
commonjs(),
}
}
<script>
// App.svelte
import('three').then(({ default: THREE }) => {
// your code here
});
</script>
Note: There is no synchronous way due to how code-splitting is evaluated at compile time. Plus it doesn't make much sense to do it like that anyways.
有没有什么方法可以构建我的 svelte 或 React 应用程序,three.js 模块(我通常使用 npm 导入)将被声明为脚本标签,该标签将从加速网络?我想保留框架的优势,但也能够减少我的最终包大小,因为我的大部分包都包含三个代码。
谢谢你的智慧
是的,您可以执行以下操作:
在您的“index.html”文件中,您可以按如下方式从 CDN 导入 js 文件:
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
然后,在你想要使用它的文件中,例如 React 组件,你可以执行以下操作:
const THREE = window.THREE;
这将替换您的导入语句,它本来是 import * as THREE from "three";
或 import THREE from "three";
有两种方法可以实现减小捆绑包大小的目标:
- 从 CDN 导入(您的建议)
- 代码拆分
从 CDN 导入
为了保持 ESModules 的语义,您可以简单地将当前的 three.js
导入替换为来自 npm CDN 的 URL,例如 unpkg
:
Pros | Cons |
---|---|
No extra configuration needed | Slower to load, as browser needs to spin up new connections to access third-party CDN |
异步
<script>
// App.svelte
import('https://unpkg.com/three@0.133.1/build/three.min.js').then(({ default: THREE }) => {
// your code here
});
</script>
同步
Note: Importing like this blocks the rest of your script from loading while
three.js
is downloading, which defeats the purpose of the whole shebang. It's just here for completeness
<script>
// App.svelte
import { default as THREE } from 'https://unpkg.com/three@0.133.1/build/three.min.js';
// your code here
</script>
代码拆分
此方法利用了您已经在使用捆绑器这一事实(可能 rollup
、vite
或 webpack
)。这个答案将集中在 rollup
上,因为它是 svelte
示例中使用的默认值。
Pros | Cons |
---|---|
Faster to load, as browser can use existing connections to access first-party resources | More complicated to get set up |
异步
在您的 rollup.config.js
文件中,确保 output.format
设置为 'esm'
并且设置 output.dir
而不是 output.file
// rollup.config.js
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/index.js',
output: {
sourcemap: !production,
format: 'esm',
name: 'app',
dir: 'public',
},
plugins: {
// your plugins
svelte({
compilerOptions: {
dev: !production,
},
}),
postcss({
extract: 'bundle.css',
}),
resolve({
browser: true,
dedupe: ['svelte'],
}),
commonjs(),
}
}
<script>
// App.svelte
import('three').then(({ default: THREE }) => {
// your code here
});
</script>
Note: There is no synchronous way due to how code-splitting is evaluated at compile time. Plus it doesn't make much sense to do it like that anyways.