Skip to content
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

chore: migrate rollup-plugin-multi-entry #88

Merged
merged 2 commits into from Dec 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion .editorconfig
Expand Up @@ -12,7 +12,6 @@ trim_trailing_whitespace = true
[*.md]
insert_final_newline = true
trim_trailing_whitespace = false
max_line_length = 500

[*.yml]
max_line_length = 500
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -26,7 +26,8 @@ This repository houses plugins that Rollup considers critical to every day use o
| [image](packages/image) | Import JPG, PNG, GIF, SVG, and WebP files |
| [inject](packages/inject) | Scan modules for global variables and injects `import` statements where necessary |
| [json](packages/json) | Convert .json files to ES6 modules |
| [legacy](packages/legacy) | Add `export` declarations to legacy non-module scripts. |
| [legacy](packages/legacy) | Add `export` declarations to legacy non-module scripts |
| [multi-entry](packages/multi-entry) | Use multiple entry points for a bundle |
| [node-resolve](packages/node-resolve) | Locate and bundle third-party dependencies in node_modules |
| [replace](packages/replace) | Replace strings in files while bundling |
| [strip](packages/strip) | Remove debugger statements and functions like assert.equal and console.log from your code |
Expand Down
125 changes: 125 additions & 0 deletions packages/multi-entry/README.md
@@ -0,0 +1,125 @@
[npm]: https://img.shields.io/npm/v/@rollup/plugin-multi-entry
[npm-url]: https://www.npmjs.com/package/@rollup/plugin-multi-entry
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-multi-entry
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-multi-entry

