Appearance
在浏览器中运行 Rollup
浏览器构建
¥The browser build
虽然常规 Rollup 构建依赖于一些 NodeJS 内置库,但也有一个仅使用浏览器 API 的浏览器构建可用。你可以通过安装它
¥While the regular Rollup build relies on some NodeJS builtin libraries, there is also a browser build available that only uses browser APIs. You can install it via
shell
npm install @rollup/browser
并在你的脚本中,通过导入它
¥and in your script, import it via
js
import { rollup } from '@rollup/browser';
或者,你可以从 CDN 导入,例如 用于 ESM 构建
¥Alternatively, you can import from a CDN, e.g. for the ESM build
js
import * as rollup from 'https://unpkg.com/@rollup/browser/dist/es/rollup.browser.js';
对于 UMD 构建
¥and for the UMD build
html
<script src="https://unpkg.com/@rollup/browser/dist/rollup.browser.js"></script>
这将创建一个全局变量 window.rollup
。请注意,在每种情况下,你都需要确保 @rollup/browser
包中的 dist/bindings_wasm_bg.wasm
文件位于浏览器版本提供的旁边。
¥which will create a global variable window.rollup
. Note that in each case, you need to make sure that the file dist/bindings_wasm_bg.wasm
from the @rollup/browser
package is served next to where the browser build is served.
由于浏览器构建无法访问文件系统,你需要通过 fs
选项提供 内存文件系统,或者需要 提供插件 来解析并加载所有要打包的模块。
¥As the browser build cannot access the file system, you either need to provide an in-memory file system via the fs
option, or you need to provide plugins that resolve and load all modules you want to bundle.
使用内存文件系统
¥Using an in-memory file system
Rollup 允许你提供内存文件系统实现,该实现至少需要实现 NodeJS fs
API 的某个子集,参见fs
选项。这使得浏览器构建的行为与 NodeJS 构建非常相似,甚至允许你使用依赖于文件系统的某些插件,前提是它们只能通过 this.fs
插件的 context 属性访问文件系统。以下是使用 memfs
的示例:
¥Rollup allows you to provide an in-memory file system implementation that needs to implement at least a certain sub-set of the NodeJS fs
API, cf. the fs
option. This makes the browser build behave very similar to the NodeJS build and even allows you to use certain plugins that rely on the file system, provided they only access it via the this.fs
plugin context property. Here is an example that uses memfs
:
js
import { rollup } from '@rollup/browser';
import { Volume } from 'memfs';
const vol = Volume.fromJSON({
'/main.js': "import foo from 'foo.js'; console.log(foo);",
'/foo.js': 'export default 42;'
});
rollup
.rollup({
input: '/main.js',
fs: vol.promises
})
.then(bundle => bundle.generate({ format: 'es' }))
.then(({ output }) => console.log(output[0].code));
使用插件解析和加载模块
¥Using plugins to resolve and load modules
你还可以通过插件解析和加载所有模块。你可以这样做:
¥You can also resolve and load all modules via plugins. Here is how you could do this:
js
const modules = {
'main.js': "import foo from 'foo.js'; console.log(foo);",
'foo.js': 'export default 42;'
};
rollup
.rollup({
input: 'main.js',
plugins: [
{
name: 'loader',
resolveId(source) {
if (modules.hasOwnProperty(source)) {
return source;
}
},
load(id) {
if (modules.hasOwnProperty(id)) {
return modules[id];
}
}
}
]
})
.then(bundle => bundle.generate({ format: 'es' }))
.then(({ output }) => console.log(output[0].code));
此示例仅支持两个导入,"main.js"
和 "foo.js"
,并且不支持相对导入。这是另一个使用绝对 URL 作为入口点并支持相对导入的示例。在这种情况下,我们只是重新打包 Rollup 本身,但它可以用于公开 ES 模块的任何其他 URL:
¥This example only supports two imports, "main.js"
and "foo.js"
, and no relative imports. Here is another example that uses absolute URLs as entry points and supports relative imports. In that case, we are just re-bundling Rollup itself, but it could be used on any other URL that exposes an ES module:
js
rollup
.rollup({
input: 'https://unpkg.com/rollup/dist/es/rollup.js',
plugins: [
{
name: 'url-resolver',
resolveId(source, importer) {
if (source[0] !== '.') {
try {
new URL(source);
// If it is a valid URL, return it
return source;
} catch {
// Otherwise make it external
return { id: source, external: true };
}
}
return new URL(source, importer).href;
},
async load(id) {
const response = await fetch(id);
return response.text();
}
}
]
})
.then(bundle => bundle.generate({ format: 'es' }))
.then(({ output }) => console.log(output));