diff --git a/README.md b/README.md
index 04105bd..35e0404 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
pkgroll
-
+
_pkgroll_ is a JavaScript package bundler powered by Rollup that automatically builds your package from entry-points defined in `package.json`. No config necessary!
@@ -38,7 +38,7 @@ npm install --save-dev pkgroll
2. Define package entry-files in `package.json`.
[These configurations](https://nodejs.org/api/packages.html#package-entry-points) are for Node.js to determine how to import the package.
-
+
Pkgroll leverages the same configuration to determine how to build the package.
```json5
@@ -237,6 +237,12 @@ Run the bundler in watch mode during development:
pkgroll --watch
```
+### Clean dist
+Clean dist directory before bundling:
+```sh
+pkgroll --clean-dist
+```
+
## FAQ
### Why bundle with Rollup?
diff --git a/src/cli.ts b/src/cli.ts
index 51233f1..7075b18 100644
--- a/src/cli.ts
+++ b/src/cli.ts
@@ -10,6 +10,7 @@ import { getSourcePath } from './utils/get-source-path.js';
import { getRollupConfigs } from './utils/get-rollup-configs.js';
import { tsconfig } from './utils/tsconfig.js';
import { log } from './utils/log.js';
+import { cleanDist } from './utils/clean-dist.js';
const { stringify } = JSON;
@@ -78,6 +79,11 @@ const argv = cli({
},
description: 'Sourcemap generation. Provide `inline` option for inline sourcemap (eg. --sourcemap, --sourcemap=inline)',
},
+ cleanDist: {
+ type: Boolean,
+ description: 'Clean dist before bundling',
+ default: false,
+ },
},
help: {
@@ -149,6 +155,15 @@ if (tsconfigTarget) {
packageJson,
);
+ if (argv.flags.cleanDist) {
+ /**
+ * Typically, something like this would be implemented as a plugin, so it only
+ * deletes what it needs to but pkgroll runs multiple builds (e.g. d.ts, mjs, etc)
+ * so as a plugin, it won't be aware of the files emitted by other builds
+ */
+ await cleanDist(distPath);
+ }
+
if (argv.flags.watch) {
log('Watch initialized');
diff --git a/src/utils/clean-dist.ts b/src/utils/clean-dist.ts
new file mode 100644
index 0000000..b3f9ba0
--- /dev/null
+++ b/src/utils/clean-dist.ts
@@ -0,0 +1,14 @@
+import fs from 'fs';
+import { fsExists } from './fs-exists.js';
+
+export const cleanDist = async (directoryPath: string) => {
+ const exists = await fsExists(directoryPath);
+ if (!exists) {
+ return;
+ }
+
+ await fs.promises.rm(directoryPath, {
+ recursive: true,
+ force: true,
+ });
+};
diff --git a/tests/specs/builds/clean-dist.ts b/tests/specs/builds/clean-dist.ts
new file mode 100644
index 0000000..d4418ce
--- /dev/null
+++ b/tests/specs/builds/clean-dist.ts
@@ -0,0 +1,105 @@
+import path from 'path';
+import fs from 'fs/promises';
+import { testSuite, expect } from 'manten';
+import { createFixture } from 'fs-fixture';
+import { pkgroll, installTypeScript } from '../../utils.js';
+
+export default testSuite(({ describe }, nodePath: string) => {
+ describe('clean dist', ({ test }) => {
+ test('no flag', async ({ onTestFinish }) => {
+ const fixture = await createFixture('./tests/fixture-package');
+ onTestFinish(async () => await fixture.rm());
+
+ installTypeScript(fixture.path);
+
+ await fixture.writeJson('package.json', {
+ main: './dist/nested/index.js',
+ module: './dist/nested/index.mjs',
+ types: './dist/nested/index.d.ts',
+ });
+
+ await pkgroll(
+ [],
+ {
+ cwd: fixture.path,
+ nodePath,
+ },
+ );
+
+ await fs.mkdir(path.join(fixture.path, 'src', 'nested2'));
+ await fixture.writeFile('./src/nested2/index.ts', 'export function sayHello2(name: string) { return name; }');
+
+ await fixture.writeJson('package.json', {
+ main: './dist/nested2/index.js',
+ module: './dist/nested2/index.mjs',
+ types: './dist/nested2/index.d.ts',
+ });
+
+ const pkgrollProcess = await pkgroll(
+ [],
+ {
+ cwd: fixture.path,
+ nodePath,
+ },
+ );
+
+ expect(pkgrollProcess.exitCode).toBe(0);
+ expect(pkgrollProcess.stderr).toBe('');
+
+ expect(await fixture.exists('dist/nested/index.js')).toBe(true);
+ expect(await fixture.exists('dist/nested/index.mjs')).toBe(true);
+ expect(await fixture.exists('dist/nested/index.d.ts')).toBe(true);
+ expect(await fixture.exists('dist/nested2/index.js')).toBe(true);
+ expect(await fixture.exists('dist/nested2/index.mjs')).toBe(true);
+ expect(await fixture.exists('dist/nested2/index.d.ts')).toBe(true);
+ });
+
+ test('with flag', async ({ onTestFinish }) => {
+ const fixture = await createFixture('./tests/fixture-package');
+ onTestFinish(async () => await fixture.rm());
+
+ installTypeScript(fixture.path);
+
+ await fixture.writeJson('package.json', {
+ main: './dist/nested/index.js',
+ module: './dist/nested/index.mjs',
+ types: './dist/nested/index.d.ts',
+ });
+
+ await pkgroll(
+ [],
+ {
+ cwd: fixture.path,
+ nodePath,
+ },
+ );
+
+ await fs.mkdir(path.join(fixture.path, 'src', 'nested2'));
+ await fixture.writeFile('./src/nested2/index.ts', 'export function sayHello2(name: string) { return name; }');
+
+ await fixture.writeJson('package.json', {
+ main: './dist/nested2/index.js',
+ module: './dist/nested2/index.mjs',
+ types: './dist/nested2/index.d.ts',
+ });
+
+ const pkgrollProcess = await pkgroll(
+ ['--clean-dist'],
+ {
+ cwd: fixture.path,
+ nodePath,
+ },
+ );
+
+ expect(pkgrollProcess.exitCode).toBe(0);
+ expect(pkgrollProcess.stderr).toBe('');
+
+ expect(await fixture.exists('dist/nested/index.js')).toBe(false);
+ expect(await fixture.exists('dist/nested/index.mjs')).toBe(false);
+ expect(await fixture.exists('dist/nested/index.d.ts')).toBe(false);
+ expect(await fixture.exists('dist/nested2/index.js')).toBe(true);
+ expect(await fixture.exists('dist/nested2/index.mjs')).toBe(true);
+ expect(await fixture.exists('dist/nested2/index.d.ts')).toBe(true);
+ });
+ });
+});
diff --git a/tests/specs/builds/index.ts b/tests/specs/builds/index.ts
index 86db517..7e8a7d9 100644
--- a/tests/specs/builds/index.ts
+++ b/tests/specs/builds/index.ts
@@ -16,5 +16,6 @@ export default testSuite(({ describe }, nodePath: string) => {
runTestSuite(import('./src-dist.js'), nodePath);
runTestSuite(import('./sourcemap.js'), nodePath);
runTestSuite(import('./typescript.js'), nodePath);
+ runTestSuite(import('./clean-dist.js'), nodePath);
});
});