[![npm][npm]][npm-url]
[![size][size]][size-url]
[![libera manifesto](https://img.shields.io/badge/libera-manifesto-lightgrey.svg)](https://liberamanifesto.com)

# @rollup/plugin-multi-entry

🍣 A Rollup plugin which allows use of multiple entry points for a bundle.

As an added bonus, the _named exports_ from all entry points will be combined. This is particularly useful for tests, but can also be used to package a library.

_Note: `default` exports cannot be combined and exported by this plugin. Only named exports will be exported._

## Requirements

This plugin requires an [LTS](https://github.com/nodejs/Release) Node version (v8.0.0+) and Rollup v1.20.0+.

## Install

Using npm:

```console
npm install @rollup/plugin-multi-entry --save-dev
```

## Usage

Suppose that we have three separate source files, each with their own export(s):

```js
// batman.js
export const belt = 'utility';
```

```js
// robin.js
export const tights = 'tight';
```

```js
// joker.js
export const color = 'purple';
```

Then, create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:

```js
import multi from '@rollup/plugin-multi-entry';

export default {
input: ['batman.js', 'robin.js', 'joker.js'],
output: {
dir: 'output'
},
plugins: [multi()]
shellscape marked this conversation as resolved.
Show resolved Hide resolved
};
```

Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api).

Using all three files above as entry points will yield a bundle with exports for `belt`, `tights`, and `color`.

## Options

### `exports`

Type: `Boolean`<br>
Default: `true`

If `true`, instructs the plugin to export named exports to the bundle from all entries. If `false`, the plugin will not export any entry exports to the bundle. This can be useful when wanting to combine code from multiple entry files, but not necessarily to export each entry file's exports.

## Supported Input Types

This plugin extends Rollup's `input` option to support multiple new value types, in addition to a `String` specifying a path to a file.

### Glob

When using `plugin-multi-entry`, input values passed as a normal `String` are [glob aware](<https://en.wikipedia.org/wiki/Glob_(programming)>). Meaning you can utilize glob wildcards and other glob patterns to specify files as being input files.

```js
export default {
input: 'batcave/friends/**/*.js',
plugins: [multi()]
// ...
};
```

### Array

An `Array` of `String` can be passed as the input. Values are glob-aware and can specify paths or globbed paths.

```js
export default {
input: ['party/supplies.js', 'batcave/friends/**/*.js'],
plugins: [multi()]
// ...
};
```

### `include` and `exclude`

For fine-grain control, an `Object` may be passed containing `include` and `exclude` properties. These properties specify and `Array` of `String` representing paths (which are also glob-aware) which should be included as entry files, as well as files that should be excluded from any entries that may have been found with `include`, respectively.

```js
export default {
input: {
// invite everyone!
include: ['food.js', 'drinks.js', 'batcave/friends/**/*.js'],
// except for the joker
exclude: ['**/joker.js']
},
plugins: [multi()]
// ...
};
```

## Meta

[CONTRIBUTING](/.github/CONTRIBUTING.md)

[LICENSE (MIT)](/LICENSE)
64 changes: 64 additions & 0 deletions packages/multi-entry/package.json
@@ -0,0 +1,64 @@
{
"name": "@rollup/plugin-multi-entry",
"version": "3.0.0",
"publishConfig": {
"access": "public"
},
"description": "Use multiple entry points for a bundle",
"license": "MIT",
"repository": "rollup/plugins",
"author": "rollup",
"homepage": "https://github.com/rollup/plugins/packages/multi-entry/#readme",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "dist/index.js",
"scripts": {
"build": "rollup -c",
"ci:coverage": "nyc pnpm run test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:lint": "pnpm run build && pnpm run lint",
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}",
"ci:test": "pnpm run test -- --verbose",
"lint": "pnpm run lint:js && pnpm run lint:docs && pnpm run lint:package",
"lint:docs": "prettier --single-quote --write README.md",
"lint:js": "eslint --fix --cache src test",
"lint:package": "prettier --write package.json --plugin=prettier-plugin-package",
"prebuild": "del-cli dist",
"prepare": "pnpm run build",
"prepublishOnly": "pnpm run lint",
"pretest": "pnpm run build",
"test": "ava"
},
"files": [
"dist",
"README.md",
"LICENSE"
],
"keywords": [
"rollup",
"plugin",
"multi",
"multiple",
"entry",
"entries"
],
"peerDependencies": {
"rollup": "^1.20.0"
},
"dependencies": {
"matched": "^1.0.2"
},
"devDependencies": {
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"rollup": "^1.20.1",
"rollup-plugin-babel": "^4.0.3"
},
"ava": {
"files": [
"!**/fixtures/**",
"!**/helpers/**",
"!**/recipes/**",
"!**/types.ts"
]
},
"module": "dist/index.es.js"
}
18 changes: 18 additions & 0 deletions packages/multi-entry/rollup.config.js
@@ -0,0 +1,18 @@
import babel from 'rollup-plugin-babel';

const pkg = require('./package.json');

export default {
input: 'src/index.js',
plugins: [
babel({
presets: [['@babel/env', { targets: { node: '8' }, modules: false }]],
babelrc: false
})
],
external: Object.keys(pkg.dependencies),
output: [
{ format: 'cjs', file: pkg.main },
{ format: 'es', file: pkg.module }
]
};
56 changes: 56 additions & 0 deletions packages/multi-entry/src/index.js
@@ -0,0 +1,56 @@
/* eslint-disable consistent-return, no-param-reassign */

import { promise as matched } from 'matched';

const entry = '\0rollup:plugin-multi-entry:entry-point';

export default function multiEntry(conf) {
let include = [];
let exclude = [];
let exporter = (path) => `export * from ${JSON.stringify(path)};`;

function configure(config) {
if (typeof config === 'string') {
include = [config];
} else if (Array.isArray(config)) {
include = config;
} else {
include = config.include || [];
exclude = config.exclude || [];
if (config.exports === false) {
exporter = (path) => `import ${JSON.stringify(path)};`;
}
}
}

if (conf) {
configure(conf);
}

return {
options(options) {
if (options.input && options.input !== entry) {
configure(options.input);
}
options.input = entry;
},

resolveId(id) {
if (id === entry) {
return entry;
}
},

load(id) {
if (id === entry) {
if (!include.length) {
return Promise.resolve('');
}
const patterns = include.concat(exclude.map((pattern) => `!${pattern}`));
return matched(patterns, { realpath: true }).then((paths) =>
paths.map(exporter).join('\n')
);
}
}
};
}
6 changes: 6 additions & 0 deletions packages/multi-entry/test/fixtures/.eslintrc
@@ -0,0 +1,6 @@
{
"rules": {
"import/prefer-default-export": "off",
"no-console": "off"
}
}
1 change: 1 addition & 0 deletions packages/multi-entry/test/fixtures/0.js
@@ -0,0 +1 @@
export const zero = 0;
1 change: 1 addition & 0 deletions packages/multi-entry/test/fixtures/1.js
@@ -0,0 +1 @@
export const one = 1;
1 change: 1 addition & 0 deletions packages/multi-entry/test/fixtures/2.js
@@ -0,0 +1 @@
console.log('Hello, 2');
74 changes: 74 additions & 0 deletions packages/multi-entry/test/test.js
@@ -0,0 +1,74 @@
/* eslint-disable no-bitwise */

import test from 'ava';
shellscape marked this conversation as resolved.
Show resolved Hide resolved
import { rollup } from 'rollup';

import { getCode } from '../../../util/test';

import multiEntry from '../';

test('takes a single file as input', async (t) => {
const bundle = await rollup({ input: 'test/fixtures/0.js', plugins: [multiEntry()] });
const code = await getCode(bundle);
t.truthy(code.includes('exports.zero = zero;'));
});

test('takes an array of files as input', async (t) => {
const bundle = await rollup({
input: ['test/fixtures/0.js', 'test/fixtures/1.js'],
plugins: [multiEntry()]
});
const code = await getCode(bundle);
t.truthy(code.includes('exports.zero = zero;'));
t.truthy(code.includes('exports.one = one;'));
});

test('allows an empty array as input', async (t) => {
const bundle = await rollup({ input: [], plugins: [multiEntry()] });
const code = await getCode(bundle);
t.falsy(code.includes('exports'));
});

test('takes a glob as input', async (t) => {
const bundle = await rollup({ input: 'test/fixtures/{0,1}.js', plugins: [multiEntry()] });
const code = await getCode(bundle);
t.truthy(code.includes('exports.zero = zero;'));
t.truthy(code.includes('exports.one = one;'));
});

test('takes an array of globs as input', async (t) => {
const bundle = await rollup({
input: ['test/fixtures/{0,}.js', 'test/fixtures/{1,}.js'],
plugins: [multiEntry()]
});
const code = await getCode(bundle);
t.truthy(code.includes('exports.zero = zero;'));
t.truthy(code.includes('exports.one = one;'));
});

test('takes an {include,exclude} object as input', async (t) => {
const bundle = await rollup({
input: {
include: ['test/fixtures/*.js'],
exclude: ['test/fixtures/1.js']
},
plugins: [multiEntry()]
});
const code = await getCode(bundle);
t.truthy(code.includes('exports.zero = zero;'));
t.falsy(code.includes('exports.one = one;'));
});

test('allows to prevent exporting', async (t) => {
const bundle = await rollup({
input: {
include: ['test/fixtures/*.js'],
exports: false
},
plugins: [multiEntry()]
});
const code = await getCode(bundle);
t.truthy(code.includes(`console.log('Hello, 2');`));
t.falsy(code.includes('zero'));
t.falsy(code.includes('one'));
});