Here is my repo for this article.
npm-package-template
This is a template for a npm package.
Current src
has trim and isOdd/isEven functionality.
How to run locally
$ yarn
# lint
$ yarn lint
# test
$ yarn test
Circle CI
image: cimg/node:15.1
Circle CI image is using npm
so need package-lock.json
.
What is npm?
npm is a package manager for the JavaScript programming language. npm, Inc. is a subsidiary of GitHub, that provides hosting for software development and version control with the usage of Git. npm is the default package manager for the JavaScript runtime environment Node.js. Wikipedia
For people who prefer to use js
instead of ts
.
In this article, I use typescript, but if you don't want to use it, you can skip things that are related to typescript such as installing typescript, generating tsconfig.json, and using ts extension and types in codes.
Set up a template project
First, we need to create a folder for the package template and run yarn init
or npm init
. I think package.json that is generated by npm init
can be better than yarn's one since it covers the most basic items.
$ mypackagetemplate
$ cd mypackagetemplate
$ yarn init or npm init
Install packages for the template
In this step, we install some packages for the template.
$ yarn add typescript --dev
# generate tsconfig.json
$ yarn tsc --init or node_modules/.bin/tsc --init
Update generated tsconfig.json like below.
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
Write code
$ mkdir src
$ cd src
$ touch index.ts
$ touch odd_even.ts
odd_even.ts
The code is super simple. Just pass a number and if the number is even, it will return true
.
export default (value: number): boolean => {
return value %2 ==0 ? true : false;
}
index.ts
The following code allows us to import the code like below.
import { odd_even } from 'package-name'
import odd_even from './odd_even';
export default {
odd_even: odd_even,
}
Add ESLint Jest
In this step, we will set up eslint and Jest.
We will install eslint and jest.
yarn run eslint --init
command allows us to create a config file intractively.
$ yarn add eslint jest ts-jest -D
$ yarn run eslint --init
# settings for this
# ❯ To check syntax and find problems
# ❯ JavaScript modules (import/export)
# ❯ None of these
# ? Does your project use TypeScript? › No / ❯ Yes
# ✔ Browser
# ✔ Node
# ❯ JavaScript
# ? Would you like to install them now with npm? › No / ❯ Yes
You will see .eslintrc.js
in your project folder
module.exports = {
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
}
};
We need to modify package.json
to run eslint
.
"scripts": {
"build": "rollup -c",
"lint": "eslint --fix 'src/**/*.ts'",
"test": "jest"
},
Now we can do lint for codes under src
.
$ yarn lint
Then, add configs for jest to package.json
"jest": {
"moduleFileExtensions": [
"ts",
"js"
],
"transform": {
"^.+\\.ts$": "ts-jest"
},
"globals": {
"ts-jest": {
"tsconfig": "tsconfig.json"
}
},
"testMatch": [
"**/test/**/*.test.ts"
]
}
Write test
First, creatae a test folder
$ mkdir test
test/odd_even.test.ts
The test code is also simple as well as odd_even.ts
. The code tests 2 cases, odd number(1) & even number(2).
import odd_even from '../src/odd_even';
describe('test odd_even', (): void => {
test('odd', (): void => {
const resp: boolean = odd_even(1);
expect(resp).toBe(false);
});
test('even', (): void => {
const resp: boolean = odd_even(2);
expect(resp).toBe(true);
});
});
Now we can run a test with the following command
$ yarn test
Set up rollup.js
The final step is setting up rollup.js(including Babel).
rollup.js
Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD. ES modules let you freely and seamlessly combine the most useful individual functions from your favorite libraries. This will eventually be possible natively everywhere, but Rollup lets you do it today.
https://rollupjs.org/guide/en/
If you don't like to use rollup.js, you can use others such as webpack.
$ yarn add rollup rollup-plugin-terser @rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-typescript tslib @babel/core @babel/preset-env -D
Add .babelrc.js
module.exports = {
presets: [
[
"@babel/preset-env",
],
],
};
rollup.config.js
import { terser } from "rollup-plugin-terser";
import pluginTypescript from "@rollup/plugin-typescript";
import pluginCommonjs from "@rollup/plugin-commonjs";
import pluginNodeResolve from "@rollup/plugin-node-resolve";
import { babel } from "@rollup/plugin-babel";
import * as path from "path";
import pkg from "./package.json";
const moduleName = pkg.name.replace(/^@.*\//, "");
const inputFileName = "src/index.ts";
const author = pkg.author;
const banner = `
/**
* @license
* author: ${author}
* ${moduleName}.js v${pkg.version}
* Released under the ${pkg.license} license.
*/
`;
export default [
{
input: inputFileName,
output: [
{
name: moduleName,
file: pkg.browser,
format: "iife",
sourcemap: "inline",
banner,
},
{
name: moduleName,
file: pkg.browser.replace(".js", ".min.js"),
format: "iife",
sourcemap: "inline",
banner,
plugins: [terser()],
},
],
plugins: [
pluginTypescript(),
pluginCommonjs({
extensions: [".js", ".ts"],
}),
babel({
babelHelpers: "bundled",
configFile: path.resolve(__dirname, ".babelrc.js"),
}),
pluginNodeResolve({
browser: true,
}),
],
},
// ES
{
input: inputFileName,
output: [
{
file: pkg.module,
format: "es",
sourcemap: "inline",
banner,
exports: "named",
},
],
external: [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.devDependencies || {}),
],
plugins: [
pluginTypescript(),
pluginCommonjs({
extensions: [".js", ".ts"],
}),
babel({
babelHelpers: "bundled",
configFile: path.resolve(__dirname, ".babelrc.js"),
}),
pluginNodeResolve({
browser: false,
}),
],
},
// CommonJS
{
input: inputFileName,
output: [
{
file: pkg.main,
format: "cjs",
sourcemap: "inline",
banner,
exports: "default",
},
],
external: [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.devDependencies || {}),
],
plugins: [
pluginTypescript(),
pluginCommonjs({
extensions: [".js", ".ts"],
}),
babel({
babelHelpers: "bundled",
configFile: path.resolve(__dirname, ".babelrc.js"),
}),
pluginNodeResolve({
browser: false,
}),
],
},
];
Finally, we can build. If everything goes well, you will see dist
folder and 4 js files(hellotslib.cjs.js, hellotslib.es.js, hellotslib.js, and hellotslib.min.js)
$ yarn build
Now you can add any functionalities that you want to bring to npm world via your npm package 😎
Top comments (0)