Skip to content

Commit

Permalink
chore: migrate rollup-plugin-run (#41)
Browse files Browse the repository at this point in the history
* chore: migrate rollup-plugin-run

* chore: remove unnecessary .gitignore file

* chore: replace all with @rollup/plugin-run

* chore: add missing ci scripts

* chore: add meta links to readme

* update Options and Usage Sections

* chore: remove unnecessary package-lock.json

* deps: add sinon, del packages

* also add `ava` test script

* test: add unit tests for plugin-run with fixtures

* chore: fix ci lint scripts

* chore: rename rollup-plugin-run in readme examples

Co-Authored-By: Andrew Powell <shellscape@users.noreply.github.com>

* deps: add rollup@^1.20.0 as peer dependency

* chore: move main index.js into lib directory

* add files section to package.json
* lint fix tests and fixtures
* lint fix readme

* chore: fix pull_request template deviate from master

* deps: fix pnpm lockfile issue
  • Loading branch information
shrirambalaji authored and shellscape committed Nov 21, 2019
1 parent bf1fb07 commit e3e1ebd
Show file tree
Hide file tree
Showing 8 changed files with 430 additions and 5 deletions.
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

🍣 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:

```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()
]
};
```

## 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": {
"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",
"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": {
"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

0 comments on commit e3e1ebd

Please sign in to comment.