This entire section with all its subsections (Installation, Tooling, Scripts) should be removed from your
src/docs/index.md
after installing. The rest of sections may be useful for your package readme, and you may just modified them insrc/docs/index.md
to meet your needs.
This is a skeleton for developing JS modules in Typescript that work both in Node.js and native JavaScript. The idea is that you should just focus on developing your typescript code in the src/ts
folder, and the necessary JS files and bundles will be created so that it can be used with no effort in every environment.
You can use string variable IS_BROWSER
to create specific code for native JS or Node. For example:
if (IS_BROWSER === 'true') {
// browser specific code here
} else {
// node.js specific code here
}
Besides the actual code, you should create unit testing (mocha+chai) files either in the test
or the src/ts
directory, although in the latter case only files ending with .spec.ts
or .test.ts
will be considered as test files.
When creating the tests, you MUST NOT import either mocha
, chai
or your package. They have been automatically added to the global scope. You must import your module with the shortcut #pkg
. In short:
-
mocha
global variable points to mocha; -
chai
points to chai; -
#pkg
points to your package (all your JavaScript exports). Use it instead any relative import when importing your module in your tests (it must be first built withnpm run build:js
). For instance:import * as myModule from '#pkg' ...
You can also use a .env
file with environment variables that can be accessed in process.env
in your tests' source files running both in node and browser javascript.
If you want your module typings to be compatible with
node16
andnodenext
module resolution (which require extensions for relative imports), please consider adding the.js
to any relative import you are using. For instance:import { myFn } from './utils.js'or:
import { myFn } from './utils/index.js'instead of
import { myFn } from './utils'
Clone this repo to your desired project directory (my-project
in the following example) and reset the git.
git clone https://github.com/juanelas/node-browser-skel.git my-project
cd my-project
rm -rf .git
git init
git add -A
Edit package.json
keys: name
, description
, keywords
, author
, repository
(or delete line if you do not have one), and license
(if you change license type, please update LICENSE
file with your chosen one).
In package.json
->nodeBrowserSkel
you can configure things like the default branch for the workflows, the badges to appear in the readme and whether to sync with https://coveralls.io/ as part of the github workflow after a new version push.
Initialize the project with:
npm i
npm update
npm run build
The README.md
file is automatically generated from the src/docs/index.md
file. EDIT src/docs/index.md
and rewrite it to your heart's content. Recall removing the section "Skeleton for developing modules for browser and Node.js in Typescript" with all its subsections (Installation, Tooling, Scripts).
- Build: Rollup is used for generating in the
dist
directory UMD, IIFE, ESM and CJS modules with the corresponding Typescript declaration files and sourcemaps. - Coverage: c8 is used to track how well your unit-tests exercise your codebase.
- Doc: TsCode is used for automatically generating the API docs. Consider documenting your code with TsCode for it to be useful.
- Lint: ts-stamdard is the chosen linter, although you can easily change it by any other linter (update the
lint
script in thepackage.json
). If developing with Visual Studio Code, consider installing the Standard-JS extension and selectts-standard
as theStandard:engine
in the extension settings. - Test: Mocha with Chai running both in Node.js and browser (using puppeteer). Test files should be created assuming that Mocha methods and Chai are declared global, so there is no need to import them (see the provided test examples). There is also no need to create separate test files for browser and Node.js, since every file will be tested against both.
-
npm run build
. First runs the linter (same asnpm run lint
), then builds the JS files (npm run build:js
), and finally builds theREADME.md
and the API doc./docs/API.md
(npm run docs
). See the specific scripts for more details. -
npm run build:js
. Creates your distributable module files (UMD, IIFE, ESM and CJS), along with the sourcemap and typescript declaration files in thedist
directory. -
npm run clean
. Cleans all the artefacts created by the rest of the script (most likely not needed). -
npm run coverage
. Runs all the unit tests (src/**/*.spec.ts
,src/**/*.test.ts
andtest/**/*.ts
) in Node.js and track how well they exercise your codebase. Besides the on-screen summary, a complete report in HTML will be generated in thecoverage
directory. -
npm run docs
. Generates theREADME.md
and the API doc./docs/API.md
(consider documenting your exported classes/functions using TSDoc for a meaningful API doc). Some labels in thesrc/README.md
file will be automatically replaced in the generatedREADME.md
:- {{PKG_NAME}} is automatically replaced with property
name
inpackage.json
file. - {{PKG_NAME_NO_SCOPE}} is automatically replaced with property
name
inpackage.json
file without the scope. E.g.@juanelas/my-pkg
would becomemy-pkg
. - {{PKG_DESCRIPTION}} is automatically replaced with property
description
inpackage.json
file. - {{PKG_CAMELCASE}} will be replaced by a camel case transformation of the package name.
- {{IIFE_BUNDLE}} will point to the IIFE bundle file if using github or gitlab as repository.
- {{ESM_BUNDLE}} will point to the ESM bundle file if using github or gitlab as repository.
- {{UMD_BUNDLE}} will point to the UMD bundle file if using github or gitlab as repository.
- It has also some automatically added badges (see the top of this file), that you can remove if desired.
- {{PKG_NAME}} is automatically replaced with property
-
npm run lint
. Uses thets-standard
linter to fix all the project files. If uncomfortable, change the linter for the one of your liking. -
npm run mocha-ts -- <glob>
. Runs Node.js mocha for the selected tests (use glob pattern) using the ESM version. Ifglob
is empty, it will test all the tests. Add--watch
before the glob to start mocha in watch mode. -
npm run mocha-ts:cjs -- <glob>
. Runs Node.js mocha for the selected tests (use glob pattern) using the CJS version. Ifglob
is empty, it will test all the tests. Add--watch
before the glob to start mocha in watch mode. -
npm run mocha-ts:browser
. Runs all mocha tests n a browser (using puppeteer) for the selected tests (use glob pattern). -
npm run mocha-ts:browser-headless
. Silently runs all mocha tests in a browser but without opening a browser window (results will be shown in the node's console). This is useful for just running tests (no debugging). -
npm test
. Runs all the unit tests (src/**/*.spec.ts
,src/**/*.test.ts
andtest/**/*.ts
) for the ESM and CJS modules in Node.js, and the ESM module bundle in a browser (using puppeteer). -
npm run test:browser
. Runs all the unit tests (src/**/*.spec.ts
,src/**/*.test.ts
andtest/**/*.ts
) in a browser (using puppeteer). Until the browser window is closed, you can debug the tests. -
npm run test:browser-headless
. Runs all the unit tests (src/**/*.spec.ts
,src/**/*.test.ts
andtest/**/*.ts
) in a browser (using puppeteer) but without opening a windows (results will be shown in the node's console). This is useful for just running tests (no debugging). -
npm run test:node
. Runs all the unit tests (src/**/*.spec.ts
,src/**/*.test.ts
andtest/**/*.ts
) for the ESM and CJS modules in Node.js. -
npm run watch -- <spec>
. Likely to be the default script during development. Tests are automatically reexecuted whenever a test or source file changes. You can optionally pass in<spec>
one or more files, directories, or globs to test (default:"{src/ts/**/*.spec.ts,src/ts/**/*.test.ts,test/**/*.ts}"
)
My package is wonderful.
@my-scope/my-package-name
can be imported to your project with npm
:
npm install @my-scope/my-package-name
Then either require (Node.js CJS):
const myPackageName = require('@my-scope/my-package-name')
or import (JavaScript ES module):
import * as myPackageName from '@my-scope/my-package-name'
The appropriate version for browser or node should be automatically chosen when importing. However, if your bundler does not import the appropriate module version (node esm, node cjs or browser esm), you can force it to use a specific one by just importing one of the followings:
@my-scope/my-package-name/dist/cjs/index.node
: for Node.js CJS module@my-scope/my-package-name/dist/esm/index.node
: for Node.js ESM module@my-scope/my-package-name/dist/esm/index.browser
: for browser ESM moduleIf you are coding TypeScript, types will not be automatically detected when using the specific versions. You can easily get the types in by creating and importing to your TS project a new types declaration file
my-package-name.d.ts
with the following line:declare module '@my-scope/my-package-name/dist/esm/index.browser' // use the specific module file you are importing
You can also build the project with npm run build
and get the ESM, IIFE and/or UMD module files fomr dist/bundles
.
YOUR TYPESCRIPT EXAMPLE CODE HERE