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-run #41

Merged
merged 16 commits into from
Nov 21, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/run/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# @rollup/plugin-run Change Log

## 1.1.0

- Allow arguments and options to be passed to `child_process.fork`

## 1.0.2

- Warn if Rollup version is too low

## 1.0.1

- Handle output files with different names from input files

## 1.0.0

- First release
102 changes: 102 additions & 0 deletions packages/run/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
[npm]: https://img.shields.io/npm/v/@rollup/plugin-run
[npm-url]: https://www.npmjs.com/package/@rollup/plugin-run
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-run
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-run

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

# @rollup/plugin-run
shrirambalaji marked this conversation as resolved.
Show resolved Hide resolved

🍣 A Rollup plugin which runs your bundles in Node once they're built.

Using this plugin gives much faster results compared to what you would do with [nodemon](https://nodemon.io/).

## Install

Using npm:

```console
npm install @rollup/plugin-run --save-dev
```

## Usage

Create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:
shellscape marked this conversation as resolved.
Show resolved Hide resolved

```js
import run from "@rollup/plugin-run";

export default {
input: "src/index.js",
output: {
file: "dist/index.js",
format: "cjs"
},
plugins: [run()]
};
```

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). If the build produces any errors, the plugin will write a 'alias' character to stderr, which should be audible on most systems.

