Skip to content

Commit

Permalink
feat: export condition flag (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
privatenumber committed May 2, 2022
1 parent 8f1fdf4 commit 392096c
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 15 deletions.
20 changes: 15 additions & 5 deletions README.md
Expand Up @@ -150,8 +150,8 @@ The target specifies the environments the output should support. Depending on ho

By default, the target is set to the version of Node.js used. It can be overwritten with the `--target` flag:

```
pkgroll --target es2020 --target node14.18.0
```sh
pkgroll --target=es2020 --target=node14.18.0
```

It will also automatically detect and include the `target` specified in `tsconfig.json#compilerOptions`.
Expand All @@ -160,18 +160,28 @@ It will also automatically detect and include the `target` specified in `tsconfi
#### Strip `node:` protocol
Node.js builtin modules can be prefixed with the [`node:` protocol](https://nodejs.org/api/esm.html#node-imports) for explicitness:

```
import fs from 'node:fs/promises';
```js
import fs from 'node:fs/promises'
```

This is a new feature and may not work in older versions of Node.js. While you can opt out of using it, your dependencies may still be using it (example package using `node:`: [path-exists](https://github.com/sindresorhus/path-exists/blob/7c95f5c1f5f811c7f4dac78ab5b9e258491f03af/index.js#L1)).

Pass in a Node.js target that that doesn't support it to strip the `node:` protocol from imports:

```sh
pkgroll --target=node12.19
```
pkgroll --target node12.19

### Export condition

Similarly to the target, the export condition specifies which fields to read from when evaluating [export](https://nodejs.org/api/packages.html#exports) and [import](https://nodejs.org/api/packages.html#imports) maps.

For example, to simulate import resolutions in Node.js, pass in `node` as the export condition:
```sh
pkgroll --export-condition=node
```


### ESM ⇄ CJS interoperability

Node.js ESM offers [interoperability with CommonJS](https://nodejs.org/api/esm.html#interoperability-with-commonjs) via [static analysis](https://github.com/nodejs/cjs-module-lexer). However, not all bundlers compile ESM to CJS syntax in a way that is statically analyzable.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -66,7 +66,7 @@
"rollup": "^2.70.2"
},
"devDependencies": {
"@pvtnbr/eslint-config": "^0.20.0",
"@pvtnbr/eslint-config": "^0.20.1",
"@types/node": "^17.0.30",
"@types/rimraf": "^3.0.2",
"cleye": "^1.2.0",
Expand Down
16 changes: 8 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/cli.ts
Expand Up @@ -50,6 +50,10 @@ const argv = cli({
}],
description: 'Compile-time environment variables (eg. --env.NODE_ENV=production)',
},
exportCondition: {
type: [String],
description: 'Export conditions for resolving dependency export and import maps (eg. --export-condition=node)',
},
},

help: {
Expand Down
9 changes: 8 additions & 1 deletion src/utils/get-rollup-configs.ts
Expand Up @@ -16,6 +16,7 @@ import { resolveTypescriptMjsCts } from './rollup-plugins/resolve-typescript-mjs
type Options = {
minify: boolean;
target: string[];
exportCondition: string[];
env: {
key: string;
value: string;
Expand Down Expand Up @@ -70,6 +71,7 @@ const getConfig = {
}),
nodeResolve({
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'],
exportConditions: options.exportCondition,
}),
...(
Object.keys(env).length > 0
Expand Down Expand Up @@ -167,7 +169,12 @@ export async function getRollupConfigs(

let config = configs.app;
if (!config) {
config = getConfig.app(flags, aliases, env, executablePaths);
config = getConfig.app(
flags,
aliases,
env,
executablePaths,
);
config.external = external;
configs.app = config;
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tests/fixture-package/src/dependency-imports-map.js
@@ -0,0 +1,3 @@
import value from 'dependency-imports-map';

console.log(value);
36 changes: 36 additions & 0 deletions tests/specs/builds/dependencies.ts
Expand Up @@ -60,5 +60,41 @@ export default testSuite(({ describe }, nodePath: string) => {

await fixture.cleanup();
});

test('imports map - default', async () => {
const fixture = await createFixture('./tests/fixture-package');

await fixture.writeJson('package.json', {
main: './dist/dependency-imports-map.js',
});

const pkgrollProcess = await pkgroll([], { cwd: fixture.path, nodePath });

expect(pkgrollProcess.exitCode).toBe(0);
expect(pkgrollProcess.stderr).toBe('');

const content = await fixture.readFile('dist/dependency-imports-map.js', 'utf8');
expect(content).toMatch('default');

await fixture.cleanup();
});

test('imports map - node', async () => {
const fixture = await createFixture('./tests/fixture-package');

await fixture.writeJson('package.json', {
main: './dist/dependency-imports-map.js',
});

const pkgrollProcess = await pkgroll(['--export-condition=node'], { cwd: fixture.path, nodePath });

expect(pkgrollProcess.exitCode).toBe(0);
expect(pkgrollProcess.stderr).toBe('');

const content = await fixture.readFile('dist/dependency-imports-map.js', 'utf8');
expect(content).toMatch('node');

await fixture.cleanup();
});
});
});

0 comments on commit 392096c

Please sign in to comment.