@keeex/tslib

1.19.3 • Public • Published

@keeex/tslib

Helper for the build process of typescript libraries.

Quick setup

  • install this library as a dev dependency (npm install @keeex/tslib)
  • put all your TypeScript source in /src
  • have all your links/scripts that reference compiled JS look into /lib
  • put all tests either in files named *.test.ts alongside the rest of the code or in /src/tests (you can mix, to have test-specific modules there)
  • if it's not a library but a final "service" or "tool" kind of project add "tslib":{"noDeclarations": false} to "package.json"
  • configure build script in "package.json" to run tslib build (also have that somewhere in prepack if applicable)
  • configure test script in "package.json" to run tslib test
  • you can use npx tsnode <script> to run a TypeScript script directly

Configuration

This project uses the following configurations from the "tslib" section in the caller's project's package.json.

The section is not mandatory; if missing, default values are used.

{
  "buildDir": "lib",
  "webDir": "web",
  "subpackageDir": "subpackages",
  "excludeFromBuild": [],
  "jsx": "react-native",
  "noDeclarations": false,
  "srcDir": "src",
  "testPattern": "mixed",
  "typesDir": "types",
  "typedoc": true,
  "buildWeb": false,
  "knip": true,
  "noMinify": true,
  "storybook": undefined,
  "entrypoints": [],
  "webDependency": [],
}

buildDir

Directory into which the output will be put. Avoid sharing this directory with other resources, as a full build will erase the whole directory.

webDir

Directory for the Babel output. See "Browser Build" below.

excludeFromBuild

Do not build files that match any of the globs provided here. The paths are relative to srcDir.

jsx

Option to pass to the react attribute in tsconfig.json. An empty string means the value is unset. Valid values are the same as those accepted by TypeScript ("preserve", "react", "react-native", "react-jsx", "react-jsxdev"). Usual value when JavaScript files are then babelized is "react-native" to leave JSX untouched.

noDeclarations

Do not generate the type declaration files in the output. Usually needed for libraries; when building a non-library project, setting this to true prevent type declaration files from being emitted.

srcDir

Directory containing the TypeScript source of the project.

testPattern

How tests are organised. The possible options are:

  • "none": no test
  • "mixed": in file named *.test.ts
  • "testDir": all tests are in ${srcDir}/tests/

Currently, this library only supports using mocha-drive tests.

typesDir

Additional typing files can be put in this directory. If configured and present, this directory will be added appropriately in tsconfig.json.

buildWeb

Automatically build the browser version with the build command.

webDependency

