Reid  Rohan

Reid Rohan

1667178300

TSdx: Zero-config CLI for TypeScript Package Development

TSdx

Despite all the recent hype, setting up a new TypeScript (x React) library can be tough. Between Rollup, Jest, tsconfig, Yarn resolutions, ESLint, and getting VSCode to play nicely....there is just a whole lot of stuff to do (and things to screw up). TSDX is a zero-config CLI that helps you develop, test, and publish modern TypeScript packages with ease--so you can focus on your awesome new library and not waste another afternoon on the configuration.

Features

TSDX comes with the "battery-pack included" and is part of a complete TypeScript breakfast:

  • Bundles your code with Rollup and outputs multiple module formats (CJS & ESM by default, and also UMD if you want) plus development and production builds
  • Comes with treeshaking, ready-to-rock lodash optimizations, and minification/compression
  • Live reload / watch-mode
  • Works with React
  • Human readable error messages (and in VSCode-friendly format)
  • Bundle size snapshots
  • Opt-in to extract invariant error codes
  • Jest test runner setup with sensible defaults via tsdx test
  • ESLint with Prettier setup with sensible defaults via tsdx lint
  • Zero-config, single dependency
  • Escape hatches for customization via .babelrc.js, jest.config.js, .eslintrc.js, and tsdx.config.js

Quick Start

npx tsdx create mylib
cd mylib
yarn start

That's it. You don't need to worry about setting up TypeScript or Rollup or Jest or other plumbing. Just start editing src/index.ts and go!

Below is a list of commands you will probably find useful:

npm start or yarn start

Runs the project in development/watch mode. Your project will be rebuilt upon changes. TSDX has a special logger for your convenience. Error messages are pretty printed and formatted for compatibility VS Code's Problems tab.

Your library will be rebuilt if you make edits.

npm run build or yarn build

Bundles the package to the dist folder. The package is optimized and bundled with Rollup into multiple formats (CommonJS, UMD, and ES Module).

npm test or yarn test

Runs your tests using Jest.

npm run lint or yarn lint

Runs Eslint with Prettier on .ts and .tsx files. If you want to customize eslint you can add an eslint block to your package.json, or you can run yarn lint --write-file and edit the generated .eslintrc.js file.

prepare script

Bundles and packages to the dist folder. Runs automatically when you run either npm publish or yarn publish. The prepare script will run the equivalent of npm run build or yarn build. It will also be run if your module is installed as a git dependency (ie: "mymodule": "github:myuser/mymodule#some-branch") so it can be depended on without checking the transpiled code into git.

Optimizations

Aside from just bundling your module into different formats, TSDX comes with some optimizations for your convenience. They yield objectively better code and smaller bundle sizes.

After TSDX compiles your code with TypeScript, it processes your code with 3 Babel plugins:

Development-only Expressions + Treeshaking

babel-plugin-annotate-pure-calls + babel-plugin-dev-expressions work together to fully eliminate dead code (aka treeshake) development checks from your production code. Let's look at an example to see how it works.

Imagine our source code is just this:

// ./src/index.ts
export const sum = (a: number, b: number) => {
  if (process.env.NODE_ENV !== 'production') {
    console.log('Helpful dev-only error message');
  }
  return a + b;
};

tsdx build will output an ES module file and 3 CommonJS files (dev, prod, and an entry file). If you want to specify a UMD build, you can do that as well. For brevity, let's examine the CommonJS output (comments added for emphasis):

// Entry File
// ./dist/index.js
'use strict';

// This determines which build to use based on the `NODE_ENV` of your end user.
if (process.env.NODE_ENV === 'production') {
  module.exports = require('./mylib.cjs.production.js');
} else {
  module.exports = require('./mylib.development.cjs');
}
// CommonJS Development Build
// ./dist/mylib.development.cjs
'use strict';

const sum = (a, b) => {
  {
    console.log('Helpful dev-only error message');
  }

  return a + b;
};

exports.sum = sum;
//# sourceMappingURL=mylib.development.cjs.map
// CommonJS Production Build
// ./dist/mylib.cjs.production.js
'use strict';
exports.sum = (s, t) => s + t;
//# sourceMappingURL=test-react-tsdx.cjs.production.js.map

AS you can see, TSDX stripped out the development check from the production code. This allows you to safely add development-only behavior (like more useful error messages) without any production bundle size impact.

For ESM build, it's up to end-user to build environment specific build with NODE_ENV replace (done by Webpack 4 automatically).

Rollup Treeshaking

TSDX's rollup config removes getters and setters on objects so that property access has no side effects. Don't do it.

Advanced babel-plugin-dev-expressions

TSDX will use babel-plugin-dev-expressions to make the following replacements before treeshaking.

__DEV__

Replaces

if (__DEV__) {
  console.log('foo');
}

with

if (process.env.NODE_ENV !== 'production') {
  console.log('foo');
}

IMPORTANT: To use __DEV__ in TypeScript, you need to add declare var __DEV__: boolean somewhere in your project's type path (e.g. ./types/index.d.ts).

// ./types/index.d.ts
declare var __DEV__: boolean;

Note: The dev-expression transform does not run when NODE_ENV is test. As such, if you use __DEV__, you will need to define it as a global constant in your test environment.

invariant

Replaces

invariant(condition, 'error message here');

with

if (!condition) {
  if ('production' !== process.env.NODE_ENV) {
    invariant(false, 'error message here');
  } else {
    invariant(false);
  }
}

Note: TSDX doesn't supply an invariant function for you, you need to import one yourself. We recommend https://github.com/alexreardon/tiny-invariant.

To extract and minify invariant error codes in production into a static codes.json file, specify the --extractErrors flag in command line. For more details see Error extraction docs.

warning

Replaces

warning(condition, 'dev warning here');

with

if ('production' !== process.env.NODE_ENV) {
  warning(condition, 'dev warning here');
}

Note: TSDX doesn't supply a warning function for you, you need to import one yourself. We recommend https://github.com/alexreardon/tiny-warning.

Using lodash

If you want to use a lodash function in your package, TSDX will help you do it the right way so that your library does not get fat shamed on Twitter. However, before you continue, seriously consider rolling whatever function you are about to use on your own. Anyways, here is how to do it right.

First, install lodash and lodash-es as dependencies

yarn add lodash lodash-es

Now install @types/lodash to your development dependencies.

yarn add @types/lodash --dev

Import your lodash method however you want, TSDX will optimize it like so.

// ./src/index.ts
import kebabCase from 'lodash/kebabCase';

export const KebabLogger = (msg: string) => {
  console.log(kebabCase(msg));
};

For brevity let's look at the ES module output.

import o from"lodash-es/kebabCase";const e=e=>{console.log(o(e))};export{e as KebabLogger};
//# sourceMappingURL=test-react-tsdx.esm.production.js.map

TSDX will rewrite your import kebabCase from 'lodash/kebabCase' to import o from 'lodash-es/kebabCase'. This allows your library to be treeshakable to end consumers while allowing to you to use @types/lodash for free.

