NPM Cheat Sheet

Package Creation Steps
1. Git, NPM, Files
- GitHub: Create a new repository using github.com
- repo name should be kebab case, i.e
package-name, instead of snake_case or camelCase. - add description
- choose public
- Initialize with a README
- Choose a license: MIT
- don't create
.gitignorefile.
- repo name should be kebab case, i.e
- Local: Clone repo
git clone <package repo url> - Local: Create
.gitignorefile
node_modules
lib
I prefer
libfor libraries and CLI tools. I preferdistfor sites. YMMV.
- Local: Initialize project
package.jsonfile as a Node packagenpm init- choose "MIT" for license to match what is in the repo
- choose 0.0.6 for initial version (1.0.0 for first 'release')
- choose defaults for others
- Local: Edit
package.json- fix up fields, such as 'description'
- replace author field with an object with more information.
- add
sideEffects:falseif you won't have sideEffects
{
"sideEffects": false,
"author": {
"name": "John Pennock",
"email": "info@pennockprojects.com",
"url": "https://pennockprojects.com"
}
}
Side Effects The "sideEffects" key is used when a module affects something outside of the module, like a browser variable. Typically we don't want sideEffects and setting to
falsegives us benefits in bundling
"sideEffects": false"sideEffects": ["someModuleWithSideEffects", "someOtherModuleWithSideEffects"]"sideEffects": ["*.js"]
- Choose NPM Name
- Decide Scoped (Preferred) or Non-Scoped
- Scoped Packages
@npm_user_name/some-cool-package-name- kebab casing
- private by default (costs money at npmjs.org)
- easy to avoid duplicates can match GitHub repo name
- can be public if
npm publish --access publicwhen publishing
- Non-scoped Packages
some-cool-package-name- kebab casing
- public always
- search npmjs.org for duplicates
- must be a unique
- Scoped Packages
- Update
package.json"name"field to your NPM package name.
- Decide Scoped (Preferred) or Non-Scoped
- Directories
./src- package source file root./src/utils- package source files./lib- output directory for packages/APIs./tests- test directory
- Create skeleton files.
- Library entrance point file
./src/index.ts
export { helloWorld } from './utils/helloWorld'
- Library Function file, i.e.
./src/util/helloWorld.ts
export function helloWorld(name: string): string {
return `Hello, ${name || "World"}!`;
}
2. Setup TypeScript
- Local: install Typescript in package as dev dependency
npm install --save-dev typescript @types/node
- Local: create
tsconfig.jsonmanually or use TypeScript CLInpx tsc --init
Here is the recommended tsconfig.json options
{
"compilerOptions": {
"declaration": true,
"declarationDir": "lib/types",
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"outDir": "lib",
"resolveJsonModule": true,
"skipDefaultLibCheck": true,
"sourceMap": true,
"target": "esnext"
},
"include": [ "src" ],
"exclude": [
"node_modules",
"lib"
],
}
3. Setup Bundler Rollup
A. Install Rollup with TypeScript and Delete Plugins
rollup-plugin-typescript2- allows for typescript supportrollup-plugin-delete- deleteslibdirectory on each build
npm install --save-dev rollup rollup-plugin-typescript2 rollup-plugin-delete
B. Install Rollup plugins
@rollup/plugin-node-resolve- findnode_modulespackages@rollup/plugin-json- converts .json files to ES6 modules@rollup/plugin-commonjs- converts CommonJS modules to ES6
npm install --save-dev @rollup/plugin-node-resolve @rollup/plugin-json @rollup/plugin-commonjs
C. Create a rollup configuration file rollup.config.js
- creates both COMMONJS `cjs` and ESM `esm` library modules
import commonjs from '@rollup/plugin-commonjs';
import del from 'rollup-plugin-delete';
import json from '@rollup/plugin-json';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import typescript from 'rollup-plugin-typescript2';
export default {
input: 'src/index.ts',
output: [
{
file: 'lib/index.cjs',
format: 'cjs',
sourcemap: true,
inlineDynamicImports: true,
},
{
file: 'lib/index.esm.js',
format: 'es',
sourcemap: true,
inlineDynamicImports: true,
}
],
plugins: [
del({ targets: 'lib/*' }),
json(),
commonjs(),
nodeResolve({ browser: false, preferBuiltins: true }),
typescript({ useTsconfigDeclarationDir: true })
]
}
D. Peer Dependencies (Optional)
Add package.son peerDependencies keys to rollup.config.js
const packageJson = require("./package.json");
const external = [...Object.keys(packageJson.peerDependencies || {})];
export default {
// ...
external
};
E. Update package.json for rollup.
- update "main" to
"main": "lib/index.cjs" - update "scripts" to include
"build": "rollup -c" - add
type,exports, andfiles - the
fileskey says which files in our repo should be bundled in the npm package. LICENSE,package.json, and README.MD are automatically included.
Here a snippet for both modified and new key:values for package.json, you will have to merge manually with existing package.json file.
{
"type": "module",
"main": "lib/index.cjs",
"exports": {
"import": {
"types": "./lib/types/index.d.ts",
"default": "./lib/index.esm.js"
},
"require": {
"types": "./lib/types/index.d.ts",
"default": "./lib/index.cjs"
}
},
"files": [ "lib" ],
"scripts": {
"build": "rollup -c"
}
}
F. Smoke Test
Build everything and make sure it works.
npm run build
validate library files generated (both cjs and esm)
./lib/index.cjs./lib/index.cjs.map./lib/index.esm.js./lib/index.esm.js.map
validate types
./lib/types/index.d.ts./lib/types/utils/helloWorld.d.ts
4. CLI (Optional)
To add a CLI to a library, here are my steps
A. Install Version injector plugin
This synchronizes the CLI version with the package.json version.
rollup-plugin-version-injector- Rollup Plugin Injector for automatic package.json version injection.
npm install --save-dev rollup-plugin-version-injector
B. Update rollup.config.js
Here are the CLI changes to rollup. NOTE export default becomes an array as it has two outputs -- CLI and Library -- instead of one.
// ...
import versionInjector from 'rollup-plugin-version-injector';
// NOTE!!!! the array multiple outputs
export default [
// Library Configuration
{
//
},
// CLI Configuration
{
input: 'src/cli.ts',
output: {
file: 'lib/cli.js',
format: 'es',
sourcemap: true,
banner: '#!/usr/bin/env node',
inlineDynamicImports: true,
},
plugins: [
commonjs(),
json(),
nodeResolve({ browser: false, preferBuiltins: true }),
typescript({ useTsconfigDeclarationDir: true }),
versionInjector({
format: 'esm',
injectInComments: false,
}),
],
external: ['fs', 'path'], // Mark Node.js built-ins as external
},
];
C. CLI Arguments Commander
Install Commander, one of many but the most straightforward for me, for CLI command line argument and options processing
npm install commander
D. CLI Entry File
Create the entry file for the CLI ./src/cli.ts
In your ./src/cli.ts process input. Here is a skeleton file example.
import { helloWorld } from "./utils/helloWorld";
import { program } from "commander";
program
.name("my-cli")
.description("A skeleton CLI to say hello world")
.usage("<name> [options]")
.helpOption("-h, --help", "Display help for command")
.version("[VI]{version}[/VI]", "-v, --version", "Display version information");
program
.argument("<name>", "name to greet", "World")
.action((name) => {
console.log(helloWorld(name));
});
program.parse(process.argv);
D. Update packgae.json
Add the bin to name your CLI and connect it your built file. Your name can be anything, my-cli shown here, but in practice it should be the NPM and repo name.
{
"bin": {
"my-cli": "./lib/cli.js"
},
}
E. Quick Test
Build everything with:
npm run build
Smoke test using npx my-cli
> npx my-cli
Hello, World!
> npx my-cli john
Hello, john!
> npx my-cli john foo
error: too many arguments. Expected 1 argument but got 2.
> npx my-cli -h
Usage: my-cli <name> [options]
A skeleton CLI to say hello world
Arguments:
name name to greet (default: "World")
Options:
-v, --version Display version information
-h, --help Display help for command
> npx my-cli --version
0.6.0
5. Setup Unit Tests
Steps for using Vitest as the test framework:
A. Install Vitest
Run the following command to install Vitest and its peer dependencies:
npm install --save-dev vitest @vitest/coverage-v8
B. Update package.json
Add a script to run Vitest in your package.json:
{
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest --coverage",
}
}
C. Configure Vitest
Create a vitest.config.ts file in the root of your project:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true, // Enable global test functions like `describe`, `it`, etc.
environment: 'node', // Use Node.js environment for testing
coverage: {
include: ['src/**/*.{js,ts}'], // Include JS/TS files in the src directory
exclude: [
'src/**/*.d.ts', // Exclude TypeScript declaration files
'src/cli.ts', // Exclude CLI entry point
'src/index.ts', // Exclude main entry point if it doesn't contain testable code
'src/utils/*.test.ts', // Exclude test files from coverage
],
provider: 'v8', // Use v8 for coverage reporting
reporter: ['text', 'html', 'json-summary', 'json'],
reportOnFailure: true, // Optional: Report coverage even if tests fail
reportsDirectory: './tests/output/coverage', // Directory to output coverage reports
},
},
});
D. Create Test Folders
./tests./tests/output./tests/output/coverage./tests/input
E. Add Test Output to .gitignore
I like setting the ./tests/output outside of git so I can dump test results into it.
node_modules
lib
tests/output
F. Smoke the Unit Test
Create a test file in
./testsfolder./srcnext to the source file- name should be the same as source file except it ends with
test.js - JavaScript for the test
For example
./src/utils/hellowWorld.test.js
import { describe, it, expect } from 'vitest';
import { helloWorld } from './helloWorld';
describe('helloWorld function', () => {
it('should return "Hello, World!" when called with no arguments', () => {
const result = helloWorld();
expect(result).toBe('Hello, World!');
});
it('should retnurn "Hello, john!" when called with "john"', () => {
const result = helloWorld('john');
expect(result).toBe('Hello, john!');
});
it('should be a function', () => {
expect(typeof helloWorld).toBe('function');
});
});
G. Run Tests
Run the tests using the following commands:
- Run all tests once
npm run test - Run all tests with Watch:
npm run test:watch - Run tests with coverage:
npm run test:coverage
H. Verify Coverage (Optional)
After running npm run test:coverage, a coverage folder will be generated with detailed coverage reports.
Advantages of Using Vitest
- Native ESM Support: Works seamlessly with your ESM-based TypeScript project.
- Fast and Lightweight: Built on Vite, making it faster than traditional test frameworks.
- TypeScript-Friendly: No additional configuration is needed for TypeScript.
6. Publish Manual Initial
Using a scoped name, i.e. @pennockprojects/ in the package.json name file, by default will be private. In order to make it public but also scoped run the following
- Make sure you have run
npm run buildsuccessfully npm whoami- should show you logged into your npm account- If not, login in with
npm login
- If not, login in with
npm publish --dry-runfor testing- IMPORTANT
npm publish --access public- make sure to use the public flag - Check in code -
git status,git commit, andgit push
Package Changeset
1. Initialize Changesets
- Local: Open project in a side branch
git checkout -b <sidebranchname> - Local: Install package CLI
npm install --save-dev @changesets/cli
- Local: Initialize 'changeset' into project (creates
.changesetdirectory and config), using CLInpx changeset init
- Local: Update
.changeset/config.json- change
"access":"restrictred"to"access":"public"
- change
2. Setup GitHub Action
A. Local Setup
- Local: Create a directories
./.github/workflows - Local: Create a
release.ymlfile in.github/workflows
name: Release
on:
push:
branches:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: checkout repository code
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.REPO_NAME_CHANGESET_TOKEN }}
- name: setup node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Create release pull request
id: changeset_action
uses: changesets/action@v1
with:
publish: npm run release-package
env:
GITHUB_TOKEN: ${{ secrets.REPO_NAME_CHANGESET_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_CHANGESET_TOKEN }}
B. Add Release Script
Local: Add the release script to the package.json
{
"scripts": {
"release-package": "npm run build && npx changeset publish"
}
}
C. Create GitHub Token
- GitHub: Account and
Settings(upper right picture, not repo setting) - GitHub:
Developer Settings <>(left hand column down) - GitHub:
Personal Access TokensandTokens (classic) - GitHub: Choose
Generate new tokenandGenerate new token (classic)button and dropdown- Add a Note, i.e. "{repo name} changeset token"
- Choose Expiration
- In Scopes - pick
repoandworkflows
- GitHub: Choose
Generate Tokenbutton - GitHub: Copy key created
- Waring - will not see again
D. Add GitHub Token to Repo
- GitHub: In your repository
SettingschooseSecrets and Variables - GitHub: Choose
Actions(below) - GitHub: Choose
New Repository Secretbutton - GitHub: Choose a SNAKE_CASE all caps name
- GitHub: Paste your GitHub Account Secret (from previous step)
- GitHub: Choose
Create - Local: Authenticate local git with new token
git remote set-url origin https://<GIT_TOKEN>@github.com/<USERNAME>/<REPOSITORY>.git
- Local: Update
release.ymlREPO_NAME_CHANGESET_TOKENto the name your created (2 places)
E. Create NPM Token
- Npmjs.com: Choose Profile Pic dropdown (upper-right)
- Npmjs.com: Choose Access Tokens
- Npmjs.com: Choose
Generate New Tokenbutton and chooseClassic Token - Npmjs.com: Choose a name like
REPO_NAME_NPM_CS_TOKEN(this can be used for all packages or individual packages) - Npmjs.com: Choose
publishprivilege - Npmjs.com: Choose
Create - GitHub: In your repository
SettingschooseSecrets and Variables - GitHub: Choose
Actions(below) - GitHub: Choose
New Repository Secretbutton - GitHub: Choose a SNAKE_CASE all caps name - use the same from Npmjs.org, i.e.
NPM_REPONAME_CS_TOKEN - GitHub: Paste your secret
- GitHub: Choose
Save - Local: Update
release.ymlNPM_CHANGESET_TOKENto the name you created at GitHub, i.e.NPM_REPONAME_CS_TOKEN
F. Branch Protection Rules
- GitHub: Choose repo
Settingstab on the repo page - GitHub: Choose
Branches - GitHub: Choose
Add classic branch protection rule - GitHub: Type
mainintoBranch name pattern - GitHub: Check
Require a pull request before merging - GitHub: Uncheck:
Require approvals- if only one contributor - GitHub: Check
Do not allow bypassing the above settings - GitHub: Choose
Createbutton
3. Publish Changeset Action
You just need to push the changes and the automatic builds and actions will follow.
git statusgit commit -m "<comment>"- Push with
git push origin <sidebranchname>
- then follow the GitHub Changeset Pull Request
- Note: For the first time adding changeset and you did not create a new version it will not to the NPM publish action.
Package Workflows
Feature Workflow
Feature Local Work
- Local: Get latest 'main'
git pull origin mainorgit pullif you have it setup
- Local: Create working side branch to 'main'
git checkout -b <new_feature_branch>
- Local: Develop Patch, Feature, or Revision
- Local: Test
npm run test- find unit test breaks earlynpm run build- find build breaks early
- Local: Create Change Set
- run
npx changeset- note no 's', not 'changesets'
- Choose 'patch' or 'minor' (typically 'major' is for prerelease)
- Enter a description
- The result creates a randomly named Change Set file in the
/.changesetfolder, for examplebusy-monkey-keys. This file documents version bump and description for the Change Set GitHub action later - important don't update
package.json. Change Set is going to to all of this automatically.
- run
- Local: Git add, commit and push changes, includes the generated changeset file.
git add .git commit -m "commit message"git push origin <new_feature_branch>
This will generate a Changeset Branch PR.
Feature GitHub PR
See GitHub Changeset Pull Request
Changeset Pull Requests
Changeset Branch PR
- GitHub: In Repository, open the 'Compare & pull request` button on the repo.
- GitHub: important On the 'Open a pull request' page, make sure the merge target, drop-down, on upper left, is
base: mainfor feature or new releasebase: <prerelease branch>for prerelease work
- GitHub: Choose 'Create Pull Request' button
- GitHub: Review 'Files Changed' tab
Changesetfile, random name, i.e.busy-monkey-keys, should be included
- GitHub: Choose 'Conversation' tab
- GitHub: Choose 'Merge pull request' button, then 'Confirm merge'
- GitHub: Choose 'Delete branch' button in the 'Pull request successfully merged' section
- GitHub: Choose the 'Actions' tab and you should see the recent action log
- Open the 'release' yml job.
- Open 'Create release pull request' section
- Check at the bottom you should see a success message 'creating pull request'
This will automatically generate a Changeset NPM Publish PR
Changeset NPM Publish PR
Note you can wait and queue other Changeset Branch PRs before doing this.
Note2 it is usually named something like 'Version Packages #11'
- GitHub: Choose the 'Pull requests' tab and then open the
Version Packagesor similar. - GitHub: Review 'Files Changed' tab
package.jsonfile with the new versionCHANGE.mdfile updated with version and messages- Changeset random named file, i.e.
busy-monkey-keys, should be deleted
- GitHub: Choose 'Conversation' tab
- GitHub: Choose 'Merge pull request' button, then 'Confirm merge'
- GitHub: Choose 'Delete branch' button in the 'Pull request successfully merged' section
- GitHub: Choose the 'Actions' tab and you should see the recent action log
- Open the 'Release' build job.
- Check 'Create release pull request' section, at there should be a success message 'success package published successfully'
This should have published a new version on npmjs.com
Pre-release Workflow
Enter Pre-release mode
- Local: one-time Git checkout to a pre-release branch
git checkout -b prerelease
- Local: one-time Enter change set pre-release mode
npx changeset pre enter alpha- Creates a new file
pre.jsonin the./.changesetfolder wheremode: "pre"- change set modetag: "alpha"- name of pre-release 'alpha' (from the change set command.)"initialVersions": {}with the version inherited in the pre-release branch
- Creates a new file
- Local: Update GitHub action file
release.ymlto add pre-release branch, i.e.prelease
on:
push:
branches:
- main
- prerelease
- Local: Git add, commit, push
- i.e.
git add .,git commit -m "commit message"andgit push
- i.e.
Pre-release Local Work
- Local: from
prereleasebranch check-out new side branch to work on the next versiongit checkout -b <prerelease branch name>
- Local: Work on code in pre-release side branch
- Local: Add a change set
npx changeset- choose
major, description
- choose
- Local: Git add, commit, push to the pre-release side branch
Pre-release GitHub PR
- GitHub: Do GitHub Create Pull Request
- merge target should be
base: prerelease
- merge target should be
- GitHub: Do GitHub Finalize Publish
Pre-release Validate Publish
- Local: switch branch back to prerelease branch from side branch
git checkout <prereelease>
- Local: Git pull to get latest in the prerelease branch
git pull origin prelease
- Local: Validate files are correct
pre.jsonfile should change set name- The change set file itself is there.
package.jsonshould have a version that says something like "2.0.0-alpha.0"
- Local: delete local branch
git branch -D <sidebranch>
- NPM: Check the 'Versions' tab, refresh, and see that there is at least 2 current tags.
- current main
- alpha version
Test Package Usage
- Local: In your test consumer application, i.e. 'example node with package application', run your application and it should be working with current version (not alpha)
- Local: Install the pre-release version
npm install @<npmusername>/<packagename>@<prerelease version>- i.e.
npm install @pennockprojects/greeting-package@2.0.0.alpha-0
- Local: Test
- Make any changes needed for the breaking change to application (maybe make a new side branch for the test application)
- Restart your test consumer application,
- Test for changes
- Local: Revert back to mainline version
npm install @pennockprojects/<packagename>@latest- i.e.
npm install @pennockprojects/greeting-package@latest
Parallel Feature
- Local: Check out side branch from 'main' (not 'prerelease')
- Local: Get latest 'main'
git pull origin main
- Local: Make Changes
- Local: Run
Package Extras
Package Dependencies
- "dependencies" - included with our package
- "peerDependencies" - not included with our package in production, but assumed to be included elsewhere
- "devDependencies" - only included during development
Processing CLI
Creating and publishing a command-line interface (CLI) tool as an npm package allows you to share your useful scripts with other developers and make them easily installable and runnable from the terminal. Here's a step-by-step guide to get your CLI tool packaged up:
- Project Setup and Initialization.
- Create a directory: Start by creating a new folder for your CLI project and navigate into it using your terminal:
mkdir my-cli && cd my-cli - Initialize the Node.js project: This will generate a package.json file to manage your project's dependencies and configurations:
npm init -y.
- Create a directory: Start by creating a new folder for your CLI project and navigate into it using your terminal:
- Writing the CLI script.
- Create an entry point: Create a new JavaScript file (e.g., index.js or cli.js) that will contain the logic of your CLI tool.
- Add the shebang: Include the following line at the very top of your entry point file (index.js or cli.js) to tell the operating system to execute it using Node.js:
#!/usr/bin/env node. - Implement your CLI logic: This is where you'll write the code that performs the actions of your CLI tool. You can use libraries like
chalk,cli,meow,Commander.jsorYargsto handle command-line argument parsing and make your CLI more robust and user-friendly.
- Configuring package.json for CLI execution
- Define the "bin" field: Add a "bin" field to your package.json file. This tells npm to create an executable symbolic link (
symlink) to your CLI script when the package is installed globally or locally with npm link.
- Define the "bin" field: Add a "bin" field to your package.json file. This tells npm to create an executable symbolic link (
"bin": {
"my-cli-command": "./index.js"
}
- Replace "my-cli-command" with the desired name users will type to run your CLI in the terminal.
- Making the script executable.
- Set executable permissions: Grant executable permissions to your entry point file using the following command:
chmod +x index.js.
- Set executable permissions: Grant executable permissions to your entry point file using the following command:
- Testing the CLI locally
- Link the package: Run
npm linkin your project directory. This creates a globalsymlinkthat allows you to test your CLI tool as if it were installed globally. - Run your CLI: Now you can test your CLI tool by typing the command name defined in your package.json's "bin" field (e.g., my-cli-command) in your terminal.
- Link the package: Run
- Publishing your package to npm
- Create an npm account (if you don't have one): You'll need an npm account to publish packages.
- Login to npm: In your project directory, run npm login and follow the prompts to authenticate with your npm account.
- Publish the package: Once logged in, use the npm publish command to publish your CLI tool to the npm registry.
- Now your CLI tool is successfully packaged as an npm package and ready to be used by others! They can install it globally with
npm install -g my-cli-commandor use npx to run it without a global installation.
Package Testing
Create a test app to host the package as a consumer.
Testing Locally
NPM Link for testing package with a test app
- In the package project run
npm link - In the test app project run
npm link <@npmusername>/<packaagename>
NPM Un-linking testing package
- In the package project run
npm unlink -g - In the test app project run:
npm unlink <@npmusername>/<packaagename>- unlinks the use of the local linknpm install <@npmusername>/<packaagename>- this uses publishednpmjs.comregistry version
Front-end Testing App
Vite as Runner
To quickly create a Vite app with favorite framework:
- with prompts:
npm create vite@latest - React.ts:
npm create vite@latest example-react-app -- -- template react.ts - Vue.ts:
npm init vite@latest my-vue-app --template vue.ts
Vite Force Flag
Add the --force flag to avoid cache issues with the package to the run script in package.json
{
"scripts": {
"dev": "vite --force",
}
}
Server Testing App
Express Node.js as Runner
- Create three files to start
- File #1:
./package.json
{
"name": "express-app",
"version": "1.0.0",
"description": "",
"main": "app.ts",
"scripts": {
"dev": "node dist/app.js",
"build": "npx tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@types/express": "^4.17.21",
"typescript": "^5.4.5"
},
"dependencies": {
"express": "^4.19.2"
}
}
- File #2:
./tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist"
},
"lib": ["es2015"]
}
- File #3:
./src/app.ts
import express from "express";
const app = express();
const port = 3000;
app.get("/", (req, res) => {
res.send("Hello World!");
});
app.listen(port, () => {
return console.log(`Express is listening at http://localhost:${port}`);
});
- Build App
npm run build - Preview App
npm run dev - Add package
npm install @npmusername/packagename
Cheats
Clean Install
npm ci- for "clean install", similar tonpm installbut used during CICD for a fresh install and uses exact versions from thepackage-lock.jsonfile.package-lock.jsonandpackage.jsonmust be identical, or it falls- does not change
package*.*files - does not install individual modules
Running Many Scripts
You can define multiple scripts in your package.json file and run them in sequence or in parallel.
- Use && (double ampersand) for sequential execution.
- Some early versions of Windows Powershell did not support this syntax, but recent versions should.
- Use & (single ampersand) for parallel execution.
- Test carefully as commands earlier in the list may be run in background and you may potentially lose the output including any error messages (depending on your platform/shell).
Invoke chained scripts via npm run.
For example, to run pre-build, build_logic, post_build, and exit scripts in sequence, you can do:
npm run pre-build && npm run build_logic && npm run post_build && npm run exit
To run them in parallel, you can do:
npm run pre-build & npm run build_logic & npm run post_build & npm run exit
Run chained scripts via a script in package.json.
For example, to run pre-build, build_logic, post_build, and exit scripts in sequence, you can add a build script in your package.json like this:
"scripts": {
...
"build": "npm run pre-build && npm run build_logic && npm run post_build && npm run exit",
"pre-build": "echo Pre-build step",
"build_logic": "echo Building...",
"post_build": "echo Post-build step",
"exit": "echo Exiting..."
}
To execute the build script, you would run:
npm run build
You can change the && to & in the build script to run the commands in parallel.