List of dependencies that have a "web" version. These packages will see their import renamed from <package>/lib/* to <package>/web/* in the browser build.

All imports from the KeeeX organizations (currently only "@keeex") should be automatically detected and added when the configuration files are generated.

storybook

Enable the generation of storybook-style documentation for React components. The default value (undefined) will enable it automatically if it can find files named *.stories.ts in the source directory. When enabled, a base storybook config will be generated in .storybook/main.ts. This configuration can be extended by creating a file named src/storybook.config.ts that exports a function that will take the base configuration object as its parameter and can edit it (replace src by the configured source directory).

Generated documentation will be put in the apidoc/storybook directory (replace apidoc by the configured directory in typedoc config).

It is possible to customize the base config by providing this object instead of true:

{
  "outputDir": "apidoc/storybook"
}

Integration with typedoc

To display a story you can either:

  • link to the storybook root (./storybook/index.html from the README.md)
  • embed an iframe in markdown:
    <iframe
      src="../storybook/?path=/story/html-accordion--primary&full=1&shortcuts=false&singleStory=true"
      width="950"
      height="400"
      style="width: 100%"
    ></iframe>
    Note that the path must point to the storybook directory, and the slug must match.

entrypoints

List of entrypoints for custom build. An entrypoint is a single file used as the source of the whole dependency tree; only files imported from that entrypoints (and it's dependencies, recursively) will be built when it is invoked. Entrypoint configuration are done using an object whose key is the name of the entrypoint, and the value is an object with the following keys:

  • path: relative path to the entrypoint from the source directory
  • forbiddenImports: an optional array of strings that will be parsed as regex. Any imported file that matches one of these is considered "forbidden" and will raise an error, preventing the build from happening.
  • disableWeb: if web builds are available for this project, entrypoints will be built against them. Use this flag to disable it.
  • license: path to a different license file for this entrypoint. If omitted uses LICENSE
  • subpackage: optional; if present allows building a "subpackage"; merging the output of an entrypoint build with a custom package.json file to create an autonomous package based on the same source tree. See the "Subpackages" section for more details.

knip

Enabled by default. Run knip, a CLI tool that detect export/import issues. When run manually you can add the production argument to only check production files (see below). The configuration used is very basic and consider all files in the source directoy to be part of the project. To mark an export as public, use the jsdoc tag @public. It can also be useful to mark internal exports as @internal, although it will still report them if unused for now.

The configuration entry for knip can either be a boolean to enable/disable it, or an object with the following properties (analogous to the base knip config):

  • entry
  • internal
  • ignore
  • ignoreBinaries
  • ignoreDependencies
  • rules

entry and internal are merged in the knip config entry. entry are marked as "production" (using a !), while internal are left as-is. Both are relative to the configured src directory. Note that test files are automatically marked as "non production". Two binaries are ignored by default: sonar-scanner and publish_check.sh. The ts-node dependency is ignored by knip, because it is possible to use it directly from tslib and not see any reference to it in the parent project. The duplicates rule, filtering items exported multiple times, is set as a warning (it will be displayed but won't prevent the check from being ok). This is often used for deprecation/renaming without breaking compatibility.

noMinify

By default, built files are minified using terser. Disabling this behavior can be useful for debugging and deployment in private servers. It is possible to temporarily enable/disable minification, disregarding this setting, by setting the environment variable TSLIB_MINIFY to "1" or "0".

typedoc

By default, tslib will produce typedoc configuration in the tsconfig-build.json file. All files will be used; however, anything marked private or internal will be ignored. Files excluded from build (test files, etc.) will also be ignored.

Generating typedoc config can be disabled by setting the typedoc property to false. The default output directory is apidoc.

The property can be left empty or set to true to use the defaults. It can also be set using these fields:

{
  "entryPoints": ["path1.ts", "path2.ts"],
  "outputDir": "apidoc",
  "missingImports": true,
  "index": "README.md",
  "sourceLinkTemplate": "https://some.site/{gitRevision}/{path}#{line}"
}

The entryPoints property, if defined, limit the entries that will be immediately visible in the documentation. If not provided, all files in srcDir are used as entry points. All paths are relative to srcDir and can include glob patterns.

The missingImports property can be used to force using the typedoc-plugin-missing-exports. If not specified, the plugin is used when no entrypoints are provided. Otherwise, it can be forced on or off.

The index proprty indicates a markdown file to use as content for the index page of the generated doc.

The sourceLinkTemplate is optional and is used to create link to source files. Typedoc supports automatic linking to github if the repository uses that, but for other cases a custom link can be provided.

Changes in the project's directory

All TypeScript-related commands will update (if needed) the tsconfig.json file in the project's root. This file will hold the configuration needed for editors/tools to handle all the source code of the project (source and tests). It also does not produce output.

The actual file used to build the project will be named tsconfig-build.json. It will contains directives to exclude test files, if applicable, and to actually produce outputs.

It is safe to commit these files with the project; they are not expected to change unless there is an update to @keeex/tslib.

It will also create a file named .tsbuildinfo used to cache changes during watch mode. This file should be ignored.

If web build are enabled, or triggered manually, a babel.web.json file will be created.

When building entrypoints, the output directory is cleaned and a subdirectory with the entrypoint name is created to contain the generated files. In addition, a dot file named after the entrypoint can be generated at the root of the project.

Usage

Create TypeScript config files

The config files are created/updated automatically with each build commands. If you want to create them by hand without calling for a build you can call

npx tslib init [auto]

If the auto argument is passed to init, missing dependencies are installed automatically.

Building the library

You can trigger a full build of the library by calling

npx tslib build

It will clear the target directory and compile all source files.

Watch build

The watch feature of npx can be triggered using

npx tslib watch

Note that this is for convenience only; it is the same as running npx tsc -w on the build config.

Running the tests

Assuming tests are configured, you can run them using

npx tslib test
# without c8
npx tslib rawtest

This will run all tests using ts-node, mocha and c8. Usual configuration for each of these is applicable. Source directory will be automatically set for c8. The NODE_ENV environment variable will be set to "test".

Tests requires the following dependencies to be available:

  • mocha
  • c8 (except for rawtest)
  • ts-node
  • @swc/core

Any extra arguments provided will be passed as-is to mocha (before the specifications).

Running tests for Sonarqube/reporting

An additional target called reporting is available:

npx tslib reporting

This will configure both c8 and mocha to output their reports into appropriate files (lcov reporter for coverage and xunit.xml for mocha).

This requires the mocha-sonarqube-reporter package to be installed as a dev dependency in addition to the other dependencies required for running tests.

Building from entrypoints

Even if entrypoints are configured, they are not built by default, since their usual use cases requires further action with the output and can conflict with full build. To build from an entrypoint, run the command entrypoint:

npx tslib entrypoint <name> [<1 to output dot dependency graph>]

The first argument can be the string "all", in which case all entrypoints will be built sequentially.

If a second argument is provided, a dot graph file is produced named after the entrypoint. The output of an entrypoint generation is found in <output dir>/<entrypoint name>.

Building API documentation

API Documentation is built using Typedoc. It requires the following packages to be installed:

  • typedoc
  • typedoc-plugin-missing-exports
  • typedoc-plugin-rename-defaults

For convenience a typedoc command is provided which makes sure the configuration is generated before calling typedoc.

Building Storybook documentation

Storybook provides live preview of React components.

It requires the following packages to be installed:

  • @storybook/addon-essentials
  • @storybook/addon-links
  • @storybook/blocks
  • @storybook/react
  • @storybook/react-webpack5
  • storybook

You can run it using this command:

npx tslib storybook build

(omit the build argument to run the live dev version)

Building all documentation

For convenience, a command to build both Typedoc and Storybook is available: doc.

Cleaning up generated content

The generated content (build output, cache and configuration) can be cleaned using:

npx tslib clean
npx tslib clean all

The first form will remove all build output and cache files. If "all" is provided, the generated configuration files are also cleaned.

Checking import/export using knip

You can use this command to generate knip configuration and run it:

npx tslib knip

Checking whole project

For convenience a check command was added that will run the following sequence:

  • generate/update config files
  • check the TypeScript build
  • check the source using eslint
  • check the import/export using knip in production mode

If any of these fails, the process will exit with an error code of 1.

npx tslib check

Browser build

You can use the following command to run a "browser" build:

npx tslib web

This will create the same output as a normal build, but it will be placed in the webDir directory (default /web) and is transpiled with Babel. To do so you need to install the following packages first:

  • @babel/cli
  • @babel/core
  • @babel/preset-env
  • babel-plugin-import-redirect

Calling npx tslib web will manually build the web version. To enable it automatically using npx tslib build set webBuild to true.

Subpackages

To build a subpackage, run the following command:

npx tslib subpackage [<name>]

If no name is provided, all configured subpackages are built. The configuration of a subpackage is done by adding the subpackage property to an entrypoint. The subpackages will be built in the directory pointed by the subpackageDir configuration entry. That property must be an object with the following properties:

  • name: the name of the subpackage (as seen by NPM)
  • packageOverride: properties to change in the output package.json
  • extraFiles: key/value mapping to copy files from the project's root into the subpackage
  • noDoc: set to true to disable typedoc generation (it won't be generated if disabled for the whole project anyway)
  • readme: path to a readme file for this subpackage, relative to the project's root

The output package.json takes the following properties from the base project's package.json file:

  • version
  • description
  • type
  • author
  • contributors
  • license
  • dependencies
  • files

It is possible to add new properties, change their values, and remove them by setting packageOverride. Any value present in this property will replace any other value, and a null value in the override results in the property being removed from the output package.json.

Extra files can be copied from the project's root by providing a mapping into extraFiles.

Subpackages are not minified; they do embed a minification script that is run on npm pack.

Dependencies handling

Unless an override is present, the dependencies property is copied from the original package.json file but dependencies that are not present in the entrypoint output will be removed.

Run TypeScript files directly

You can run TypeScript files directly using npx tsnode <script path>. Contrary to ts-node, this accepts files with the suffix .ts.

Under the hood

The project basically wraps three steps:

  • creating the two tsc config files according to presets and project's settings
  • clean the target directory, run tsc and put the license in output files
  • run mocha with appropriate flags to use c8 and ts-node

Not the hardest thing in the world, but repeated in every projects.

Entrypoints leverage the ability of the TypeScript compiler to only grab dependencies, added with custom code to actually make sure some files are excluded from the build.

Readme

Keywords

none

Package Sidebar

Install

npm i @keeex/tslib

Homepage

keeex.me/oss

Weekly Downloads

3

Version

1.19.3

License

MIT

Unpacked Size

119 kB

Total Files

35

Last publish

Collaborators

  • keeex_jenkins
  • marc-keeex
  • cley_faye