Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Zero-config CLI for TypeScript package development

License

NotificationsYou must be signed in to change notification settings

weiran-zsd/dts-cli

 
 

NPM versionDownloads/monthConventional Commits

a fork of the official tsdx.

$ npm install dts-cli -D# for npm users$ yarn add dts-cli -D# for yarn users$ pnpm install dts-cli -D# for pnpm users

Despite all the recent hype, setting up a new TypeScript (x React) library can be tough. BetweenRollup,Jest,tsconfig,Yarn resolutions, ESLint, and getting VSCode to play nicely....there is just a whole lot of stuff to do (and things to screw up). DTS is a zero-config CLI that helps you develop, test, and publish modern TypeScript packages with ease--so you can focus on your awesome new library and not waste another afternoon on the configuration.

Features

DTS comes with the "battery-pack included" and is part of a complete TypeScript breakfast:

  • Bundles your code withRollup and outputs multiple module formats (CJS & ESM by default, and also UMD if you want) plus development and production builds
  • Comes with treeshaking, ready-to-rock lodash optimizations, and minification/compression
  • Live reload / watch-mode
  • Works with React
  • Human readable error messages (and in VSCode-friendly format)
  • Bundle size snapshots
  • Opt-in to extractinvariant error codes
  • Jest test runner setup with sensible defaults viadts test
  • ESLint with Prettier setup with sensible defaults viadts lint
  • Zero-config, single dependency
  • Escape hatches for customization via.babelrc.js,jest.config.js,.eslintrc.js, anddts.config.js/dts.config.ts

Quick Start

npx dts-cli create mylibcd mylibyarn start

That's it. You don't need to worry about setting up TypeScript or Rollup or Jest or other plumbing. Just start editingsrc/index.ts and go!

Below is a list of commands you will probably find useful:

npm start oryarn start

Runs the project in development/watch mode. Your project will be rebuilt upon changes. DTS has a special logger for your convenience. Error messages are pretty printed and formatted for compatibility VS Code's Problems tab.

Your library will be rebuilt if you make edits.

npm run build oryarn build

Bundles the package to thedist folder.The package is optimized and bundled with Rollup into multiple formats (CommonJS, UMD, and ES Module).

npm test oryarn test

Runs your tests using Jest.

npm run lint oryarn lint

Runs Eslint with Prettier on .ts and .tsx files.If you want to customize eslint you can add aneslint block to your package.json, or you can runyarn lint --write-file and edit the generated.eslintrc.js file.

prepare script

Bundles and packages to thedist folder.Runs automatically when you run eithernpm publish oryarn publish. Theprepare script will run the equivalent ofnpm run build oryarn build. It will also be run if your module is installed as a git dependency (ie:"mymodule": "github:myuser/mymodule#some-branch") so it can be depended on without checking the transpiled code into git.

Setting up VSCode

By default the eslint VSCode extension won't work, since it can't find the configuration file needed in order to start the eslint server. Runnpm run lint -- --write-file in order to write the config file in the correct location.

Optimizations

Aside from just bundling your module into different formats, DTS comes with some optimizations for your convenience. They yield objectively better code and smaller bundle sizes.

After DTS compiles your code with TypeScript, it processes your code with 3 Babel plugins:

Development-only Expressions + Treeshaking

babel-plugin-annotate-pure-calls +babel-plugin-dev-expressions work together to fully eliminate dead code (aka treeshake) development checks from your production code. Let's look at an example to see how it works.

Imagine our source code is just this:

// ./src/index.tsexportconstsum=(a:number,b:number)=>{if(process.env.NODE_ENV!=='production'){console.log('Helpful dev-only error message');}returna+b;};

dts build will output an ES module file and 3 CommonJS files (dev, prod, and an entry file). If you want to specify a UMD build, you can do that as well. For brevity, let's examine the CommonJS output (comments added for emphasis):

// Entry File// ./dist/index.js'use strict';// This determines which build to use based on the `NODE_ENV` of your end user.if(process.env.NODE_ENV==='production'){module.exports=require('./mylib.cjs.production.js');}else{module.exports=require('./mylib.cjs.development.js');}
// CommonJS Development Build// ./dist/mylib.cjs.development.js'use strict';constsum=(a,b)=>{{console.log('Helpful dev-only error message');}returna+b;};exports.sum=sum;//# sourceMappingURL=mylib.cjs.development.js.map
// CommonJS Production Build// ./dist/mylib.cjs.production.js'use strict';exports.sum=(s,t)=>s+t;//# sourceMappingURL=test-react-tsdx.cjs.production.js.map

AS you can see, DTS stripped out the development check from the production code.This allows you to safely add development-only behavior (like more useful error messages) without any production bundle size impact.

For ESM build, it's up to end-user to build environment specific build with NODE_ENV replace (done by Webpack 4 automatically).

Rollup Treeshaking

DTS's rollup configremoves getters and setters on objects so that property access has no side effects. Don't do it.

Advancedbabel-plugin-dev-expressions

DTS will usebabel-plugin-dev-expressions to make the following replacementsbefore treeshaking.

__DEV__

Replaces

if(__DEV__){console.log('foo');}

with

if(process.env.NODE_ENV!=='production'){console.log('foo');}

IMPORTANT: To use__DEV__ in TypeScript, you need to adddeclare var __DEV__: boolean somewhere in your project's type path (e.g../types/index.d.ts).

// ./types/index.d.tsdeclarevar__DEV__:boolean;

Note: Thedev-expression transform does not run whenNODE_ENV istest. As such, if you use__DEV__, you will need to define it as a global constant in your test environment.

invariant

Replaces

invariant(condition,'error message here');

with

if(!condition){if('production'!==process.env.NODE_ENV){invariant(false,'error message here');}else{invariant(false);}}

Note: DTS doesn't supply aninvariant function for you, you need to import one yourself. We recommendhttps://github.com/alexreardon/tiny-invariant.

To extract and minifyinvariant error codes in production into a staticcodes.json file, specify the--extractErrors flag in command line. For more details seeError extraction docs.

warning

Replaces

warning(condition,'dev warning here');

with

if('production'!==process.env.NODE_ENV){warning(condition,'dev warning here');}

Note: DTS doesn't supply awarning function for you, you need to import one yourself. We recommendhttps://github.com/alexreardon/tiny-warning.

Using lodash

If you want to use a lodash function in your package, DTS will help you do it theright way so that your library does not get fat shamed on Twitter. However, before you continue, seriously consider rolling whatever function you are about to use on your own. Anyways, here is how to do it right.

First, installlodash andlodash-es asdependencies

yarn add lodash lodash-es

Now install@types/lodash to your development dependencies.

yarn add @types/lodash --dev

Import your lodash method however you want, DTS will optimize it like so.

// ./src/index.tsimportkebabCasefrom'lodash/kebabCase';exportconstKebabLogger=(msg:string)=>{console.log(kebabCase(msg));};

For brevity let's look at the ES module output.

importofrom"lodash-es/kebabCase";conste=e=>{console.log(o(e))};export{easKebabLogger};//# sourceMappingURL=test-react-tsdx.esm.production.js.map

DTS will rewrite yourimport kebabCase from 'lodash/kebabCase' toimport o from 'lodash-es/kebabCase'. This allows your library to be treeshakable to end consumers while allowing to you to use@types/lodash for free.

Note: DTS will also transform destructured imports. For example,import { kebabCase } from 'lodash' would have also been transformed to `import o from "lodash-es/kebabCase".

Error extraction

After running--extractErrors, you will have a./errors/codes.json file with all your extractedinvariant error codes. This process scans your production code and swaps out yourinvariant error message strings for a corresponding error code (just like React!). This extraction only works if your error checking/warning is done by a function calledinvariant.

Note: We don't provide this function for you, it is up to you how you want it to behave. For example, you can use eithertiny-invariant ortiny-warning, but you must then import the module as a variable calledinvariant and it should have the same type signature.

⚠️Don't forget: you will need to host the decoder somewhere. Once you have a URL, look at./errors/ErrorProd.js and replace thereactjs.org URL with yours.

Known issue: ourtransformErrorMessages babel plugin currently doesn't have sourcemap support, so you will see "Sourcemap is likely to be incorrect" warnings.We would love your help on this.

TODO: Simple guide to host error codes to be completed

Types rollup

DTS can automatically rollup TypeScript type definitions into a singleindex.d.ts file viarollup-plugin-dts plugin. To enable types rollup, add--rollupTypes flag to yourbuild andwatch scripts.

"build":"dts build --rollupTypes","start":"dts watch --rollupTypes",

rollup-plugin-dts was seen to cause issues when using json and less imports. Use with caution.

Customization

Rollup

⚠️❗ Warning:
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 calleddts.config.js (ordts.config.ts) at the root of your project like so:

dts.config.js

// Not transpiled with TypeScript or Babel, so use plain Es6/Node.js!/** *@type {import('dts-cli').DtsConfig} */module.exports={// This function will run for each entry/format/env combinationrollup(config,options){returnconfig;// always return a config.},};

or

constdefineConfig=require('dts-cli').defineConfig;module.exports=defineConfig({// This function will run for each entry/format/env combinationrollup:(config,options)=>{returnconfig;// always return a config.},});

dts.config.ts

import{defineConfig}from'dts-cli';exportdefaultdefineConfig({// This function will run for each entry/format/env combinationrollup:(config,options)=>{returnconfig;// always return a config.},});

Theoptions object contains the following:

exportinterfaceDtsOptions{// path to fileinput:string;// Name of packagename:string;// JS targettarget:'node'|'browser';// Module formatformat:'cjs'|'umd'|'esm'|'system';// Environmentenv:'development'|'production';// Path to tsconfig filetsconfig?:string;// Is error extraction running?extractErrors?:boolean;// Is minifying?minify?:boolean;// Is this the very first rollup config (and thus should one-off metadata be extracted)?writeMeta?:boolean;// Only transpile, do not type check (makes compilation faster)transpileOnly?:boolean;}

Example: Adding Postcss

constpostcss=require('rollup-plugin-postcss');constautoprefixer=require('autoprefixer');constcssnano=require('cssnano');module.exports={rollup(config,options){config.plugins.push(postcss({plugins:[autoprefixer(),cssnano({preset:'default',}),],inject:false,// only write out CSS for the first bundle (avoids pointless extra files):extract:!!options.writeMeta,}));returnconfig;},};

Babel

You can add your own.babelrc to the root of your project and DTS willmerge it withits own Babel transforms (which are mostly for optimization), putting any new presets and plugins at the end of its list.

Jest

You can add your ownjest.config.js to the root of your project and DTS willshallow merge it withits own Jest config.

ESLint

You can add your own.eslintrc.js to the root of your project and DTS willdeep merge it withits own ESLint config.

patch-package

If you still need more customizations, we recommend usingpatch-package so you don't need to fork.Keep in mind that these types of changes may be quite fragile against version updates.

Inspiration

DTS was originally ripped out ofFormik's build tooling.DTS has several similarities to@developit/microbundle, but that is because Formik's Rollup configuration and Microbundle's internals had converged around similar plugins.

Comparison with Microbundle

Some key differences include:

  • DTS includes out-of-the-box test running via Jest
  • DTS includes out-of-the-box linting and formatting via ESLint and Prettier
  • DTS includes a bootstrap command with a few package templates
  • DTS allows for some lightweight customization
  • DTS is TypeScript focused, but also supports plain JavaScript
  • DTS outputs distinct development and production builds (like React does) for CJS and UMD builds. This means you can include rich error messages and other dev-friendly goodies without sacrificing final bundle size.

API Reference

dts watch

Description  Rebuilds on any changeUsage  $ dts watch [options]Options  -i, --entry           Entry module  --target              Specify your target environment  (default web)  --name                Specify name exposedin UMD builds  --format              Specify module format(s)  (default cjs,esm)  --tsconfig            Specify your custom tsconfig path (default<root-folder>/tsconfig.json)  --verbose             Keep outdated console outputin watch mode instead of clearing the screen  --onFirstSuccess      Run acommand on the first successful build  --onSuccess           Run acommand on a successful build  --onFailure           Run acommand on a failed build  --noClean             Don't clean the dist folder  --transpileOnly       Skip type checking  --rollupTypes         Enable types rollup  -h, --help            Displays this messageExamples  $ dts watch --entry src/foo.tsx  $ dts watch --target node  $ dts watch --name Foo  $ dts watch --format cjs,esm,umd  $ dts watch --tsconfig ./tsconfig.foo.json  $ dts watch --noClean  $ dts watch --onFirstSuccess "echo The first successful build!"  $ dts watch --onSuccess "echo Successful build!"  $ dts watch --onFailure "echo The build failed!"  $ dts watch --transpileOnly

dts build

Description  Build your project once andexitUsage  $ dts build [options]Options  -i, --entry           Entry module  --target              Specify your target environment  (default web)  --name                Specify name exposedin UMD builds  --format              Specify module format(s)  (default cjs,esm)  --extractErrors       Opt-in to extracting invariant error codes  --tsconfig            Specify your custom tsconfig path (default<root-folder>/tsconfig.json)  --transpileOnly       Skiptype checking  --rollupTypes         Enable types rollup  -h, --help            Displays this messageExamples  $ dts build --entry src/foo.tsx  $ dts build --target node  $ dts build --name Foo  $ dts build --format cjs,esm,umd  $ dts build --extractErrors  $ dts build --tsconfig ./tsconfig.foo.json  $ dts build --transpileOnly

dts test

This runs Jest, forwarding all CLI flags to it. Seehttps://jestjs.io for options. For example, if you would like to run in watch mode, you can rundts test --watch. So you could set up yourpackage.jsonscripts like:

{"scripts": {"test":"dts test","test:watch":"dts test --watch","test:coverage":"dts test --coverage"  }}

dts lint

Description  Run eslint with PrettierUsage  $ dts lint [options]Options  --fix               Fixes fixable errors and warnings  --ignore-pattern    Ignore a pattern  --max-warnings      Exits with non-zero error codeif number of warnings exceed this number  (default Infinity)  --write-file        Write the config file locally  --report-file       Write JSON report to file locally  -h, --help          Displays this messageExamples  $ dts lint src  $ dts lint src --fix  $ dts lint srctest --ignore-pattern test/foo.ts  $ dts lint srctest --max-warnings 10  $ dts lint src --write-file  $ dts lint src --report-file report.json

dts create

Description  Create a new package with DTSUsage  $ dts create<pkg> [options]Options  --template    Specify a template. Allowed choices: [basic, react, react-with-storybook]  --husky       Should husky be added to the generated project?  (default true)  -h, --help    Displays this messageExamples  $ dts create mypackage  $ dts create --template react mypackage  $ dts create --husky mypackage  $ dts create --no-husky mypackage  $ dts create --huskyfalse mypackage

Multiple Entry Files

You can rundts watch ordts build with multiple entry files, for example:

dts build \  --entry ./src/index.ts \  --entry ./src/foo.ts \  --entry ./src/subdir/index.ts \  --entry ./src/globdir/**/*.ts

When given multiple entries, dts-cli will output separate bundles for each file for each format, as well as theirdeclarations. Each file will be output todist/ with the same name it has in thesrc/ directory. Entries insubdirectories ofsrc/ will be mapped to equivalently named subdirectories indist/.dts-cli will also expand any globs.

Contributing

Please see theContributing Guidelines.

Author

License

MIT

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Jared Palmer

📖🎨👀🔧⚠️🚧💻

swyx

🐛💻📖🎨🤔🚇🚧👀

Jason Etcovitch

🐛⚠️

Sam Kvale

💻⚠️🐛📖👀🤔💬

Lucas Polito

💻📖💬

Steven Kalt

💻

Harry Hedger

🤔📖💻💬

Arthur Denner

🐛💻💬

Carl

🤔📖💻⚠️💬

Loïc Mahieu

💻⚠️

Sebastian Sebald

📖💻⚠️

Karl Horky

📖🤔

James George

📖

Anton Gilgur

🚧📖💻🐛💡🤔💬👀⚠️

Kyle Holmberg

💻💡⚠️👀💬

Sigurd Spieckermann

🐛💻

Kristofer Giltvedt Selbekk

💻

Tomáš Ehrlich

🐛💻

Kyle Johnson

🐛💻

Etienne Dldc

🐛💻⚠️

Florian Knop

🐛

Gonzalo D'Elia

💻

Alec Larson

💻👀🤔💬

Justin Grant

🐛🤔💬

Jirat Ki.

💻⚠️🐛

Nate Moore

💻🤔

Haz

📖

Basti Buck

💻🐛

Pablo Saez

💻🐛

Jake Gavin

🐛💻

Grant Forrest

💻⚠️🐛

Sébastien Lorber

💻

Kirils Ladovs

📖

Enes Tüfekçi

💻📖

Bogdan Chadkin

👀💬🤔

Daniel K.

💻📖⚠️🤔🐛

Quentin Sommer

📖

Hyan Mandian

💻⚠️

Sung M. Kim

🐛💻

John Johnson

💻📖

Jun Tomioka

💻⚠️

Leonardo Dino

💻🐛

Honza Břečka

💻🐛

Ward Loos

💻🤔

Brian Bugh

💻🐛

Cody Carse

📖

Josh Biddick

💻

Jose Albizures

💻⚠️🐛

Rahel Lüthy

📖

Michael Edelman

💻🤔

Charlike Mike Reagent

👀💻🤔

Frederik Wessberg

💬

Elad Ossadon

💻⚠️🐛

Kevin Kipp

💻

Matija Folnovic

💻📖

Andrew

💻

Ryan Castner

💻⚠️🤔

Yordis Prieto

💻

NCPhillips

📖

Arnaud Barré

💻📖

Peter W

📖

Joe Flateau

💻📖

H.John Choi

📖

Jon Stevens

📖🤔🐛

greenkeeper[bot]

🚇💻

allcontributors[bot]

🚇📖

dependabot[bot]

🚇🛡️💻

GitHub

🚇

Eugene Samonenko

⚠️💡💬🤔

Joseph Wang

🐛

Kotaro Sugawara

🐛💻

Semesse

💻

Bojan Mihelac

💻

Dan Dascalescu

📖

Yuriy Burychka

💻

Jesse Hoyos

💻

Mike Deverell

💻

Nick Hehr

💻📖💡

Bnaya Peretz

🐛💻

Andres Alvarez

💻📖💡

Yaroslav K.

📖

Dragoș Străinu

🤔

George Varghese M.

💻📖⚠️

Reinis Ivanovs

🤔💬

Orta Therox

💬📖

Martijn Saly

🐛

Alex Johansson

📖

hb-seb

💻

seungdols

🐛

Béré Cyriac

🐛

Dmitriy Serdtsev

🐛

Vladislav Moiseev

💻

Felix Mosheev

🐛📖

Ludovico Fischer

💻

Altrim Beqiri

🐛💻⚠️

Tane Morgan

🐛💻

This project follows theall-contributors specification. Contributions of any kind welcome!

About

Zero-config CLI for TypeScript package development

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Languages

  • TypeScript70.8%
  • JavaScript28.3%
  • Other0.9%

[8]ページ先頭

©2009-2025 Movatter.jp