Note: TSDX will also transform destructured imports. For example, import { kebabCase } from 'lodash' would have also been transformed to `import o from "lodash-es/kebabCase".

Error extraction

After running --extractErrors, you will have a ./errors/codes.json file with all your extracted invariant error codes. This process scans your production code and swaps out your invariant error message strings for a corresponding error code (just like React!). This extraction only works if your error checking/warning is done by a function called invariant.

Note: We don't provide this function for you, it is up to you how you want it to behave. For example, you can use either tiny-invariant or tiny-warning, but you must then import the module as a variable called invariant and it should have the same type signature.

⚠️Don't forget: you will need to host the decoder somewhere. Once you have a URL, look at ./errors/ErrorProd.js and replace the reactjs.org URL with yours.

Known issue: our transformErrorMessages babel plugin currently doesn't have sourcemap support, so you will see "Sourcemap is likely to be incorrect" warnings. We would love your help on this.

TODO: Simple guide to host error codes to be completed

Customization

Rollup

❗⚠️❗ Warning
These modifications will override the default behavior and configuration of TSDX. As such they can invalidate internal guarantees and assumptions. These types of changes can break internal behavior and can be very fragile against updates. Use with discretion!

TSDX uses Rollup under the hood. The defaults are solid for most packages (Formik uses the defaults!). However, if you do wish to alter the rollup configuration, you can do so by creating a file called tsdx.config.js at the root of your project like so:

// Not transpiled with TypeScript or Babel, so use plain Es6/Node.js!
module.exports = {
  // This function will run for each entry/format/env combination
  rollup(config, options) {
    return config; // always return a config.
  },
};

The options object contains the following:

export interface TsdxOptions {
  // path to file
  input: string;
  // Name of package
  name: string;
  // JS target
  target: 'node' | 'browser';
  // Module format
  format: 'cjs' | 'umd' | 'esm' | 'system';
  // Environment
  env: 'development' | 'production';
  // Path to tsconfig file
  tsconfig?: string;
  // Is error extraction running?
  extractErrors?: boolean;
  // Is minifying?
  minify?: boolean;
  // Is this the very first rollup config (and thus should one-off metadata be extracted)?
  writeMeta?: boolean;
  // Only transpile, do not type check (makes compilation faster)
  transpileOnly?: boolean;
}

Example: Adding Postcss

const postcss = require('rollup-plugin-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');

module.exports = {
  rollup(config, options) {
    config.plugins.push(
      postcss({
        plugins: [
          autoprefixer(),
          cssnano({
            preset: 'default',
          }),
        ],
        inject: false,
        // only write out CSS for the first bundle (avoids pointless extra files):
        extract: !!options.writeMeta,
      })
    );
    return config;
  },
};

Babel

You can add your own .babelrc to the root of your project and TSDX will merge it with its own Babel transforms (which are mostly for optimization), putting any new presets and plugins at the end of its list.

Jest

You can add your own jest.config.js to the root of your project and TSDX will shallow merge it with its own Jest config.

ESLint

You can add your own .eslintrc.js to the root of your project and TSDX will deep merge it with its own ESLint config.

patch-package

If you still need more customizations, we recommend using patch-package so you don't need to fork. Keep in mind that these types of changes may be quite fragile against version updates.

Inspiration

TSDX was originally ripped out of Formik's build tooling. TSDX has several similarities to @developit/microbundle, but that is because Formik's Rollup configuration and Microbundle's internals had converged around similar plugins.

Comparison with Microbundle

Some key differences include:

  • TSDX includes out-of-the-box test running via Jest
  • TSDX includes out-of-the-box linting and formatting via ESLint and Prettier
  • TSDX includes a bootstrap command with a few package templates
  • TSDX allows for some lightweight customization
  • TSDX is TypeScript focused, but also supports plain JavaScript
  • TSDX outputs distinct development and production builds (like React does) for CJS and UMD builds. This means you can include rich error messages and other dev-friendly goodies without sacrificing final bundle size.

API Reference

tsdx watch

Description
  Rebuilds on any change

Usage
  $ tsdx watch [options]

Options
  -i, --entry           Entry module
  --target              Specify your target environment  (default web)
  --name                Specify name exposed in UMD builds
  --format              Specify module format(s)  (default cjs,esm)
  --tsconfig            Specify your custom tsconfig path (default <root-folder>/tsconfig.json)
  --verbose             Keep outdated console output in watch mode instead of clearing the screen
  --onFirstSuccess      Run a command on the first successful build
  --onSuccess           Run a command on a successful build
  --onFailure           Run a command on a failed build
  --noClean             Don't clean the dist folder
  --transpileOnly       Skip type checking
  -h, --help            Displays this message

Examples
  $ tsdx watch --entry src/foo.tsx
  $ tsdx watch --target node
  $ tsdx watch --name Foo
  $ tsdx watch --format cjs,esm,umd
  $ tsdx watch --tsconfig ./tsconfig.foo.json
  $ tsdx watch --noClean
  $ tsdx watch --onFirstSuccess "echo The first successful build!"
  $ tsdx watch --onSuccess "echo Successful build!"
  $ tsdx watch --onFailure "echo The build failed!"
  $ tsdx watch --transpileOnly

tsdx build

Description
  Build your project once and exit

Usage
  $ tsdx build [options]

Options
  -i, --entry           Entry module
  --target              Specify your target environment  (default web)
  --name                Specify name exposed in UMD builds
  --format              Specify module format(s)  (default cjs,esm)
  --extractErrors       Opt-in to extracting invariant error codes
  --tsconfig            Specify your custom tsconfig path (default <root-folder>/tsconfig.json)
  --transpileOnly       Skip type checking
  -h, --help            Displays this message

Examples
  $ tsdx build --entry src/foo.tsx
  $ tsdx build --target node
  $ tsdx build --name Foo
  $ tsdx build --format cjs,esm,umd
  $ tsdx build --extractErrors
  $ tsdx build --tsconfig ./tsconfig.foo.json
  $ tsdx build --transpileOnly

tsdx test

This runs Jest, forwarding all CLI flags to it. See https://jestjs.io for options. For example, if you would like to run in watch mode, you can run tsdx test --watch. So you could set up your package.json scripts like:

{
  "scripts": {
    "test": "tsdx test",
    "test:watch": "tsdx test --watch",
    "test:coverage": "tsdx test --coverage"
  }
}

tsdx lint

Description
  Run eslint with Prettier

Usage
  $ tsdx lint [options]

Options
  --fix               Fixes fixable errors and warnings
  --ignore-pattern    Ignore a pattern
  --max-warnings      Exits with non-zero error code if number of warnings exceed this number  (default Infinity)
  --write-file        Write the config file locally
  --report-file       Write JSON report to file locally
  -h, --help          Displays this message

Examples
  $ tsdx lint src
  $ tsdx lint src --fix
  $ tsdx lint src test --ignore-pattern test/foo.ts
  $ tsdx lint src test --max-warnings 10
  $ tsdx lint src --write-file
  $ tsdx lint src --report-file report.json

Contributing

Please see the Contributing Guidelines.

Download Details:

Author: jaredpalmer
Source Code: https://github.com/jaredpalmer/tsdx 
License: MIT license

#typescript #react #npm #rollup 

TSdx: Zero-config CLI for TypeScript Package Development
Daron  Moore

Daron Moore

1657832400

TypeScript, React, Rollup, and Chrome V3 Manifest Starter

This is a bare bones starter for building React/Typescript extensions for Chrome using manifest_version: 3.

Under the hood, this starter leans pretty heavily on the infrastructure from Extend Chrome. The primary difference is this starter integrates some foundational code and manifest configuration for v3 which I couldn't find in the boilerplate examples they offer.

Notes

In my tinkering with this starter there are a few notes that I find helpful.

1. Manually bundle files

If you reference files that can't be automatically recognized, use the web_accessible_resources property in manifest to explicitly bundle them.

"web_accessible_resources": [
    {
      "resources": [
        "pages/popup/index.html",
        "pages/popup/App.tsx",
        "pages/popup/index.tsx"
      ],
      "matches": [
        "<all_urls>"
      ]
    }
  ]

2. Split v2 and v3 manifests

Though a little hacky, I have had some success generating v2 and v3 manifests with a little customization to this starter. The approach can be seen on my extension Link Roamer.

The premise is pretty simple: hook into a specific string value throughout your app and programmatically fire v2 or v3 API methods depending on the build environment.

In this way, functions can be conditionally compiled.

if ('isV3Manifest') {
  return (
    await chrome.scripting.executeScript({
      target: { tabId },
      func,
    })
  )[0].result
} else {
  return (
    await browser.tabs.executeScript(tabId, {
      code: `(${func})()`,
    })
  )[0]
}

Development

For development with automatic reloading:

npm run start

Open the Extensions Dashboard, enable "Developer mode", click "Load unpacked", and choose the dist folder.

When you make changes in src the background script and any content script will reload automatically.

Production

When it's time to publish your Chrome extension, make a production build to submit to the Chrome Web Store. This boilerplate will use the version in package.json, unless you add a version to src/manifest.json.

Make sure you have updated the name and version of your extension in package.json.

Run the following line:

yarn build

This will create a ZIP file with your package name and version in the releases folder.


More apps by me

I like making things. Check out what I'm up to lately.


Author: rossmoody
Source code: https://github.com/rossmoody/ts-extension-starter
License: MIT license

#react-native #typescript #rollup 

TypeScript, React, Rollup, and Chrome V3 Manifest Starter
Ella  Windler

Ella Windler

1657141200

Rollup Plugin Css Only: Rollup Plugin That Bundles Imported Css

Rollup plugin that bundles imported css

Installation

npm install --save-dev rollup-plugin-css-only

# If using Node.js lower than 10.12
npm install --save-dev rollup-plugin-css-only@1

Usage

// rollup.config.js
import css from 'rollup-plugin-css-only'

export default {
  entry: 'entry.js',
  dest: 'bundle.js',
  plugins: [
    css({ output: 'bundle.css' })
  ]
}
// entry.js
import './reset.css'
import './layout.css'

import Vue from 'vue'

Options

The idea is to keep the options similar to rollup-plugin-sass.

There is 1 option: output. By default the plugin will base the filename for the css on the bundle destination.

css({
  // Filename to write all styles to
  output: 'bundle.css',

  // Callback that will be called ongenerate with two arguments:
  // - styles: the contents of all style tags combined: 'body { color: green }'
  // - styleNodes: an array of style objects: [{lang: 'css', content: 'body { color: green }'}]
  output: function (styles, styleNodes) {
    writeFileSync('bundle.css', styles)
  },

  // Disable any style output or callbacks
  output: false,

  // Default behaviour is to write all styles to the bundle destination where .js is replaced by .css
  output: null
})

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Contributions and feedback are very welcome.

To get it running:

  1. Clone the project.
  2. npm install
  3. npm run build

Credits


Author:  thgh
Source code: https://github.com/thgh/rollup-plugin-css-only
License: MIT license

#css #rollup  #javascript  

Rollup Plugin Css Only: Rollup Plugin That Bundles Imported Css
Kevon  Krajcik

Kevon Krajcik

1657040400

Rollup Plugin Buble: Compile ES2015 with Buble in Vite

@rollup/plugin-buble

🍣 A Rollup plugin which converts ES2015+ code with the Bublé compiler.

Requirements

This plugin requires an LTS Node version (v8.0.0+) and Rollup v1.20.0+.

Install

Using npm:

npm install @rollup/plugin-buble --save-dev

Usage

Create a rollup.config.js configuration file and import the plugin:

import buble from '@rollup/plugin-buble';

export default {
  input: 'src/index.js',
  output: {
    dir: 'output',
    format: 'cjs'
  },
  plugins: [buble()]
};

Then call rollup either via the CLI or the API.

Options

transforms

Type: Object
Default: { modules: false }

Specifies additional transform options for the Bublé compiler.

exclude

Type: String | Array[...String]
Default: null

A minimatch pattern, or array of patterns, which specifies the files in the build the plugin should ignore. By default no files are ignored.

include

Type: String | Array[...String]
Default: null

A minimatch pattern, or array of patterns, which specifies the files in the build the plugin should operate on. By default all files are targeted.

Meta

CONTRIBUTING

LICENSE (MIT)


Author: 
Source Code: https://github.com/rollup/plugins/
License: 
#vite #typescript #javascript #rollup 

Rollup Plugin Buble: Compile ES2015 with Buble in Vite
Kevon  Krajcik

Kevon Krajcik

1657029600

Rollup Plugin Babel: Compile Your Files with Babel With Vite

@rollup/plugin-babel

🍣 A Rollup plugin for seamless integration between Rollup and Babel.

Why?

If you're using Babel to transpile your ES6/7 code and Rollup to generate a standalone bundle, you have a couple of options:

  • run the code through Babel first, being careful to exclude the module transformer, or
  • run the code through Rollup first, and then pass it to Babel.

Both approaches have disadvantages – in the first case, on top of the additional configuration complexity, you may end up with Babel's helpers (like classCallCheck) repeated throughout your code (once for each module where the helpers are used). In the second case, transpiling is likely to be slower, because transpiling a large bundle is much more work for Babel than transpiling a set of small files.

Either way, you have to worry about a place to put the intermediate files, and getting sourcemaps to behave becomes a royal pain.

Using Rollup with @rollup/plugin-babel makes the process far easier.

Requirements

This plugin requires an LTS Node version (v10.0.0+) and Rollup v1.20.0+.

Install

npm install @rollup/plugin-babel --save-dev

Usage

Create a rollup.config.js configuration file and import the plugin:

import { babel } from '@rollup/plugin-babel';

const config = {
  input: 'src/index.js',
  output: {
    dir: 'output',
    format: 'esm'
  },
  plugins: [babel({ babelHelpers: 'bundled' })]
};

export default config;

Then call rollup either via the CLI or the API.

Using With @rollup/plugin-commonjs

When using @rollup/plugin-babel with @rollup/plugin-commonjs in the same Rollup configuration, it's important to note that @rollup/plugin-commonjs must be placed before this plugin in the plugins array for the two to work together properly. e.g.

import { babel } from '@rollup/plugin-babel';
import commonjs from '@rollup/plugin-commonjs';

const config = {
  ...
  plugins: [
    commonjs(),
    babel({ babelHelpers: 'bundled' })
  ],
};

Options

This plugin respects Babel configuration files by default and they are generally the best place to put your configuration.

You can also run Babel on the generated chunks instead of the input files. Even though this is slower, it is the only way to transpile Rollup's auto-generated wrapper code to lower compatibility targets than ES5, see Running Babel on the generated code for details.

All options are as per the Babel documentation, plus the following:

exclude

Type: String | RegExp | Array[...String|RegExp]
 

A minimatch pattern, or array of patterns, which specifies the files in the build the plugin should ignore. When relying on Babel configuration files you can only exclude additional files with this option, you cannot override what you have configured for Babel itself.

include

Type: String | RegExp | Array[...String|RegExp]
 

A minimatch pattern, or array of patterns, which specifies the files in the build the plugin should operate on. When relying on Babel configuration files you cannot include files already excluded there.

filter

Type: (id: string) => boolean
 

Custom filter function can be used to determine whether or not certain modules should be operated upon.

Usage:

import { createFilter } from '@rollup/pluginutils';
const include = 'include/**.js';
const exclude = 'exclude/**.js';
const filter = createFilter(include, exclude, {});

extensions

Type: Array[...String]
Default: ['.js', '.jsx', '.es6', '.es', '.mjs']

An array of file extensions that Babel should transpile. If you want to transpile TypeScript files with this plugin it's essential to include .ts and .tsx in this option.

babelHelpers

Type: 'bundled' | 'runtime' | 'inline' | 'external'
Default: 'bundled'

It is recommended to configure this option explicitly (even if with its default value) so an informed decision is taken on how those babel helpers are inserted into the code.

We recommend to follow these guidelines to determine the most appropriate value for your project:

  • 'runtime' - you should use this especially when building libraries with Rollup. It has to be used in combination with @babel/plugin-transform-runtime and you should also specify @babel/runtime as dependency of your package. Don't forget to tell Rollup to treat the helpers imported from within the @babel/runtime module as external dependencies when bundling for cjs & es formats. This can be accomplished via regex (external: [/@babel\/runtime/]) or a function (external: id => id.includes('@babel/runtime')). It's important to not only specify external: ['@babel/runtime'] since the helpers are imported from nested paths (e.g @babel/runtime/helpers/get) and Rollup will only exclude modules that match strings exactly.
  • 'bundled' - you should use this if you want your resulting bundle to contain those helpers (at most one copy of each). Useful especially if you bundle an application code.
  • 'external' - use this only if you know what you are doing. It will reference helpers on global babelHelpers object. Used in combination with @babel/plugin-external-helpers.
  • 'inline' - this is not recommended. Helpers will be inserted in each file using this option. This can cause serious code duplication. This is the default Babel behavior as Babel operates on isolated files - however, as Rollup is a bundler and is project-aware (and therefore likely operating across multiple input files), the default of this plugin is "bundled".

skipPreflightCheck

Type: Boolean
Default: false

Before transpiling your input files this plugin also transpile a short piece of code for each input file. This is used to validate some misconfiguration errors, but for sufficiently big projects it can slow your build times so if you are confident about your configuration then you might disable those checks with this option.

External dependencies

Ideally, you should only be transforming your source code, rather than running all of your external dependencies through Babel (to ignore external dependencies from being handled by this plugin you might use exclude: 'node_modules/**' option). If you have a dependency that exposes untranspiled ES6 source code that doesn't run in your target environment, then you may need to break this rule, but it often causes problems with unusual .babelrc files or mismatched versions of Babel.

We encourage library authors not to distribute code that uses untranspiled ES6 features (other than modules) for this reason. Consumers of your library should not have to transpile your ES6 code, any more than they should have to transpile your CoffeeScript, ClojureScript or TypeScript.

Use babelrc: false to prevent Babel from using local (i.e. to your external dependencies) .babelrc files, relying instead on the configuration you pass in.

Helpers

In some cases Babel uses helpers to avoid repeating chunks of code – for example, if you use the class keyword, it will use a classCallCheck function to ensure that the class is instantiated correctly.

By default, those helpers will be inserted at the top of the file being transformed, which can lead to duplication. This rollup plugin automatically deduplicates those helpers, keeping only one copy of each one used in the output bundle. Rollup will combine the helpers in a single block at the top of your bundle.

You can customize how those helpers are being inserted into the transformed file with babelHelpers option.

Modules

This is not needed since Babel 7 - it knows automatically that Rollup understands ES modules & that it shouldn't use any module transform with it. Unless you forcefully include a module transform in your Babel configuration.

If you have been pointed to this section by an error thrown by this plugin, please check your Babel configuration files and disable any module transforms when running Rollup builds.

Running Babel on the generated code

You can run @rollup/plugin-babel on the output files instead of the input files by using getBabelOutputPlugin(...). This can be used to perform code transformations on the resulting chunks and is the only way to transform Rollup's auto-generated code. By default, the plugin will be applied to all outputs:

// rollup.config.js
import { getBabelOutputPlugin } from '@rollup/plugin-babel';

export default {
  input: 'main.js',
  plugins: [
    getBabelOutputPlugin({
      presets: ['@babel/preset-env']
    })
  ],
  output: [
    { file: 'bundle.cjs.js', format: 'cjs' },
    { file: 'bundle.esm.js', format: 'esm' }
  ]
};

If you only want to apply it to specific outputs, you can use it as an output plugin (requires at least Rollup v1.27.0):

// rollup.config.js
import { getBabelOutputPlugin } from '@rollup/plugin-babel';

export default {
  input: 'main.js',
  output: [
    { file: 'bundle.js', format: 'esm' },
    {
      file: 'bundle.es5.js',
      format: 'esm',
      plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] })]
    }
  ]
};

The include, exclude and extensions options are ignored when the when using getBabelOutputPlugin and createBabelOutputPluginFactory will produce warnings, and there are a few more points to note that users should be aware of.

You can also run the plugin twice on the code, once when processing the input files to transpile special syntax to JavaScript and once on the output to transpile to a lower compatibility target:

// rollup.config.js
import babel, { getBabelOutputPlugin } from '@rollup/plugin-babel';

export default {
  input: 'main.js',
  plugins: [babel({ presets: ['@babel/preset-react'] })],
  output: [
    {
      file: 'bundle.js',
      format: 'esm',
      plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] })]
    }
  ]
};

Babel configuration files

Unlike the regular babel plugin, getBabelOutputPlugin(...) will not automatically search for Babel configuration files. Besides passing in Babel options directly, however, you can specify a configuration file manually via Babel's configFile option:

getBabelOutputPlugin({
  configFile: path.resolve(__dirname, 'babel.config.js')
});

Using formats other than ES modules or CommonJS

As getBabelOutputPlugin(...) will run after Rollup has done all its transformations, it needs to make sure it preserves the semantics of Rollup's output format. This is especially important for Babel plugins that add, modify or remove imports or exports, but also for other transformations that add new variables as they can accidentally become global variables depending on the format. Therefore it is recommended that for formats other than esm or cjs, you set Rollup to use the esm output format and let Babel handle the transformation to another format, e.g. via

presets: [['@babel/preset-env', { modules: 'umd' }], ...]

to create a UMD/IIFE compatible output. If you want to use getBabelOutputPlugin(...) with other formats, you need to specify allowAllFormats: true as plugin option:

rollup.rollup({...})
.then(bundle => bundle.generate({
  format: 'iife',
  plugins: [getBabelOutputPlugin({
    allowAllFormats: true,
    // ...
  })]
}))

Injected helpers

By default, helpers e.g. when transpiling classes will be inserted at the top of each chunk. In contrast to when applying this plugin on the input files, helpers will not be deduplicated across chunks.

Alternatively, you can use imported runtime helpers by adding the @babel/transform-runtime plugin. This will make @babel/runtime an external dependency of your project, see @babel/plugin-transform-runtime for details.

Note that this will only work for esm and cjs formats, and you need to make sure to set the useESModules option of @babel/plugin-transform-runtime to true if you create ESM output:

rollup.rollup({...})
.then(bundle => bundle.generate({
  format: 'esm',
  plugins: [getBabelOutputPlugin({
    presets: ['@babel/preset-env'],
    plugins: [['@babel/plugin-transform-runtime', { useESModules: true }]]
  })]
}))
// input
export default class Foo {}

// output
import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';

var Foo = function Foo() {
  _classCallCheck(this, Foo);
};

export default Foo;

And for CommonJS:

rollup.rollup({...})
.then(bundle => bundle.generate({
  format: 'cjs',
  plugins: [getBabelOutputPlugin({
    presets: ['@babel/preset-env'],
    plugins: [['@babel/plugin-transform-runtime', { useESModules: false }]]
  })]
}))
// input
export default class Foo {}

// output
('use strict');

var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');

var Foo = function Foo() {
  _classCallCheck(this, Foo);
};

module.exports = Foo;

Another option is to use @babel/plugin-external-helpers, which will reference the global babelHelpers object. It is your responsibility to make sure this global variable exists.

Custom plugin builder

@rollup/plugin-babel exposes a plugin-builder utility that allows users to add custom handling of Babel's configuration for each file that it processes.

createBabelInputPluginFactory accepts a callback that will be called with the loader's instance of babel so that tooling can ensure that it using exactly the same @babel/core instance as the loader itself.

It's main purpose is to allow other tools for configuration of transpilation without forcing people to add extra configuration but still allow for using their own babelrc / babel config files.

Example

import { createBabelInputPluginFactory } from '@rollup/plugin-babel';

export default createBabelInputPluginFactory((babelCore) => {
  function myPlugin() {
    return {
      visitor: {}
    };
  }

  return {
    // Passed the plugin options.
    options({ opt1, opt2, ...pluginOptions }) {
      return {
        // Pull out any custom options that the plugin might have.
        customOptions: { opt1, opt2 },

        // Pass the options back with the two custom options removed.
        pluginOptions
      };
    },

    config(cfg /* Passed Babel's 'PartialConfig' object. */, { code, customOptions }) {
      if (cfg.hasFilesystemConfig()) {
        // Use the normal config
        return cfg.options;
      }

      return {
        ...cfg.options,
        plugins: [
          ...(cfg.options.plugins || []),

          // Include a custom plugin in the options.
          myPlugin
        ]
      };
    },

    result(result, { code, customOptions, config, transformOptions }) {
      return {
        ...result,
        code: result.code + '\n// Generated by some custom plugin'
      };
    }
  };
});

Meta

CONTRIBUTING

LICENSE (MIT)


Author: 
Source Code: https://github.com/rollup/plugins/
License: 

#vite #rollup #typescript #javascript

Rollup Plugin Babel: Compile Your Files with Babel With Vite
Kevon  Krajcik

Kevon Krajcik

1657008000

A Rollup Plugin to Support Variables in Dynamic Imports In Rollup

@rollup/plugin-dynamic-import-vars

🍣 A rollup plugin to support variables in dynamic imports in Rollup.

function importLocale(locale) {
  return import(`./locales/${locale}.js`);
}

Requirements

This plugin requires an LTS Node version (v10.0.0+) and Rollup v1.20.0+.

Install

Using npm:

npm install @rollup/plugin-dynamic-import-vars --save-dev

Usage

Create a rollup.config.js configuration file and import the plugin:

import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';

export default {
  plugins: [
    dynamicImportVars({
      // options
    })
  ]
};

Options

include

Type: String | Array[...String]
Default: []

Files to include in this plugin (default all).

exclude

Type: String | Array[...String]
Default: []

Files to exclude in this plugin (default none).

warnOnError

Type: Boolean
Default: false

By default, the plugin quits the build process when it encounters an error. If you set this option to true, it will throw a warning instead and leave the code untouched.

How it works

When a dynamic import contains a concatenated string, the variables of the string are replaced with a glob pattern. This glob pattern is evaluated during the build, and any files found are added to the rollup bundle. At runtime, the correct import is returned for the full concatenated string.

Some example patterns and the glob they produce:

`./locales/${locale}.js` -> './locales/*.js'
`./${folder}/${name}.js` -> './*/*.js'
`./module-${name}.js` -> './module-*.js'
`./modules-${name}/index.js` -> './modules-*/index.js'
'./locales/' + locale + '.js' -> './locales/*.js'
'./locales/' + locale + foo + bar '.js' -> './locales/*.js'
'./locales/' + `${locale}.js` -> './locales/*.js'
'./locales/' + `${foo + bar}.js` -> './locales/*.js'
'./locales/'.concat(locale, '.js') -> './locales/*.js'
'./'.concat(folder, '/').concat(name, '.js') -> './*/*.js'

Code that looks like this:

function importLocale(locale) {
  return import(`./locales/${locale}.js`);
}

Is turned into:

function __variableDynamicImportRuntime__(path) {
  switch (path) {
    case './locales/en-GB.js':
      return import('./locales/en-GB.js');
    case './locales/en-US.js':
      return import('./locales/en-US.js');
    case './locales/nl-NL.js':
      return import('./locales/nl-NL.js');
    default:
      return new Promise(function (resolve, reject) {
        queueMicrotask(reject.bind(null, new Error('Unknown variable dynamic import: ' + path)));
      });
  }
}

function importLocale(locale) {
  return __variableDynamicImportRuntime__(`./locales/${locale}.js`);
}

Limitations

To know what to inject in the rollup bundle, we have to be able to do some static analysis on the code and make some assumptions about the possible imports. For example, if you use just a variable you could in theory import anything from your entire file system.

function importModule(path) {
  // who knows what will be imported here?
  return import(path);
}

To help static analysis, and to avoid possible foot guns, we are limited to a couple of rules:

Imports must start with ./ or ../.

All imports must start relative to the importing file. The import should not start with a variable, an absolute path or a bare import:

// Not allowed
import(bar);
import(`${bar}.js`);
import(`/foo/${bar}.js`);
import(`some-library/${bar}.js`);

Imports must end with a file extension

A folder may contain files you don't intend to import. We, therefore, require imports to end with a file extension in the static parts of the import.

// Not allowed
import(`./foo/${bar}`);
// allowed
import(`./foo/${bar}.js`);

Imports to your own directory must specify a filename pattern

If you import your own directory you likely end up with files you did not intend to import, including your own module. It is therefore required to give a more specific filename pattern:

// not allowed
import(`./${foo}.js`);
// allowed
import(`./module-${foo}.js`);

Globs only go one level deep

When generating globs, each variable in the string is converted to a glob * with a maximum of one star per directory depth. This avoids unintentionally adding files from many directories to your import.

In the example below this generates ./foo/*/*.js and not ./foo/**/*.js.

import(`./foo/${x}${y}/${z}.js`);

Meta

CONTRIBUTING

LICENSE (MIT)


Author: rollup
Source Code:  https://github.com/rollup/plugins/
License: 

#rollup #vite #typescript #javascript

 A Rollup Plugin to Support Variables in Dynamic Imports In Rollup
Ella  Windler

Ella Windler

1656993600

Rollup Plugin Sizes: Display Bundle Content and Size in The Console

rollup-plugin-sizes   

Simple analysis on rollup bundling, helping you to spot libaries bloating up your bundles.

/src/index.js:
codemirror - 446.92 KB (35.94%)
remarkable - 193.72 KB (15.58%)
app - 95.87 KB (7.71%)
autolinker - 81.64 KB (6.57%)
lodash.filter - 62.77 KB (5.05%)
...

or with way more details!

/src/index.js:
codemirror - 446.92 KB (35.94%)
        lib\codemirror.js - 347.8 KB (77.82%)
        mode\javascript\javascript.js - 27.78 KB (6.22%)
        mode\markdown\markdown.js - 25.54 KB (5.72%)
        mode\meta.js - 14.44 KB (3.23%)
        mode\xml\xml.js - 12.52 KB (2.80%)
        addon\edit\closebrackets.js - 7.04 KB (1.58%)
        addon\edit\matchbrackets.js - 5.39 KB (1.21%)
        addon\comment\continuecomment.js - 3.59 KB (0.80%)
        addon\selection\active-line.js - 2.82 KB (0.63%)
remarkable - 193.72 KB (15.58%)
        lib\common\entities.js - 46.44 KB (23.97%)
        lib\rules.js - 10.2 KB (5.26%)
        lib\rules_block\list.js - 6.65 KB (3.43%)
        lib\ruler.js - 5.44 KB (2.81%)
        lib\rules_block\deflist.js - 5.22 KB (2.69%)
...

Install

$ npm i rollup-plugin-sizes -D

Usage

Add to your rollup build as the last plugin via JS API or Config file.

JS API

var rollup = require("rollup"),

    buble = require("rollup-plugin-buble"),
    sizes = require("rollup-plugin-sizes");

rollup.rollup({
    entry   : "src/main.js",
    plugins : [
        buble(),
        sizes()
    ]
}).then(function(bundle) {
    ...
});

Config file

import buble from 'rollup-plugin-buble';
import sizes from 'rollup-plugin-sizes';

export default {
    ...
    plugins : [
        buble(),
        sizes()
    ]
};

Options

details - Set to true to enable file-by-file breakdowns of space usage.

report - Customize reporting. See source code for the default reporter.


Author: tivac
Source code: https://github.com/tivac/rollup-plugin-sizes\
License: MIT license

#javascript  #rollup 

Rollup Plugin Sizes: Display Bundle Content and Size in The Console
Ella  Windler

Ella Windler

1656982800

Rollup Plugin Serve: Rollup Plugin to Serve The Bundle

Rollup plugin to serve the bundle

Installation

npm install --save-dev rollup-plugin-serve

yarn add rollup-plugin-serve

Usage

// rollup.config.js
import serve from 'rollup-plugin-serve'

export default {
  input: 'src/main.js',
  output: {
    file: 'dist/bundle.js',
    format: ...
  },
  plugins: [
    serve('dist')
  ]
}

Options

By default it serves the current project folder. Change it by passing a string:

serve('public')    // will be used as contentBase

// Default options
serve({
  // Launch in browser (default: false)
  open: true,

  // Page to navigate to when opening the browser.
  // Will not do anything if open=false.
  // Remember to start with a slash.
  openPage: '/different/page',

  // Show server address in console (default: true)
  verbose: false,

  // Folder to serve files from
  contentBase: '',

  // Multiple folders to serve from
  contentBase: ['dist', 'static'],

  // Set to true to return index.html (200) instead of error page (404)
  historyApiFallback: false,

  // Path to fallback page
  historyApiFallback: '/200.html',

  // Options used in setting up server
  host: 'localhost',
  port: 10001,

  // By default server will be served over HTTP (https: false). It can optionally be served over HTTPS
  https: {
    key: fs.readFileSync('/path/to/server.key'),
    cert: fs.readFileSync('/path/to/server.crt'),
    ca: fs.readFileSync('/path/to/ca.pem')
  },

  //set headers
  headers: {
    'Access-Control-Allow-Origin': '*',
    foo: 'bar'
  },

  // set custom mime types, usage https://github.com/broofa/mime#mimedefinetypemap-force--false
  mimeTypes: {
    'application/javascript': ['js_commonjs-proxy']
  }

  // execute function after server has begun listening
  onListening: function (server) {
    const address = server.address()
    const host = address.address === '::' ? 'localhost' : address.address
    // by using a bound function, we can access options as `this`
    const protocol = this.https ? 'https' : 'http'
    console.log(`Server listening at ${protocol}://${host}:${address.port}/`)
  }
})

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Contributions and feedback are very welcome.

This project aims to stay lean and close to standards. New features should encourage to stick to standards. Options that match the behaviour of webpack-dev-server are always ok.

To get it running:

  1. Clone the project.
  2. npm install
  3. npm run build

Credits


Author: thgh
Source code: https://github.com/thgh/rollup-plugin-serve
License: MIT license

#rollup  #javascript 

Rollup Plugin Serve: Rollup Plugin to Serve The Bundle
Ella  Windler

Ella Windler

1656950400

Rollup Plugin Notify: Displays Rollup Errors As System Notifications

rollup-plugin-notify

📟 Displays rollup errors as system notifications.

Example

Installation

npm install --save-dev rollup-plugin-notify

Usage

Pretty simple, no settings, no options, just import the notify() function and add it to your rollup config file. Then you can start rollup in an endless watch mode rollup -c -w and minimize the terminal because all incoming errors will be caught and shown as notifications!

Rollup v0.60.0 or higher is required

// rollup.config.js
import notify from 'rollup-plugin-notify';

export default {
  // ...
  plugins: [
    notify()
  ]
};

Check out ./example folder for demo app.

Displayed information

We try to fit as much of useful information (file, code snippet, position) as possible in the little space of 4-line notification. But it is hard to test this module for all the plugins out there, each of which can and will throw different errors of various shapes.

Basic Rollup's parse errors and Babel plugin work great out of the box. If you feel like rollup-plugin-notify could display better errors for your favorite Rollup plugin, let us know, or better yet, hit us up with a PR.

Contributing

Contributions, help and feedback is welcome. Underlying node-notifier module is troublesome and difficult to test across platforms so testing and troubleshooting on other systems would be appreciated.


Author: MikeKovarik
Source code: https://github.com/MikeKovarik/rollup-plugin-notify
License: MIT license

#rollup #javascript 

Rollup Plugin Notify: Displays Rollup Errors As System Notifications
Hermann  Frami

Hermann Frami

1654323025

Serverless Externals Plugin

Serverless Externals Plugin

Only include listed node_modules and their dependencies in Serverless.

This plugin helps Serverless package only external modules, and Rollup bundle all the other modules.

Image

Installation

npm install serverless-externals-plugin

or

yarn add serverless-externals-plugin

serverless.yml:

plugins:
  - serverless-externals-plugin

package:
  individually: true

functions:
  handler:
    handler: dist/bundle.handler
    externals:
      report: dist/node-externals-report.json
    package:
      patterns:
        - "!./**"
        - ./dist/bundle.js

rollup.config.js:

import { rollupPlugin as externals } from "serverless-externals-plugin";

export default {
  ...
  output: { file: "dist/bundle.js", format: "cjs" },
  treeshake: {
    moduleSideEffects: "no-external",
  },
  plugins: [
    externals(__dirname, { modules: ["pkg3"] }),
    commonjs(),
    nodeResolve({ preferBuiltins: true, exportConditions: ["node"] }),
    ...
  ],
}

Example

Externals Plugin interacts with both Serverless and with your bundler (Rollup).

Let's say you have two modules in your package.json, pkg2 and pkg3. pkg3 is a module with native binaries, so it can't be bundled.

root
+-- pkg3@2.0.0
+-- pkg2@0.0.1
    +-- pkg3@1.0.0

Because pkg3 can't be bundled, both ./node_modules/pkg3 and ./node_modules/pkg2/node_modules/pkg3 should be included in the bundle. pkg2 can just be bundled, but should import pkg3 as follows: require('pkg2/node_modules/pkg3'). It cannot just do require('pkg3') because pkg3 has a different version than pkg2/node_modules/pkg3.

In the Serverless package, only ./node_modules/pkg3/** and ./node_modules/pkg2/node_modules/pkg3/** should be included, all the other contents of node_modules are already bundled.

Externals Plugin provides a Serverless plugin and a Rollup plugin to support this.

There are other reasons modules can't be bundled. For example, readable-stream and sshpk cannot be bundled due to circular dependency errors.

Configuration

In rollup.config.js:

output: { file: "dist/bundle.js", format: "cjs" },
plugins: [
  externals(__dirname, { modules: ["aws-sdk"] }),
  ...
]

This will generate a file called node-externals-report.json next to bundle.js, with the module paths that should be packaged.

It can then be included in serverless.yml:

custom:
  externals:
    report: dist/node-externals-report.json

Configuration object

The configuration object has these options:

  • modules: string[]: a list of module names that should be kept external (default [])
  • report?: boolean | string: whether to generate a report or report path (default ${distPath}/node-externals-report.json)
  • packaging.exclude?: string[]: modules which shouldn't be packaged by Serverless (e.g. ['aws-sdk'], default [])
  • packaging.forceIncludeModuleRoots?: string[]: module roots that should always be packaged (e.g. ['node_modules/pg'], default [])
  • file?: string: path to a different configuration object

It's also possible to filter on module versions. (e.g. uuid@<8). This uses a semver range.

How it works

Externals Plugin uses Arborist by NPM to analyze the node_modules tree (using loadActual()).

Using the Externals configuration (a list of modules you want to keep external), the Plugin will then build a list of all dependencies that should be kept external. This list will contain the modules in the configuration and all the (non-dev) dependencies, recursively.

In the example, the list will contain both pkg2/node_modules/pkg3 and pkg3.

The Rollup Plugin will then generate a report (e.g. node-externals-report.json) which contains the modules that are actually imported. This file is then used by the Serverless Plugin to generate a list of include patterns.

Report

If you mark both aws-sdk and sshpk as external, but you don't use sshpk, the generated report will look as follows:

node-externals-report.json:

{
  "isReport": true,
  "importedModuleRoots": [
    "node_modules/aws-sdk"
  ],
  "config": {
    "modules": [
      "aws-sdk",
      "sshpk"
    ]
  }
}

Serverless can therefore ignore sshpk and all its dependencies, making the bundle even smaller.

The report is generated by analyzing the files Rollup emits (including dynamic imports).

Rollup Plugin

A fully configured rollup.config.js could look as follows:

import { rollupPlugin as externals } from "serverless-externals-plugin";
import commonjs from "@rollup/plugin-commonjs";
import nodeResolve from "@rollup/plugin-node-resolve";

/** @type {import('rollup').RollupOptions} */
const config = {
  input: "index.js",
  output: {
    file: "bundle.js",
    format: "cjs",
    exports: "default",
  },
  treeshake: {
    moduleSideEffects: "no-external",
  },
  plugins: [
    externals(__dirname, { modules: ["aws-sdk"] }),
    commonjs(),
    nodeResolve({ preferBuiltins: true, exportConditions: ["node"] }),
  ],
};

export default config;

Make sure externals comes before @rollup/plugin-commonjs and @rollup/plugin-node-resolve.

Make sure moduleSideEffects: "no-external" is set. By default, Rollup includes all external modules that appear in the code because they might contain side effects, even if they can be treeshaken. By setting this option Rollup will assume external modules have no side effects.

("no-external" is equivalent to (id, external) => !external)

Preferably, also set exportConditions: ["node"] as an option in the node-resolve plugin. This ensures that Rollup uses Node's resolution algorithm, so that packages like uuid can be bundled.

Implementation

The Rollup plugin provides a resolveId function to Rollup. For every import (e.g. require('pkg3')) in your source code, Rollup will ask the Externals Plugin whether the import is external, and where to find it.

The Plugin will look for the import in the Arborist graph, and if it's declared as being external it will return the full path to the module that's being imported (e.g. pkg2/node_modules/pkg3).

node-externals.json

It's also possible to add the externals config to a file, called node-externals.json.

In node-externals.json:

{
  "modules": [
    "pkg3"
  ]
}

In rollup.config.js:

plugins: [
  externals(__dirname, { file: 'node-externals.json' }),
  ...
]

Dynamic requires

If your code or one of your Node modules does the following:

require("p" + "g");
// or
import("p" + "g");

Then this plugin will not be able to detect which modules should be packaged. You can force include them by using packaging.forceIncludeModuleRoots:

...
packaging: {
  forceIncludeModuleRoots: ["node_modules/pg"]
}

The plugin will then treat node_modules/pg as if it was imported directly in the bundle. It will also include all the dependencies.

For example: in knex, an SQL builder, pg is a peer dependency. Inside knex it is imported as follows:

// knex/lib/index.js
const resolvedClientName = resolveClientNameWithAliases(clientName);
Dialect = require(`./dialects/${resolvedClientName}/index.js`);
// knex/lib/dialects/postgres/index.js
require('pg');

If you're using knex, you'd have to force include node_modules/pg. If you want to bundle knex, you would also have to enable ignoreDynamicImports in your rollup.config.js:

commonjs({ ignoreDynamicRequires: true }),

This will make sure the require call is not changed.

Another solution is to add knex to the list of externals. In that case the whole node_modules/knex folder will be uploaded, and none of its code will be transformed.

Caveats

Externals with side effects

It's unlikely, but if you have external modules with side effects (like polyfills), make sure to configure Rollup properly.

NOTE: This only applies to external modules. You should probably bundle your polyfills.

import "some-external-module"; // this doesn't work, Rollup will treeshake it away

As Rollup will remove external modules with side effects, make sure to add something like this to the Rollup config:

treeshake: {
  moduleSideEffects: (id, external) => !id.test(/some-external-module/) || !external
}

Only one node_modules supported

This plugin doesn't have support for analyzing multiple node_modules folders. If you have more node_modules folders on your NODE_PATH (e.g. from a Lambda layer), you can still use the external field of Rollup.

Keeping aws-sdk excluded

As the aws-sdk node module is included by default in Lambdas, you can add packaging.exclude: ["aws-sdk"] to exclude it from the Serverless package. Note that this is not recommended because of possible version differences. (Check the aws-sdk version included in runtimes here)

All subdependencies marked as external

When listing modules as external, all their subdependencies will also be marked as external.

For example:

// rollup.config.js
plugins: [
  externals(__dirname, { modules: ["botkit"] }),
  ...
]
// lambda.js
const express = require('express');
const serverlessHttp = require('serverless-http');
const app = express();

module.exports.handler = serverlessHttp(app);

In the resulting bundle, express will not be bundled. This is because botkit also depends on express, and is therefore marked as external. botkit itself and the rest of its subdependencies will be filtered out of the modules to be uploaded.

It is therefore recommended to limit the length of the modules array to only the necessary. In that way you can achieve the smallest bundles.

Todo

  • Ensure compatibility with Serverless Jetpack or speedup packaging somehow
  • Webpack plugin
  • Esbuild plugin
  • Layer support
  • Look into externalizing single files in a module (e.g. .node files), and bundling the rest
  • Yarn PnP support
  • Pre-calculate actually used top-level externals to solve last caveat

Motivation

I wanted to include Cheerio/JSDom and AWS SDK in a Typescript project, but neither could be bundled because of obscure errors, so they needed to be external. To reduce package size, I didn't want to make every module external. Manually looking up a module and adding its dependencies to rollup.config.js and serverless.yml is simply too much work. This plugin makes this much easier.

Credits

Some Serverless-handling code was taken from Serverless Jetpack. Also inspired by Serverless Plugin Include Dependencies and Webpack Node Externals

Author: Bubblydoo
Source Code: https://github.com/bubblydoo/serverless-externals-plugin 
License: MIT license

#serverless #plugin #rollup 

Serverless Externals Plugin
伊藤  直子

伊藤 直子

1654224300

Rollupを使用してTypeScriptおよびJavaScript用のライブラリをパッケージ化する

コードベースのクリーンアップは、信頼できるコードを作成するための基本的なステップです。同じコードを異なる技術プラットフォーム用にコンパイルする必要がある場合、このプロセスは特に複雑になる可能性があります。現代のウェブ開発はこの良い例です。

現在、単純なAPIを提供する単一のサーバーがある場合でも、数十の異なる小さな機能を処理できる可能性があります。これはすぐに混乱する可能性がありますが、幸いなことに、私たちの生活を楽にするプロセスとツールがあります。

この記事では、ロールアップの使用について説明します。Rollupは、新しいライブラリのすべての機能を1つのバンドルにまとめるプロセスを支援するように設計されたモジュールバンドラーです。

Rollupの背後にある考え方は、Rollupがバンドルを準備し、それをバックエンドアプリケーションのライブラリであろうとブラウザのモジュールであろうと、最も効率的な方法でラップする間、関数に集中できるようにすることで開発を簡素化することです。

ロールアップとは何ですか?

Rollupの公式ドキュメントによると、「RollupはJavaScriptのモジュールバンドラーであり、小さなコードをライブラリやアプリケーションなど、より大きく複雑なものにコンパイルします。」

これは、新しいライブラリを設計する際の興味深いスタンスであり、2000年代初頭に一般的だった長い設計セッションから一歩離れています。当時は、関数とオブジェクトを設計してから、それらを1つのモジュールにバンドルしていました。これにより、インターフェイスが均質化され、実行する場所またはプラットフォームに簡単に統合できるようになります。

Rollupを特別なものにしているのは、ファイルを小さく保つ機能です。これは2つの方法で実現されます。1つは、RollupがESモジュール(CommonJSモジュールよりも効率的)に基づいているためです。2つ目は、生成されたバンドルから未使用のコードを削除するためです。

デモライブラリの使用例

ロールアップの効率を証明するために、デモライブラリを使用します。課題(もちろん、私たちが勝つことになる)は、まったく同じコードベースを持ち、それをコンパイルしてTypeScriptとJavaScriptの両方で使用することです。

デモライブラリの設定

このデモで使用する小さなデモライブラリは、2つの関数セットを並べたものです。1つは文字列用で、もう1つは数値用です。ここにあるセットアップを保存するために、GitHubにリポジトリをアセンブルしました。

一般的な考え方は、と呼ばれるファイルにまったく同じ基本関数(/srcディレクトリにあります)を収集することです。numbersManipulation.jsstringsManipulation.js

使用する予定の関数は、別のファイルに収集されますgameLibrary.js。このファイルは、アプリケーションで使用する予定のファイルです。

アイデアは、ロールアップを使用して、さまざまなライブラリからの機能をバンドルする方法を模倣することです。

先に進む前に、プロジェクトをセットアップして実行し、すべてが正常に機能していることを確認しましょう。まず、実行してnpm i (必要に応じて使用することもできyarnます)、すべてのパッケージをダウンロードします。

これで、を使用してテストスクリプトを実行する準備が整いましたnpm run test。これにより、バンドルがコンパイルされ、JavaScript(appJS.js)バージョンとTypeScriptバージョン(appTS.ts)の両方のバージョンのアプリケーションが実行されます。

以下に示す実行の出力は、2つのスクリプトとを実行するだけappJS.jsですappTS.ts。どちらのスクリプトも同じコードベースであるライブラリを使用しており、Rollupによって生成されるファイル/src/gameLibrary.jsに貢献します。bundle.js

ロールアップで2つの言語を使用する

/srcディレクトリに含まれるリポジトリを見てみましょう。前述のように、アプリケーションで使用する予定のライブラリと、に含まれるrollup -cスクリプトで実行されるコマンドは、を読み取り、ディレクトリ内のバンドルをアセンブルします。buildpackage.jsonrollup.configuration.js/dist

そのようなディレクトリの内容を考えてみましょう:

最初のファイルは、d.tsTypeScriptの既存のJavaScriptコードベースの形状を記述した宣言ファイルです。

2番目のファイル、bundle.jsは最も興味深いファイルです。これは、Rollupを使用して作成したバンドルです。

3番目のファイルは.map、バンドルを縮小したい場合に備えて、元のソースを追跡するために使用されます。

次に、ツリーシェイクプロセスがどのように機能するかについて簡単に説明します。

木の揺れのプロセス

木の揺れはロールアップの重要な機能です。ツリーシェイクを使用すると、最小限の機能を含むバンドルを作成して、コードをより軽量かつ高速に保つことができます。

上の図では、コードの静的分析によって差し引かれる関数呼び出しツリーを見ることができます。関数が列挙され、使用するコードとの関連性が追跡されます。

この分析の後、関連する機能を収集して並置することにより、バンドルが組み立てられます。下の写真bundle.jsを除いて、すべての機能を含むファイルの結果を見ることができます。どのコードにもリンクされていなかったため、破棄されました。isOdd()isOdd()

比喩的に言えば、関数isOdd()はどのブランチにも接続されていないため、依存関係のツリーを振ることによって機能が低下しました。

もう1つの興味深い詳細は、紺色のブロックに表示されます。これらは、バンドルで明示的にエクスポートされないが、関数によって使用されるconvert()関数です。予想どおり、それらはbundle.jsにあり、水色のブロックは独自のファイルに明示的にエクスポートされています。

一般的に、ツリーシェイクは、プロジェクトに多数のサードパーティライブラリとフレームワークが必要な場合に効果的です。各ライブラリとフレームワークには、数十の関数とメソッドがあります。

ライブラリのアクセサリ

バンドルは、を実行して作成されrollup.config.jsます。これは、バンドルを作成するための入力ファイルとプラグインの観点から実行される操作について説明しています。

import dts from 'rollup-plugin-dts'
import esbuild from 'rollup-plugin-esbuild'

export default [
  {
    input: `src/gameLibrary.js`,
    plugins: [esbuild()],
    output: [
      {
        file: `dist/bundle.js`,
        format: 'cjs',
        sourcemap: true,
        exports: 'default',
      },
    ]
  },
  {
    input: `src/gameLibrary.js`,
    plugins: [dts()],
    output: {
      file: `dist/bundle.d.ts`,
      format: 'es',
    },
  }
]

上記のコードでは、GitHubリポジトリから構成ファイルを確認できます。魔法がどこで起こるかを理解するためにこれについて話し合いましょう。

このファイルは、ロールアップに2つの操作を実行するように指示します。7行目でバンドルをアセンブルし、 19行目でプラグインを使用してファイルをesbuild plugin生成します。両方の手順は、6行目と18​​行目に示されている同じ入力ファイルで実行されます。d.tsdts/src/gameLibrary.js

このファイル/src/gameLibrary.jsは、バンドル作成プロセスで「シェイク」される依存関係ツリーのルートです。

プラグインは、esbuild11行目に示されているCommonJSバンドルと、.map12行目の値によって要求されたソースマップ(前のセクションで見たファイル)を生成します。ロールアップ構成ファイルの一般的な構造は注目に値します。それぞれが独自の構成を持つプラグインの配列をエクスポートします。

利用可能なプラグインの(そうではない)完全なリストについては、このリポジトリを確認できます。

結論

この投稿では、Rollupフレームワークを使用して、関数のさまざまなライブラリからのコードを均質化する方法と、2つの異なる言語で使用するための効率的なバンドルを作成する方法を示しました。

私の意見では、ロールアップは、さまざまなコンテキスト、言語、またはプラットフォームで使用される可能性のあるすべてのプロジェクトに採用できます。これは、大小を問わず、必要になる可能性のある微調整の表面を提供し、実際に生成しているコードのサイズを監視できるようにします。

このストーリーは、もともとhttps://blog.logrocket.com/using-rollup-package-library-typescript-javascript/で公開されました

#typescript #javascript #rollup #packaging 

Rollupを使用してTypeScriptおよびJavaScript用のライブラリをパッケージ化する

Uso De Rollup Para Empaquetar Una Biblioteca Para TypeScript Y JS

Limpiar su base de código es un paso fundamental para escribir código confiable. Este proceso puede ser particularmente complejo cuando se debe compilar el mismo código para diferentes plataformas tecnológicas. El desarrollo web moderno es un gran ejemplo de esto.

Hoy en día, incluso cuando tiene un solo servidor que proporciona una API simple, es probable que aún maneje decenas de funcionalidades diferentes más pequeñas. Esto puede volverse confuso bastante rápido, pero afortunadamente existen procesos y herramientas para hacernos la vida más fácil.

En este artículo, discutiremos el uso de Rollup. Rollup es un paquete de módulos diseñado para ayudar en el proceso de recopilar todas las funcionalidades de su nueva biblioteca en un solo paquete.

La idea detrás de Rollup es simplificar el desarrollo permitiéndole concentrarse en la función mientras Rollup prepara el paquete y lo envuelve de la manera más eficiente, ya sea una biblioteca para una aplicación de back-end o un módulo para el navegador.

¿Qué es Roll up?

Según la documentación oficial de Rollup , "Rollup es un paquete de módulos para JavaScript que compila pequeñas piezas de código en algo más grande y complejo, como una biblioteca o una aplicación".

Esta es una postura interesante en el diseño de una nueva biblioteca y está a un paso de las largas sesiones de diseño que eran comunes a principios de la década de 2000. En ese entonces, diseñaría sus funciones y objetos y luego los agruparía en un solo módulo. Esto homogeneizaría las interfaces y permitiría que se integren fácilmente en el lugar o plataforma para ejecutarse.

Lo que hace que Rollup sea especial es su capacidad para mantener archivos pequeños. Lo logra de dos maneras: primero debido al hecho de que Rollup se basa en módulos ES (más eficientes que los módulos CommonJS); y segundo porque elimina el código no utilizado del paquete producido.

Ejemplo usando una biblioteca de demostración

Para probar la eficiencia de Rollup, usaremos una biblioteca de demostración. El desafío (que ganaremos, por supuesto) es tener exactamente el mismo código base y luego compilarlo y usarlo con TypeScript y JavaScript.

Configuración de la biblioteca de demostración

La pequeña biblioteca de demostración que usaremos en esta demostración es una yuxtaposición de dos conjuntos de funciones, una para cadenas y otra para números. Reuní un repositorio en GitHub para ahorrarte algo de configuración, que se encuentra aquí .

La idea general es tener exactamente las mismas funciones básicas (las encontrará en el /srcdirectorio) recopiladas en los archivos llamados numbersManipulation.jsy stringsManipulation.js.

Las funciones que pretendemos utilizar están recogidas en otro archivo, gameLibrary.js. Este mismo archivo es el que pretendemos usar en nuestra aplicación.

La idea es imitar la forma en que se usa Rollup para agrupar funcionalidades provenientes de diferentes bibliotecas.

Antes de continuar, configuremos y ejecutemos el proyecto para comprobar que todo funciona bien. Primero, ejecuta npm i (también puedes usar yarnsi lo prefieres) para descargar todos los paquetes.

Ahora, está listo para ejecutar el script de prueba con npm run test, que compilará el paquete y ejecutará ambas versiones de las aplicaciones: la versión de JavaScript ( appJS.js) y la versión de TypeScript ( appTS.ts).

El resultado de la ejecución, que se ve a continuación, simplemente ejecutará los dos scripts appJS.jsy appTS.ts. Ambos scripts usan el mismo código base, la biblioteca /src/gameLibrary.js, que contribuirá al bundle.jsarchivo producido por Rollup.

Usar dos idiomas en Rollup

Veamos el repositorio que /srccontiene el directorio. Como se mencionó anteriormente, las bibliotecas que pretendemos usar en nuestras aplicaciones y el comando rollup -c, ejecutado en el script buildcontenido en el package.json, leerá rollup.configuration.jsy ensamblará el paquete en el /distdirectorio.

Consideremos el contenido de dicho directorio:

El primer archivo es el d.tsarchivo de declaración que describe la forma de un código base de JavaScript existente para TypeScript.

El segundo archivo, bundle.js, es el más interesante. Este es el paquete que creamos usando Rollup.

El tercer archivo es .mapy se usa para realizar un seguimiento de la fuente original, en caso de que queramos minimizar el paquete.

Ahora, discutiremos brevemente cómo funciona el proceso de sacudir árboles.

El proceso de sacudir el árbol

La sacudida de árboles es una característica importante en Rollup. El movimiento del árbol permite la creación de un paquete que incluye la funcionalidad mínima, manteniendo el código más ligero y rápido.

En la imagen de arriba, puede ver el árbol de llamadas a funciones que se deduce del análisis estático del código. Las funciones se enumeran y se rastrea su relevancia para el código que vamos a utilizar.

Después de este análisis, el paquete se ensambla reuniendo y yuxtaponiendo las funciones relevantes. Puede ver el resultado del bundle.jsarchivo que contiene todas las funciones, excepto isOdd()en la foto a continuación. isOdd()fue descartado porque no estaba vinculado a ningún código.

Metafóricamente, la función isOdd()se vino abajo sacudiendo el árbol de las dependencias porque no estaba adherido a ninguna rama.

Otro detalle interesante se muestra en los bloques de color azul oscuro. Estas son funciones que no se exportan explícitamente en el paquete, pero son utilizadas por la convert()función. Como era de esperar, los encontrará en bundle.js, y los bloques de color azul claro se exportarán explícitamente en sus propios archivos.

En términos generales, la sacudida de árboles es efectiva cuando su proyecto necesita muchas bibliotecas y marcos de trabajo de terceros que tienen docenas de funciones y métodos disponibles.

Complementando la biblioteca

El paquete se crea ejecutando rollup.config.js. Esto describe las operaciones que se realizarán en términos de archivos de entrada y complementos para crear el paquete.

import dts from 'rollup-plugin-dts'
import esbuild from 'rollup-plugin-esbuild'

export default [
  {
    input: `src/gameLibrary.js`,
    plugins: [esbuild()],
    output: [
      {
        file: `dist/bundle.js`,
        format: 'cjs',
        sourcemap: true,
        exports: 'default',
      },
    ]
  },
  {
    input: `src/gameLibrary.js`,
    plugins: [dts()],
    output: {
      file: `dist/bundle.d.ts`,
      format: 'es',
    },
  }
]

En el código anterior, puede ver el archivo de configuración de mi repositorio de GitHub . Discutamos esto para entender dónde ocurre la magia.

El archivo le indica a Rollup que realice dos operaciones: ensamble el paquete usando la esbuild pluginlínea 7 y genere el d.tsarchivo usando el dtscomplemento en la línea 19. Ambos pasos se realizarán en el mismo archivo de entrada /src/gameLibrary.js, que se muestra en las líneas 6 y 18.

El archivo /src/gameLibrary.jses la raíz del árbol de dependencias que se “sacudirá” en el proceso de creación del paquete.

El esbuildcomplemento generará un paquete CommonJS, que se muestra en la línea 11, y también un mapa de origen (el .maparchivo que vimos en la sección anterior) según lo solicitado por el valor en la línea 12. Vale la pena señalar que la estructura general del archivo de configuración Rollup exporta una variedad de complementos, cada uno con sus propias configuraciones.

Puede consultar este repositorio para obtener una lista (no tan) completa de los complementos disponibles.

Conclusión

En esta publicación, demostramos cómo se puede usar el marco Rollup para homogeneizar el código proveniente de diferentes bibliotecas de funciones, así como también cómo producir un paquete eficiente para usar en dos idiomas diferentes.

En mi opinión, Rollup puede adoptarse para cualquier proyecto que pueda usarse en diferentes contextos, lenguajes o plataformas. Ofrece una superficie para los ajustes que pueda necesitar, ya sean grandes o pequeños, lo que le permite controlar el tamaño del código que realmente está produciendo.

Esta historia se publicó originalmente en https://blog.logrocket.com/using-rollup-package-library-typescript-javascript/

#typescript #javascript #rollup #packaging 

Uso De Rollup Para Empaquetar Una Biblioteca Para TypeScript Y JS

Rollup: Next-generation ES Module Bundler

Rollup

Overview

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 uses the standardized ES module format for code, instead of previous idiosyncratic solutions such as CommonJS and AMD. ES modules let you freely and seamlessly combine the most useful individual functions from your favorite libraries. Rollup can optimize ES modules for faster native loading in modern browsers, or output a legacy module format allowing ES module workflows today.

Quick Start Guide

Install with npm install --global rollup. Rollup can be used either through a command line interface with an optional configuration file, or else through its JavaScript API. Run rollup --help to see the available options and parameters. The starter project templates, rollup-starter-lib and rollup-starter-app, demonstrate common configuration options, and more detailed instructions are available throughout the user guide.

Commands

These commands assume the entry point to your application is named main.js, and that you'd like all imports compiled into a single file named bundle.js.

For browsers:

# compile to a <script> containing a self-executing function
rollup main.js --format iife --name "myBundle" --file bundle.js

For Node.js:

# compile to a CommonJS module
rollup main.js --format cjs --file bundle.js

For both browsers and Node.js:

# UMD format requires a bundle name
rollup main.js --format umd --name "myBundle" --file bundle.js

Why

Developing software is usually easier if you break your project into smaller separate pieces, since that often removes unexpected interactions and dramatically reduces the complexity of the problems you'll need to solve, and simply writing smaller projects in the first place isn't necessarily the answer. Unfortunately, JavaScript has not historically included this capability as a core feature in the language.

This finally changed with ES modules support in JavaScript, which provides a syntax for importing and exporting functions and data so they can be shared between separate scripts. Most browsers and Node.js support ES modules. However, Node.js releases before 12.17 support ES modules only behind the --experimental-modules flag, and older browsers like Internet Explorer do not support ES modules at all. Rollup allows you to write your code using ES modules, and run your application even in environments that do not support ES modules natively. For environments that support them, Rollup can output optimized ES modules; for environments that don't, Rollup can compile your code to other formats such as CommonJS modules, AMD modules, and IIFE-style scripts. This means that you get to write future-proof code, and you also get the tremendous benefits of...

Tree Shaking

In addition to enabling the use of ES modules, Rollup also statically analyzes and optimizes the code you are importing, and will exclude anything that isn't actually used. This allows you to build on top of existing tools and modules without adding extra dependencies or bloating the size of your project.

For example, with CommonJS, the entire tool or library must be imported.

// import the entire utils object with CommonJS
var utils = require('utils');
var query = 'Rollup';
// use the ajax method of the utils object
utils.ajax('https://api.example.com?search=' + query).then(handleResponse);

But with ES modules, instead of importing the whole utils object, we can just import the one ajax function we need:

// import the ajax function with an ES import statement
import { ajax } from 'utils';
var query = 'Rollup';
// call the ajax function
ajax('https://api.example.com?search=' + query).then(handleResponse);

Because Rollup includes the bare minimum, it results in lighter, faster, and less complicated libraries and applications. Since this approach is based on explicit import and export statements, it is vastly more effective than simply running an automated minifier to detect unused variables in the compiled output code.

Compatibility

Importing CommonJS

Rollup can import existing CommonJS modules through a plugin.

Publishing ES Modules

To make sure your ES modules are immediately usable by tools that work with CommonJS such as Node.js and webpack, you can use Rollup to compile to UMD or CommonJS format, and then point to that compiled version with the main property in your package.json file. If your package.json file also has a module field, ES-module-aware tools like Rollup and webpack will import the ES module version directly.

Author: Rollup
Source Code: https://github.com/rollup/rollup 
License: View license

#node #rollup #javascript #typescript 

Rollup: Next-generation ES Module Bundler

Introduction to Ethereum Rollups for Beginners

Overview

Ethereum, the most popular blockchain, has seen scaling issues for quite a long time now. With high gas fees due to congestion being the primary pain point. With the increasing cost to use the network, a plethora of scaling solutions have emerged. Today in this guide, we will go over some Ethereum scaling solutions and deep dive into rollups.

Ethereum Scaling solutions

The main goal of all the Ethereum scaling solutions is to increase transaction speed and throughput without compromising the decentralized nature of the blockchain.

There are two main directions in which these scaling solutions are being explored:

  • On-chain Scaling.
  • Off-chain Scaling.

On-chain Scaling

On-chain or Layer 1 scaling solutions refer to increasing the capacity of the core blockchain layer, usually by increasing the numbers of transactions that can be fit in a block. In Ethereum’s case, on-chain scaling would mean changing the Ethereum Mainnet protocol. Increasing the amount of data/transactions that can fit into an Ethereum block would also increase the hardware requirements to run a node, raising some critics around this scaling solution. It can limit the number of nodes and may affect decentralization. But, with Ethereum 2 comes a concept of Sharding; sharding is the process of splitting the Ethereum infrastructure/database. This will reduce the node load by dividing the work; it is a much broader concept.

Off-chain Scaling

Off-chain scaling solutions are meant to indirectly scale the primary layer one blockchain by adding more layers to process the transactions without using the actual core blockchain. Off-chain scaling uses the main layer of blockchain as a trust and arbitration layer. Off-chain scaling is often referred to as Layer 2 scaling as it adds another layer on top of the main Ethereum layer. 

Layer 2 scaling is seen as an immediate resolution for Ethereum scalability as it maintains decentralization, which is the most valuable thing for the Ethereum community. Layer 2 solutions further require additional hardware or complex software to be built, so it takes longer for networks to feel its effects. Layer 2 solutions derive their security from Ethereum and can be custom built/run by an individual, organization, or community based on the use cases. 

Following are types of solutions: 

  • Sidechains: Sidechains are EVM compatible blockchains connected to Ethereum via bridges. They have their own consensus protocol and block parameters.

     
  • Rollups: Rollups perform transaction execution outside the main Ethereum blockchain and send the transaction data back to the main Ethereum network.

     
  • State channels: State channels use multisig channels to settle transactions off the main chain between parties and send the state to the main blockchain. These are very secure but have particular use cases.

     
  • Plasma: Plasma is a framework where there are side chains anchored to the main Ethereum blockchain, and they are connected to the Etheruem blockchain via a root contract; this contract records the current state and states the rules for the child chains.

Rollups

On one hand, we have layer 2 solutions such as channels that are fully secure by Ethereum security but work well for only a specific set of applications; sidechains, on the other hand, are usually EVM compatible and can scale general purpose applications, but the main drawback is that they do not rely on Ethereum for security but instead have their own consensus model.

Rollups try to bring the best of both of these worlds by creating a general-purpose solution while still having the security of Ethereum. Rollups settle the transactions outside of the main Ethereum network but post the transaction data back to the Ethereum network and still derive its security from the Ethereum protocol. Each rollup has its specific contracts deployed on the main Ethereum network. Rollups executes the transaction off the chain mainly on a rollup specific chain and then batch the transaction data, compresses it, and sends it to the main Etheruem chain; this reduces the load on the main Ethereum network of actually processing those transactions.

This helps in reducing the fees and blockchain adoption by increasing participation. Rollups also enable redeployment of all the existing Ethereum smart contracts to a rollup with little or no change. 

Types of Rollups

Rollups look like an up-and-coming solution to the Ethereum scalability problem, but how can we make sure that the transaction data posted on Ethereum by rollups is valid? Different rollup types handle this differently. There are two types of rollups based on this; Optimistic Rollups and ZK-rollups.

Optimistic rollups:

Optimistic rollups, as the name suggests at first, assume that the transaction data submitted to the Ethereum network is correct and valid. Whenever there is an invalid transaction, there is a dispute resolution. A party submits a batch of transaction data to Ethereum, and whenever someone detects a fraudulent transaction, they can offer fraud proof against that transaction. Here both the parties, the one submitting the transaction data batch and the one submitting the fraud proof, have their ETH staked. This means that any misconduct from either party would result in loss of their ETH. Whenever a fraud proof is submitted, the suspicious transaction is executed again, this time on the main Ethereum network. To make sure the transaction is replayed with the exact state when it was originally performed on the rollup chain, a manager contract is created that replaces certain function calls with a state from the rollup. 

Examples: Optimism, Arbitrum.

ZK-rollups:

ZK-rollups or Zero-Knowledge rollups, unlike Optimistic rollups, don’t have any dispute resolution mechanism. It uses a clever piece of cryptography Zero-Knowledge proofs. In this model, every batch of transactions submitted to Ethereum includes a cryptographic proof called a SNARK ( Succinct Non-Interactive Argument of Knowledge ) verified by a contract that is deployed on the Ethereum main network. This contract maintains the state of all transfers on the rollups chain, and this state can be updated only with validity proof. This means that only the validity proof needs to be stored on the main Ethereum network instead of bulky transaction data, thus making zk-rollups quicker and cheaper comparatively.

Examples: Loopring, STARKWARE, zkSync

Conclusion

If you made it here now, you know a little bit more about Ethereum scaling solutions and a lot more about rollups.

Link: https://www.quicknode.com/guides/infrastructure/introduction-to-ethereum-rollups

#rollup #solidity  #blockchain  #ethereum 

Introduction to Ethereum Rollups for Beginners
Callum  Owen

Callum Owen

1648106340

What are Rollups in Crypto? ZKSnarks vs Optimistics Rollups Explained

Rollups are  way to "roll up" a bunch of transactions into one single piece of data to save space and processing power on the blockchain. Right now, there are 2 main rollups: ZKsnarks and Optimistic rollups and you can watch our video to learn how both work, including the benefits and drawbacks.

#rollup #crypto #optimistic 

What are Rollups in Crypto? ZKSnarks vs Optimistics Rollups Explained