New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use rollup in a browser?I can't find how to use rollup in a browser in the official documentation! #3012
Comments
Rollup will not automatically pull in modules from remote URLs. You can use https://github.com/mjackson/rollup-plugin-url-resolve to do that but I never tried if it works in a browser (if not I think this would be worth a ticket). This is the basics of how you use Rollup without file system access if you roll your own loading logic: https://rollupjs.org/guide/en/#a-simple-example |
Also worth noting that Rollup may not be necessary in the browser. Most modern, up to date browsers support ES6 Modules via the |
Unfortunately, I can't use "https://github.com/mjackson/rollup-plugin-url-resolve" in my browser. |
I found the use of rollUp in the browser in the source code of the official website! <script context="module">
export function preload() {
return this.fetch(`api/examples.json`).then(r => r.json()).then(examples => ({ examples }));
}
</script>
<script>
import Input from './_Input/index.svelte';
import Output from './_Output/index.svelte';
import {dirname, resolve} from './_utils/path';
import {supportsCodeSplitting, supportsInput} from './_utils/rollupVersion';
import { onMount } from 'svelte';
import { stores } from '@sapper/app';
import { get } from 'svelte/store';
export let examples = [];
let output = [];
let options = {
format: 'cjs',
name: 'myBundle',
amd: { id: '' },
globals: {}
};
let codeSplitting = false;
let selectedExample = null;
let selectedExampleModules = [];
let modules = [];
let warnings = [];
let input;
let rollup;
let error;
function getUrlRollupVersion() {
if (typeof window === 'undefined') return null;
const versionMatch = /version=([^&]+)/.exec(window.location.search);
return versionMatch && versionMatch[1];
}
const urlRollupVersion = getUrlRollupVersion();
const atob = typeof window ==='undefined'
? base64 => Buffer.from(base64, 'base64').toString()
: window.atob;
function loadRollup () {
const url = urlRollupVersion ?
`https://unpkg.com/rollup@${urlRollupVersion}/dist/rollup.browser.js` :
'https://unpkg.com/rollup/dist/rollup.browser.js';
return new Promise(( fulfil, reject ) => {
const script = document.createElement('script');
script.src = url;
script.onload = () => {
fulfil(window.rollup);
};
script.onerror = reject;
document.querySelector('head').appendChild(script);
});
}
onMount(async () => {
const {query} = get(stores().page);
try {
if ( query.shareable ) {
const json = decodeURIComponent(atob(query.shareable));
({modules, options, example: selectedExample} = JSON.parse(json));
input.$set({modules, selectedExample});
} else if ( query.gist ) {
const result = await (await fetch(`https://api.github.com/gists/${query.gist}`, {
method: 'GET',
headers: { Accept: 'application/vnd.github.v3+json' }
})).json();
const entryModules = query.entry ? query.entry.split(',') : [];
modules = [result.files['main.js'] || { filename: 'main.js', content: '' }]
.concat(Object.keys(result.files)
.filter(fileName => fileName !== 'main.js')
.map(fileName => result.files[fileName])
).map(module => ({
name: module.filename,
code: module.content,
isEntry: entryModules.indexOf(module.filename) >= 0
}));
} else {
selectedExample = '00';
}
} catch (err) {
console.error(err);
selectedExample = '00';
}
rollup = await loadRollup();
codeSplitting = rollup && supportsCodeSplitting(rollup.VERSION);
return requestBundle();
});
$: {
if (selectedExample) {
updateSelectedExample();
}
}
function updateSelectedExample() {
fetch(`api/examples/${selectedExample}.json`).then(r => r.json()).then(example => {
modules = example.modules;
selectedExampleModules = modules.map(module => ({...module}))
});
input.$set({modules, selectedExample});
}
$: {
if (modules) {
requestDebouncedBundle();
}
}
$: {
if (options) {
requestBundle();
}
}
// TODO instead of debouncing, we should bundle in a worker
let bundleDebounceTimeout;
function requestDebouncedBundle() {
clearTimeout(bundleDebounceTimeout);
bundleDebounceTimeout = setTimeout(requestBundle, 100);
}
let bundlePromise = null;
async function requestBundle() {
if (!modules.length || !rollup) return;
if (bundlePromise) {
await bundlePromise;
}
bundlePromise = bundle().then(() => bundlePromise = null);
}
async function bundle () {
console.clear();
console.log(`running Rollup version %c${rollup.VERSION}`, 'font-weight: bold');
if (selectedExample && selectedExampleModules.length) {
if (modules.length !== selectedExampleModules.length || selectedExampleModules.some((module, index) => {
const currentModule = modules[index];
return currentModule.name !== module.name ||
currentModule.code !== module.code ||
currentModule.isEntry !== module.isEntry;
})) {
selectedExample = null;
selectedExampleModules = [];
}
}
updateUrl();
let moduleById = {};
modules.forEach(module => {
moduleById[module.name] = module;
});
warnings = [];
const inputOptions = {
plugins: [{
resolveId ( importee, importer ) {
if ( !importer ) return importee;
if ( importee[0] !== '.' ) return false;
let resolved = resolve(dirname(importer), importee).replace(/^\.\//, '');
if ( resolved in moduleById ) return resolved;
resolved += '.js';
if ( resolved in moduleById ) return resolved;
throw new Error(`Could not resolve '${importee}' from '${importer}'`);
},
load: function ( id ) {
return moduleById[id].code;
}
}],
onwarn ( warning ) {
warnings.push(warning);
console.group(warning.loc ? warning.loc.file : '');
console.warn(warning.message);
if ( warning.frame ) {
console.log(warning.frame);
}
if ( warning.url ) {
console.log(`See ${warning.url} for more information`);
}
console.groupEnd();
}
};
if ( codeSplitting ) {
inputOptions.input = modules
.filter(( module, index ) => index === 0 || module.isEntry)
.map(module => module.name);
} else {
inputOptions[supportsInput(rollup.VERSION) ? 'input' : 'entry'] = 'main.js';
}
try {
const generated = await (await rollup.rollup(inputOptions)).generate(options);
if ( codeSplitting ) {
output = generated.output;
error = null;
} else {
output = [generated];
error = null;
}
} catch (err) {
error = err;
if ( error.frame ) console.log(error.frame);
setTimeout(() => {
throw error;
});
}
}
function updateUrl () {
if ( typeof history === 'undefined' ) return;
const params = {};
if ( typeof rollup !== 'undefined' ) {
params.version = rollup.VERSION;
} else if ( urlRollupVersion ) {
params.version = urlRollupVersion;
}
const json = JSON.stringify({
modules,
options,
example: selectedExample
});
params.shareable = btoa(encodeURIComponent(json));
const queryString = Object.keys(params).map(key => `${key}=${params[key]}`).join('&');
const url = `/repl/?${queryString}`;
window.history.replaceState({}, '', url);
}
</script>
<style>
.repl {
height: calc(100% - 3.6em);
}
.left, .right {
width: 100%;
padding: 1em;
}
:global(button) {
font-family: inherit;
font-size: inherit;
border: none;
outline: none;
cursor: pointer;
background-color: #eee;
padding: 0.5em 1em;
margin-bottom: 1em;
}
:global(button):hover, :global(button):active {
background-color: #eaeaea;
}
:global(button):disabled {
cursor: default;
}
:global(.icon) {
font-size: 0.8em;
}
:global(input) {
display: block;
width: 100%;
font-family: inherit;
font-size: inherit;
padding: 0.5em;
border: none;
outline: none;
line-height: 1;
color: #333;
background-color: inherit;
}
:global(input):focus {
background-color: #eaeaea;
}
@media (min-width: 45rem) {
.left, .right {
width: 50%;
height: 100%;
float: left;
overflow-y: auto;
}
}
</style>
<div class='repl'>
<div class='left'>
<h2>ES6 modules go in...</h2>
<div class='input'>
<Input {examples} {codeSplitting} bind:selectedExample bind:modules bind:this={input}/>
</div>
</div>
<div class='right'>
<h2>...{#if output.length > 1}chunks come{:else}bundle comes{/if} out</h2>
<div class='output'>
<Output bind:options {output} {error} {warnings} waiting={!rollup}/>
</div>
</div>
</div>
<!-- trick Sapper into generating example JSON files -->
{#each examples as example}
<a hidden href="api/examples/{example.id}.json">{example.title}</a>
{/each} |
If the plugin itself is the problem, I would really recommend opening a ticket for this plugin as this could become a powerful extension.
You can use all In short,
One unfortunate point is that the Rollup website cannot use the dynamic import syntax due to compatibility with outdated versions but mainly because of content security policy issues that we do not have under control. |
Same issue/proposal here. https://cdn.jsdelivr.net/npm/rollup@2.56.3/dist/rollup.browser.js var bundle = rollup.rollup({
input: "rollup://localhost/a.mjs",
plugins: [
{
name: "rollup-in-browser-example",
resolveId(importee, importer) {
console.debug("resolveId", { importee, importer });
return new URL(importee, importer).href;
},
load(id) {
console.debug("load", { id });
switch (id) {
case "rollup://localhost/a.mjs":
return `import b from './b.mjs'; export default {a:b};`;
case "rollup://localhost/b.mjs":
return Promise.resolve(`export default {b:'b'}`);
}
throw new Error();
},
},
],
});
var { code } = (await (await bundle).generate({})).output[0];
console.info(code); Output var b = {b:'b'};
var a = {a:b};
export { a as default }; |
Are there any CDN provide rollup browser ESM build? 🤔 |
https://cdn.skypack.dev/rollup /*
* [Package Error] "rollup@v2.57.0" could not be built.
*
* [1/5] Verifying package is valid…
* [2/5] Installing dependencies from npm…
* [3/5] Building package using esinstall…
* Running esinstall...
* rollup-plugin-inject: failed to parse rollup/dist/shared/rollup.js. Consider restricting the plugin to particular files via options.include
* Failed to load node_modules/rollup/dist/shared/rollup.js
* Unexpected token
* Install failed.
* Install failed.
*
* How to fix:
* - If you believe this to be an error in Skypack, file an issue here: https://github.com/skypackjs/skypack-cdn/issues
* - If you believe this to be an issue in the package, share this URL with the package authors to help them debug & fix.
* - Use https://skypack.dev/ to find a web-friendly alternative to find another package.
*/ |
No idea what Skypack is doing there, but Rollup does have an ESM build that ships with each install (as well as a browser ESM build). The ESM Node build is located in |
@lukastaegert |
Just wanted to second this. This would be super useful for making custom bundle builders for libraries so that people can configure their bundle client side. |
Here's the fix for version
|
Documentation Is:
Please Explain in Detail...
How to use rollup in a browser?
I found the rollup's ES module for the browser in the npm repository, but I don't know how to use it in the browser.
https://cdn.jsdelivr.net/npm/rollup@1.17.0/dist/rollup.browser.es.js
I can't find how to use rollup in a browser in the official documentation!
Your Proposal for Changes
Please provide more help documentation!
The text was updated successfully, but these errors were encountered: