Research
Security News
Threat Actor Exposes Playbook for Exploiting npm to Build Blockchain-Powered Botnets
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It is optimized for bundling JavaScript files to use in a browser, and it is also capable of transforming code using plugins.
Bundling Modules
Rollup can bundle multiple JavaScript modules into a single file. The above code demonstrates how to create a bundle from an entry point file 'src/main.js' and output it as an immediately-invoked function expression (IIFE) to 'bundle.js'.
import rollup from 'rollup';
async function build() {
const bundle = await rollup.rollup({
input: 'src/main.js'
});
await bundle.write({
file: 'bundle.js',
format: 'iife',
name: 'MyModule'
});
}
build();
Tree-shaking
Rollup includes a feature called 'tree-shaking' which removes unused code from the final bundle. This helps in reducing the size of the bundle and improving load times.
import { rollup } from 'rollup';
rollup({
input: 'src/index.js',
treeshake: true // Tree-shaking is enabled by default
}).then(bundle => {
// Code to write the bundle
});
Plugin System
Rollup supports a wide range of plugins that can transform the code, add functionality, or integrate with other build tools. The code sample shows how to use the JSON plugin to import JSON files as modules.
import { rollup } from 'rollup';
import json from '@rollup/plugin-json';
rollup({
input: 'src/index.js',
plugins: [json()]
}).then(bundle => {
// Code to write the bundle
});
Webpack is a powerful module bundler that can handle not only JavaScript but also assets like images, fonts, and stylesheets. It has a larger ecosystem and more configuration options compared to Rollup, making it more suitable for complex applications.
Parcel is a web application bundler that offers a zero-configuration experience. It is known for its fast build times and out-of-the-box support for various file types. Parcel is easier to set up than Rollup and Webpack but may offer less fine-grained control.
Browserify allows you to use `require('modules')` in the browser by bundling up all of your dependencies. It is one of the earlier bundlers and is focused on simplicity and ease of use, but it doesn't have built-in tree-shaking like Rollup.
I roll up, I roll up, I roll up, Shawty I roll up
I roll up, I roll up, I roll up –Wiz Khalifa
This is an early stage project under active development. If you find a bug, please raise an issue!.
Rollup includes both an API and a CLI tool.
To bundle an app without any external dependencies, just choose the output module format (--format/-f
) and point rollup at the entry file.
rollup --format iife -- src/app.js > build/app.js
# With inline sourcemaps:
rollup -f iife --sourcemap inline -- src/app.js > build/app.js
When you have external dependencies, specify them with --external/-e
.
rollup --format cjs -e acorn,chalk,magic-string -- src/main.js > lib/main.js
# When building UMD, you may need to name the globals
rollup -f umd --globals jquery:jQuery,lodash:_ -- src/app.js > build.app.js
If your external dependency is packaged through npm and has a jsnext:main
field in its package.json file, rollup won't treat it as an external dependency and can be clever about extracting only the required variable bindings.
For the complete set of options, run rollup --help
.
Right now, you have a few different options if you want to create a bundle out of your ES6 modules:
1. Esperanto has recently been deprecated in favor of rollup. :)
But there's a flaw in how these systems work. Pretend it's the future, and lodash is available as an ES6 module, and you want to use a single helper function from it:
// app.js
import { pluck } from 'lodash';
With that single import statement, you've just caused the whole of lodash to be included in your bundle, even though you only need to use a tiny fraction of the code therein.
If you're using esperanto, that's not totally disastrous, because a sufficiently good minifier will be able to determine through static analysis that most of the code will never run, and so remove it. But there are lots of situations where static analysis fails, and unused code will continue to clutter up your bundle.
If you're using any of the other tools, static analysis won't be able to even begin to determine which of lodash's exports aren't used by your app (AFAIK! please correct me if I'm wrong).
I picked lodash because it does offer one solution to this problem: modular builds. Today, in your CommonJS modules, you can do this:
var pluck = require( 'lodash/collection/pluck' );
This is not the answer. Using a folder structure to define an interface is a bad idea - it makes it harder to guarantee backwards compatibility, it imposes awkward constraints on library authors, and it allows developers to do this sort of thing:
var cheekyHack = require( 'undocumented/private/module' );
Sure enough, you won't be able to do this with ES6 modules.
This project is an attempt to prove a different idea: ES6 modules should define their interface through a single file (which, by convention, is currently exposed as the jsnext:main
field in your package.json file), like so...
// snippet from future-lodash.js
export { partition } from './src/collection/partition';
export { pluck } from './src/collection/pluck';
export { reduce } from './src/collection/reduce';
/* ...and so on... */
...and ES6 bundlers should handle importing in a much more granular fashion. Rather than importing an entire module, an intelligent bundler should be able to reason like so:
pluck
from future-lodash.js
future-lodash.js
, the definition of pluck
can be found in lodash/src/collection/pluck.js
pluck
depends on map
and property
, which are in... these filesIn other words, the 'tree-shaking' approach of throwing everything in then removing the bits you don't need is all wrong - instead, we should be selective about what we include in the first place.
This is not a trivial task. There are almost certainly a great many complex edge cases. Perhaps it's not possible. But I intend to find out.
The example below is aspirational. It isn't yet implemented - it exists in the name of README driven development.
rollup.rollup({
// The bundle's starting point
entry: 'app.js',
// Any external modules you don't want to include
// in the bundle (includes node built-ins)
external: [ 'path', 'fs', 'some-other-lib' ]
}).then( function ( bundle ) {
// generate code and a sourcemap
const { code, map } = bundle.generate({
// output format - 'amd', 'cjs', 'es6', 'iife', 'umd'
format: 'amd',
// exports - 'auto', 'none', 'default', 'named'
exports: 'auto',
// amd/umd options
moduleId: 'my-library',
// umd options
moduleName: 'MyLibrary', // necessary if the bundle has exports
globals: {
backbone: 'Backbone'
}
});
fs.writeFileSync( 'bundle.js', code + '\n//# sourceMappingURL=bundle.js.map' );
fs.writeFileSync( 'bundle.js.map', map.toString() );
// possible convenience method
bundle.write({
dest: 'bundle.js', // also writes sourcemap
format: 'amd'
});
});
The duplication (rollup.rollup
) is intentional. You have to say it like you're in the circus, otherwise it won't work.
Not that there's any code here at the time of writing, but this project is released under the MIT license.
FAQs
Next-generation ES module bundler
The npm package rollup receives a total of 23,851,281 weekly downloads. As such, rollup popularity was classified as popular.
We found that rollup demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.