The plugin `forks` a child process with the generated file, every time the bundle is rebuilt (after first closing the previous process, if it's not the first run).

_Note: This plugin works with Rollup's code-splitting if you're using dynamic `import(...)` — the only constraint is that you have a single entry point specified in the config._

## Options

This plugin supports pass through option available for [child_process.fork(...)](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options).

Example:

Debugging with sourcemaps using [source-map-support](https://www.npmjs.com/package/source-map-support):

```diff
// rollup.config.js
import run from '@rollup/plugin-run';

export default {
input: 'src/index.js',
output: {
file: 'dist/index.js',
format: 'cjs',
+ sourcemap: true
},
plugins: [
- run()
+ run({
+ execArgv: ['-r', 'source-map-support/register']
+ })
]
};
```

## Practical Example

The feature is usually intended for development use, you may prefer to only include it when Rollup is being run in watch mode:

```diff
// rollup.config.js
import run from '@rollup/plugin-run';

+const dev = process.env.ROLLUP_WATCH === 'true';

export default {
input: 'src/index.js',
output: {
file: 'dist/index.js',
format: 'cjs'
},
plugins: [
- run()
+ dev && run()
]
};
```
shrirambalaji marked this conversation as resolved.
Show resolved Hide resolved

## Meta

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

[LICENSE (MIT)](/LICENSE)
69 changes: 69 additions & 0 deletions packages/run/lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const path = require('path');
const childProcess = require('child_process');

module.exports = (opts = {}) => {
let input;
let proc;

const args = opts.args || [];
const forkOptions = opts.options || opts;
delete forkOptions.args;

return {
name: 'run',

// eslint-disable-next-line no-shadow
options(opts) {
let inputs = opts.input;

if (typeof inputs === 'string') {
inputs = [inputs];
}

if (typeof inputs === 'object') {
inputs = Object.values(inputs);
}

if (inputs.length > 1) {
throw new Error(`@rollup/plugin-run only works with a single entry point`);
}

input = path.resolve(inputs[0]);
},

generateBundle(outputOptions, bundle, isWrite) {
if (!isWrite) {
this.error(`@rollup/plugin-run currently only works with bundles that are written to disk`);
}

const dir = outputOptions.dir || path.dirname(outputOptions.file);

let dest;

for (const fileName in bundle) {
if (Object.prototype.hasOwnProperty.call(bundle, fileName)) {
const chunk = bundle[fileName];

if (!('isEntry' in chunk)) {
this.error(`@rollup/plugin-run requires Rollup 0.65 or higher`);
}

// eslint-disable-next-line no-continue
if (!chunk.isEntry) continue;

if (chunk.modules[input]) {
dest = path.join(dir, fileName);
break;
}
}
}

if (dest) {
if (proc) proc.kill();
proc = childProcess.fork(dest, args, forkOptions);
} else {
this.error(`@rollup/plugin-run could not find output chunk`);
}
}
};
};
48 changes: 48 additions & 0 deletions packages/run/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@rollup/plugin-run",
"version": "1.1.0",
"publishConfig": {
"access": "public"
},
"description": "Run your bundle after you've built it",
"license": "MIT",
"repository": "rollup/plugins",
"author": "Rich Harris",
"homepage": "https://github.com/rollup/plugins/packages/run/#readme",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "lib/index.js",
"scripts": {
shrirambalaji marked this conversation as resolved.
Show resolved Hide resolved
"ci:coverage": "nyc pnpm run test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:lint": "pnpm run lint && pnpm run security",
"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",
shrirambalaji marked this conversation as resolved.
Show resolved Hide resolved
"lint:docs": "prettier --single-quote --write README.md",
"lint:js": "eslint --fix --cache lib test",
"lint:package": "prettier --write package.json --plugin=prettier-plugin-package",
"prepublishOnly": "pnpm run lint && pnpm run test",
"security": "echo 'pnpm needs `npm audit` support'",
"test": "ava"
},
"files": [
"lib"
],
"keywords": [
"rollup",
"plugin",
"run"
],
"peerDependencies": {
"rollup": "^1.20.0"
},
"devDependencies": {
shrirambalaji marked this conversation as resolved.
Show resolved Hide resolved
"del": "^5.1.0",
"rollup": "^1.20.0",
"sinon": "^7.5.0"
},
"ava": {
"files": [
"!**/fixtures/**"
]
}
}
1 change: 1 addition & 0 deletions packages/run/test/fixtures/change-detect-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const Greeting = () => 'Hola'; // eslint-disable-line
1 change: 1 addition & 0 deletions packages/run/test/fixtures/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const Greeting = () => 'Hello'; // eslint-disable-line
88 changes: 88 additions & 0 deletions packages/run/test/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
const fs = require('fs');
const { EventEmitter } = require('events');

const { join } = require('path');

const childProcess = require('child_process');

const writeFile = require('util').promisify(fs.writeFile);

const del = require('del');
const { rollup } = require('rollup');
const test = require('ava');
const sinon = require('sinon');

const run = require('../lib/');

const cwd = join(__dirname, 'fixtures/');
const file = join(cwd, 'output/bundle.js');
const input = join(cwd, 'input.js');

process.chdir(cwd);

const outputOptions = { file, format: 'cjs' };

let mockChildProcess;
test.before(() => {
mockChildProcess = sinon
.stub(childProcess, ['fork'])
.returns({ ...new EventEmitter(), kill: sinon.fake() });
});

test('builds the bundle and forks a child process', async (t) => {
const bundle = await rollup({
input,
plugins: [run()]
});
await bundle.write(outputOptions);
t.true(mockChildProcess.calledWithExactly(outputOptions.file, [], {}));
});

test('allows pass-through options for child_process.fork', async (t) => {
const forkOptions = {
cwd,
detached: false,
silent: false
};
const bundle = await rollup({
input,
plugins: [run(forkOptions)]
});

await bundle.write(outputOptions);
t.true(mockChildProcess.calledWithExactly(outputOptions.file, [], forkOptions));
});

test('throws an error when bundle is not written to disk', async (t) => {
const bundle = await rollup({
input,
plugins: [run()]
});
await t.throwsAsync(
async () => {
await bundle.generate(outputOptions);
},
{
instanceOf: Error,
message: '@rollup/plugin-run currently only works with bundles that are written to disk'
}
);
});

test('detects changes - forks a new child process and kills older process', async (t) => {
// eslint-disable-next-line no-shadow
const input = join(cwd, 'change-detect-input.js');
const bundle = await rollup({
input,
plugins: [run()]
});
await bundle.write(outputOptions);
await writeFile(input, "export const Greeting = () => 'Hola'; // eslint-disable-line");
await bundle.write(outputOptions);
t.true(mockChildProcess.calledWithExactly(outputOptions.file, [], {}));
t.is(mockChildProcess().kill.callCount, 1);
});

test.after(async () => {
await del(['output']);
});
Loading