Skip to content

Commit

Permalink
feat: add support for dts.config.ts (#132)
Browse files Browse the repository at this point in the history
* feat: add support for dts.config.ts

attempts to load dts.config.ts if it is available,
throws an error if unable to load it. if dts.config.ts
isn't available, moves on to check for dts.config.js.

enables type declarations in tsconfig.json so that
people can import types correctly.

this commit does not include documentation about how
to use dts.config.ts as type exports should probably
be revisited.

closes #128

* test: use native typescript syntax for dts.config.ts

* docs: add docs on dts.config.ts
  • Loading branch information
ToppleTheNun authored Feb 14, 2022
1 parent 4768b77 commit a5b4365
Show file tree
Hide file tree
Showing 14 changed files with 254 additions and 9 deletions.
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ DTS comes with the "battery-pack included" and is part of a complete TypeScript
- Jest test runner setup with sensible defaults via `dts test`
- ESLint with Prettier setup with sensible defaults via `dts lint`
- Zero-config, single dependency
- Escape hatches for customization via `.babelrc.js`, `jest.config.js`, `.eslintrc.js`, and `dts.config.js`
- Escape hatches for customization via `.babelrc.js`, `jest.config.js`, `.eslintrc.js`, and `dts.config.js`/`dts.config.ts`

## Quick Start

Expand Down Expand Up @@ -336,7 +336,9 @@ DTS can automatically rollup TypeScript type definitions into a single `index.d.
> **❗⚠️❗ Warning**: <br>
> These modifications will override the default behavior and configuration of DTS. As such they can invalidate internal guarantees and assumptions. These types of changes can break internal behavior and can be very fragile against updates. Use with discretion!
DTS uses Rollup under the hood. The defaults are solid for most packages (Formik uses the defaults!). However, if you do wish to alter the rollup configuration, you can do so by creating a file called `dts.config.js` at the root of your project like so:
DTS uses Rollup under the hood. The defaults are solid for most packages (Formik uses the defaults!). However, if you do wish to alter the rollup configuration, you can do so by creating a file called `dts.config.js` (or `dts.config.ts`) at the root of your project like so:

**dts.config.js**

```js
// Not transpiled with TypeScript or Babel, so use plain Es6/Node.js!
Expand All @@ -348,10 +350,23 @@ module.exports = {
};
```

**dts.config.ts**

```typescript
import { DtsOptions, RollupOptions } from 'dts-cli';

export default {
// This function will run for each entry/format/env combination
rollup(config: RollupOptions, options: DtsOptions) {
return config; // always return a config.
},
};
```

The `options` object contains the following:

```tsx
export interface TsdxOptions {
export interface DtsOptions {
// path to file
input: string;
// Name of package
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"bin": {
"dts": "./dist/index.js"
},
"typings": "./dist/index.d.ts",
"scripts": {
"prepare": "tsc -p tsconfig.json",
"build": "tsc -p tsconfig.json",
Expand Down Expand Up @@ -106,6 +107,7 @@
"sort-package-json": "^1.53.1",
"tiny-glob": "^0.2.9",
"ts-jest": "^27.1.3",
"ts-node": "^10.5.0",
"tslib": "^2.3.1",
"type-fest": "^2.10.0",
"typescript": "^4.5.5"
Expand All @@ -114,6 +116,7 @@
"@commitlint/cli": "^16.1.0",
"@commitlint/config-conventional": "^16.0.0",
"@release-it/conventional-changelog": "^4.1.0",
"@types/cssnano": "^5.0.0",
"@types/eslint": "^8.4.1",
"@types/figlet": "^1.5.4",
"@types/fs-extra": "^9.0.13",
Expand Down
3 changes: 2 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export const paths = {
appErrorsJson: resolveApp('errors/codes.json'),
appErrors: resolveApp('errors'),
appDist: resolveApp('dist'),
appConfig: resolveApp('dts.config.js'),
appConfigJs: resolveApp('dts.config.js'),
appConfigTs: resolveApp('dts.config.ts'),
jestConfig: resolveApp('jest.config.js'),
progressEstimatorCache: resolveApp('node_modules/.cache/.progress-estimator'),
};
18 changes: 16 additions & 2 deletions src/createBuildConfigs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { paths } from './constants';
import { DtsOptions, NormalizedOpts, PackageJson } from './types';

import { createRollupConfig } from './createRollupConfig';
import logError from './logError';
import { interopRequireDefault } from './utils';

// check for custom dts.config.js
let dtsBuildConfig = {
Expand All @@ -14,8 +16,20 @@ let dtsBuildConfig = {
},
};

if (fs.existsSync(paths.appConfig)) {
dtsBuildConfig = require(paths.appConfig);
if (fs.existsSync(paths.appConfigTs)) {
try {
require('ts-node').register({
compilerOptions: {
module: 'CommonJS',
},
});
dtsBuildConfig = interopRequireDefault(require(paths.appConfigTs)).default;
} catch (error) {
logError(error);
process.exit(1);
}
} else if (fs.existsSync(paths.appConfigJs)) {
dtsBuildConfig = require(paths.appConfigJs);
}

export async function createBuildConfigs(
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -655,3 +655,6 @@ prog
);

prog.parse(process.argv);

export { RollupOptions } from 'rollup';
export { DtsOptions } from './types';
5 changes: 5 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,8 @@ export function getReactVersion({
export function getNodeEngineRequirement({ engines }: PackageJson) {
return engines && engines.node;
}

// copied from https://github.com/facebook/jest/blob/5b14366bf3726d48c67b1c6609764556052d909f/packages/jest-util/src/interopRequireDefault.ts#L10
export function interopRequireDefault(obj: any): any {
return obj && obj.__esModule ? obj : { default: obj };
}
64 changes: 64 additions & 0 deletions test/integration/dts-build-withConfigTs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as fs from 'fs-extra';
import * as shell from 'shelljs';

import * as util from '../utils/fixture';
import { execWithCache } from '../utils/shell';

shell.config.silent = false;

const testDir = 'integration';
const fixtureName = 'build-withConfigTs';
const stageName = `stage-integration-${fixtureName}`;

describe('integration :: dts build :: dts-config.ts', () => {
beforeAll(() => {
util.teardownStage(stageName);
util.setupStageWithFixture(testDir, stageName, fixtureName);
});

it('should create a CSS file in the dist/ directory', () => {
const output = execWithCache('node ../dist/index.js build');

// TODO: this is kind of subpar naming, rollup-plugin-postcss just names it
// the same as the output file, but with the .css extension
expect(shell.test('-f', 'dist/build-withconfigts.cjs.development.css'));

expect(output.code).toBe(0);
});

it('should autoprefix and minify the CSS file', async () => {
const output = execWithCache('node ../dist/index.js build');

const cssText = await fs.readFile(
'./dist/build-withconfigts.cjs.development.css'
);

// autoprefixed and minifed output
expect(
cssText.includes('.test::-moz-placeholder{color:"blue"}')
).toBeTruthy();

expect(output.code).toBe(0);
});

it('should compile files into a dist directory', () => {
const output = execWithCache('node ../dist/index.js build');

expect(shell.test('-f', 'dist/index.js')).toBeTruthy();
expect(
shell.test('-f', 'dist/build-withconfigts.cjs.development.js')
).toBeTruthy();
expect(
shell.test('-f', 'dist/build-withconfigts.cjs.production.min.js')
).toBeTruthy();
expect(shell.test('-f', 'dist/build-withconfigts.esm.js')).toBeTruthy();

expect(shell.test('-f', 'dist/index.d.ts')).toBeTruthy();

expect(output.code).toBe(0);
});

afterAll(() => {
util.teardownStage(stageName);
});
});
30 changes: 30 additions & 0 deletions test/integration/fixtures/build-withConfigTs/dts.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { DtsOptions, RollupOptions } from '../src';
import autoprefixer from 'autoprefixer';
import cssnano from 'cssnano';
import postcss from 'rollup-plugin-postcss';

// This is necessary due to how typechecking works with the @types/cssnano
// package. If you remove the `if` check below and attempt to add the cssnano
// processor directly, you run into issues with type stack depth.
const getPlugins = () => {
const plugins: any[] = [autoprefixer()];
const cssnanoProcessor = cssnano({ preset: 'default' });
if ('version' in cssnanoProcessor) {
plugins.push(cssnanoProcessor);
}
return plugins;
};

export default {
rollup(config: RollupOptions, options: DtsOptions) {
config?.plugins?.push(
postcss({
plugins: getPlugins(),
inject: false,
// only write out CSS for the first bundle (avoids pointless extra files):
extract: !!options.writeMeta,
})
);
return config;
},
};
7 changes: 7 additions & 0 deletions test/integration/fixtures/build-withConfigTs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"scripts": {
"build": "dts build"
},
"name": "build-withconfigts",
"license": "MIT"
}
4 changes: 4 additions & 0 deletions test/integration/fixtures/build-withConfigTs/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* ::placeholder should be autoprefixed, and everything minified */
.test::placeholder {
color: 'blue';
}
8 changes: 8 additions & 0 deletions test/integration/fixtures/build-withConfigTs/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import './index.css';

export const sum = (a: number, b: number) => {
if ('development' === process.env.NODE_ENV) {
console.log('dev only output');
}
return a + b;
};
25 changes: 25 additions & 0 deletions test/integration/fixtures/build-withConfigTs/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"baseUrl": ".",
"module": "ESNext",
"lib": ["dom", "esnext"],
"declaration": true,
"sourceMap": true,
"rootDir": "./src",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"paths": {
"dts-cli": ["../src"]
}
},
"include": ["src", "types"]
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"importHelpers": true,
"esModuleInterop": true,
"outDir": "dist",
"declaration": false,
"declaration": true,
"module": "commonjs",
"rootDir": "src",
"strict": true,
Expand Down
Loading

0 comments on commit a5b4365

Please sign in to comment.