μμ£Ό μ¬μ©λλ κΈ°λ₯μ Typescript λ‘ μμ±ν΄μ NPM μ κ²μν ν λ€λ₯Έ νλ‘μ νΈμμ μ¬μ©νκ³ μΆμ΄ NPM μ ν¨ν€μ§λ₯Ό μ΄λ»κ² 곡κ°νλμ§λ₯Ό νμΈνμ΅λλ€.
μ λ @bbon
μ€μ½νλ₯Ό μ¬μ©ν΄μ @bbon/formatter
ν¨ν€μ§λ₯Ό κ²μν κ²μ
λλ€.
μ€μ½ν npm-scope νμ΄μ§μμ μ 보λ₯Ό νμΈν μ μμ΅λλ€.
npm ν¨ν€μ§λ μ΄λ¦μ΄ κ³ μ ν΄μΌ νλλ°, μ½ 1,268,126 κ°μ 곡κ°λ ν¨ν€μ§ (2020-04-25 νμ¬) κ° μ‘΄μ¬νλ μνμμ ν¨ν€μ§ μ΄λ¦μ κ²°μ νλ κ²μ λ§€μ° μ΄λ ΅μ΅λλ€λ§, μ€μ½νλ₯Ό μ¬μ©νλ©΄ μνλ ν¨ν€μ§ μ΄λ¦μ μ¬μ©ν μ μλ€κ³ μκ°λμμ΅λλ€.
λ°λΌνλ©΄μ ν¨ν€μ§λ₯Ό κ²μνμλ €λ©΄ μλ λ΄μ©μ νμΈνκΈ° μ μ npm κ³μ μ λ§λ€κ³ μμνλ κ²μ μ μν©λλ€.
νλ‘μ νΈ κ΅¬μ±
GitHub μ μ μ₯μλ₯Ό λ§λ€κ³ , λ‘컬 μ μ₯μλ‘ λ³΅μ ν ν μμν©λλ€.
νλ‘μ νΈ μ΄κΈ°ν
νλ‘μ νΈλ₯Ό μ΄κΈ°νν©λλ€.
$ npm init
package.json
νμΌμ νΈμ§κΈ°λ‘ μ΄κ³ νμν μ 보λ₯Ό νΈμ§ν©λλ€.
package.json νμΌμ νμΈνμμμ€.
{
"name": "@bbon/formatter",
"version": "1.0.0",
"description": "Format the entered values.",
"repository": {
"type": "git",
"url": "git+https://github.com/bbonkr/bbon-formatter.git"
},
"homepage": "https://github.com/bbonkr/bbon-formatter",
"bugs": {
"url": "https://github.com/bbonkr/bbon-formatter/issues"
},
"keywords": ["formatting", "string", "utility"],
"author": "Pon Cheol Ku <dev@bbon.kr> (http://bbon.kr)",
"license": "MIT"
}
package.json νμΌμ λͺ μΈλ npm-package.json νμ΄μ§μμ νμΈν μ μμ΅λλ€.
νλ‘μ νΈ μ€μ
κΈ°λ₯μ ꡬννκΈ° μν΄μ νμ μ€ν¬λ¦½νΈλ₯Ό μ¬μ©ν©λλ€.
μ½λ μμ± κ·μΉ μ§μ μ μν΄ eslint, prettier λ₯Ό μ¬μ©ν©λλ€.
λ¨μν μ€νΈλ jestλ₯Ό μ¬μ©ν©λλ€.
μμ‘΄ ν¨ν€μ§λ₯Ό μ€μΉν©λλ€.
$ npm install --save-dev typescript eslint prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-plugin-import eslint-plugin-prettier jest @types/jest @types/node ts-jest
.prettierrc
νμΌμ λ§λ€κ³ , κ΅¬μ± λ΄μ©μ μ
λ ₯ν©λλ€.
{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 4
}
.eslintrc
νμΌμ λ§λ€κ³ , κ΅¬μ± λ΄μ©μ μ
λ ₯ν©λλ€.
{
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": [
"plugin:@typescript-eslint/recommended",
"prettier",
"prettier/@typescript-eslint",
"plugin:prettier/recommended"
],
"parserOptions": {
"ecmaVersion": 2018, // Allows for the parsing of modern ECMAScript features
"sourceType": "module" // Allows for the use of imports
},
"rules": {
"no-console": "warn"
}
}
.eslintignore
νμΌμ λ§λ€κ³ λ΄μ©μ νΈμ§ν©λλ€.
dist/
.gitignore νμΌμ λ§λ€κ³ λ΄μ©μ νΈμ§ν©λλ€.
node_modules/
dist/
.jest/
νμ μ€ν¬λ¦½νΈ νλ‘μ νΈ μΆκ°
tsc --init
λͺ
λ ΉμΌλ‘ νμ
μ€ν¬λ¦½νΈ νλ‘μ νΈ νμΌ tsconfig.json
μ μΆκ°ν©λλ€.
$ npx tsc --init
tsconfig.json νμΌμ λͺ μΈλ tsconfig.json - typescript νμ΄μ§μμ νμΈν μ μμ΅λλ€.
λ§λ€μ΄μ§ tsocnfig.json
νμΌμ λ΄μ©μ νΈμ§ν©λλ€.
{
"compilerOptions": {
/* Basic Options */
"target": "es5",
"module": "commonjs",
"declaration": true,
"outDir": "./dist",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
},
"exclude": ["__test__", "./**/*.spec.ts", "dist"]
}
μ½λ μμ±
src λλ ν°λ¦¬λ₯Ό λ§λ€κ³ μ½λλ₯Ό μμ±ν©λλ€.
src/StringFormatter.ts
νμΌμ λ΄μ©μ
λλ€.
/**
* ν¬λ§·ν
κΈ°λ₯μ μ 곡ν©λλ€.
*
* @export
* @class StringFormatter
*/
export class StringFormatter {
/**
* μ«μμ 1000 λ¨μ ꡬλΆμλ₯Ό μΆκ°ν΄μ λ¬Έμμ΄λ‘ μΆλ ₯ν©λλ€.
*
* @param {(number | string)} value
* @param {string} delimiter ꡬλΆμ; κΈ°λ³Έκ°: **,** μ½€λ§ λ¬Έμ
* @returns {string}
* @memberof StringFormatter
*/
public NumberWithDelimiter(value: number | string, delimiter = ","): string {
let stringValue = "";
let fraction = "";
if (typeof value === "number") {
stringValue = value.toString();
}
if (typeof value === "string") {
stringValue = value;
}
if (stringValue.indexOf(".") >= 0) {
const splittedValue = stringValue.split(".");
if (splittedValue.length > 1) {
stringValue = splittedValue[0];
fraction = splittedValue[1];
}
}
stringValue = stringValue.replace(/\B(?=(\d{3})+(?!\d))/g, delimiter);
return `${stringValue}${fraction ? `.${fraction}` : ""}`;
}
}
src/index.ts
νμΌμ λ΄μ©μ
λλ€.
export { StringFormatter } from "./StringFormatter";
λ¨μν μ€νΈ μΆκ°
src/StringFormatter.spec.ts
νμΌμ λ΄μ©μ
λλ€.
import { StringFormatter } from "./StringFormatter";
describe("StringFormatter", () => {
const formatter = new StringFormatter();
it("μΈμ리λ§λ€ ꡬλΆμκ° μΆκ°λ μ«μ νμμ λ¬Έμμ΄", () => {
expect(formatter.NumberWithDelimiter(1000)).toBe("1,000");
});
it("ν° μ«μλ μΈμ리λ§λ€ ꡬλΆμκ° μΆκ°λ μ«μ νμμ λ¬Έμμ΄", () => {
expect(formatter.NumberWithDelimiter(12345678901234)).toBe(
"12,345,678,901,234"
);
});
it("μμμ μλ κ°μ ꡬλΆμκ° μΆκ°λμ§ μμ΅λλ€.", () => {
expect(formatter.NumberWithDelimiter(1000.1234)).toBe("1,000.1234");
});
it("μ«μνμμ λ¬Έμμ΄μ μ
λ ₯νλ©΄ μΈμ리λ§λ€ ꡬλΆμκ° μΆκ°λ μ«μ νμμ λ¬Έμμ΄", () => {
expect(formatter.NumberWithDelimiter("1000")).toBe("1,000");
});
it("μ«μνμμ λ¬Έμμ΄μ μ
λ ₯νλ©΄ μμμ μλ κ°μ ꡬλΆμκ° μΆκ°λμ§ μμ΅λλ€.", () => {
expect(formatter.NumberWithDelimiter("1000.1234")).toBe("1,000.1234");
});
it("λΉ λΆμμ΄μ λΉ λ¬Έμμ΄μ λ°νν©λλ€.", () => {
expect(formatter.NumberWithDelimiter("")).toBe("");
});
});
jest ꡬμ±λ΄μ©μ package.json νμΌμ μΆκ°ν©λλ€.
{
// ... μ΄μ λ΄μ©
"jest": {
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
},
"globals": {
"ts-jest": {
"tsConfig": "tsconfig.json"
}
},
"testRegex": "\\.(test|spec)\\.((js|ts))$",
"setupFilesAfterEnv": ["./__test__/setup.ts"],
"cacheDirectory": "./.jest/cache"
}
}
NPM μ€ν¬λ¦½νΈ
λΉλ, λ¦°νΈ, ν μ€νΈ μ€ν¬λ¦½νΈλ₯Ό μΆκ°ν©λλ€.
{
// ... μ΄μ λ΄μ©
"scripts": {
"test": "jest",
"build": "tsc",
"lint": "eslint ./src/**/*.ts",
"lint:fix": "eslint ./src/**/*.ts --fix"
}
}
λΉλ μ€ν¬λ¦½νΈ μ€ν λͺ λ Ήμ μλμ κ°μ΅λλ€.
$ npm run build
λΉλ μ€ν¬λ¦½νΈλ₯Ό μ€ννλ©΄ dist λλ ν°λ¦¬κ° λ§λ€μ΄μ§κ³ , dist λλ ν°λ¦¬μ νμ
μ€ν¬λ¦½νΈλ‘ μμ±ν μ½λμμ νΈλμ€νμΌλ StringFormatter.js
, index.js
, StringFormatter.d.ts
, index.d.ts
νμΌμ΄ λ§λ€μ΄ μ§λλ€.
ν μ€νΈ μ€ν¬λ¦½νΈ μ€ν λͺ λ Ήμ μλμ κ°μ΅λλ€.
$ npm run test
> @bbon/formatter@1.0.1 test D:\repos\formatter
> jest
PASS src/StringFormatter.spec.ts
StringFormatter
β μΈμ리λ§λ€ ꡬλΆμκ° μΆκ°λ μ«μ νμμ λ¬Έμμ΄ (1ms)
β ν° μ«μλ μΈμ리λ§λ€ ꡬλΆμκ° μΆκ°λ μ«μ νμμ λ¬Έμμ΄
β μμμ μλ κ°μ ꡬλΆμκ° μΆκ°λμ§ μμ΅λλ€. (1ms)
β μ«μνμμ λ¬Έμμ΄μ μ
λ ₯νλ©΄ μΈμ리λ§λ€ ꡬλΆμκ° μΆκ°λ μ«μ νμμ λ¬Έμμ΄
β μ«μνμμ λ¬Έμμ΄μ μ
λ ₯νλ©΄ μμμ μλ κ°μ ꡬλΆμκ° μΆκ°λμ§ μμ΅λλ€.
β λΉ λΆμμ΄μ λΉ λ¬Έμμ΄μ λ°νν©λλ€.
Test Suites: 1 passed, 1 total
Tests: 6 passed, 6 total
Snapshots: 0 total
Time: 1.646s, estimated 3s
Ran all test suites.
NPM ν¨ν€μ§ κ²μ μ€λΉ
NPM ν¨ν€μ§λ₯Ό κ²μνκΈ° μ μ ν¨ν€μ§μ ν¬ν¨λ νμΌμ μ§μ ν©λλ€.
ν¨ν€μ§λ₯Ό μ¬μ©νλ λΆμ μ μ₯μμ νμμλ νμΌμ μ μΈνκ³ , κΌ νμν νμΌλ§ μ λ¬νλ κ²μ΄ μ’κ² μ΅λλ€.
νμ¬ κ΅¬μ±λ νλ‘μ νΈλ₯Ό λΉλνλ©΄ dist λλ ν°λ¦¬κ° λ§λ€μ΄μ§κ³ , νμ μ€ν¬λ¦½νΈλ‘ μμ±λ μ½λμ νΈλμ€νμΌ κ²°κ³Όκ° μ μ₯λ©λλ€.
λ°λΌμ, dist λλ ν°λ¦¬μ λ΄μ©μ NPM ν¨ν€μ§μ κΌ ν¬ν¨λμ΄μΌ ν©λλ€.
λ€λ₯Έ μ λͺ ν ν¨ν€μ§μ λ΄μ©μ νμΈν΄λ³΄λ, ν¨ν€μ§ μ 보μ λΌμ΄μ μ€ μ 보λ ν¬ν¨νκ³ μμ΅λλ€.
νμν νμΌλ§ μ λ¬λλλ‘ κ΅¬μ±νκΈ° μν΄ .npmignore
νμΌμ λ§λ€κ³ λ΄μ©μ νΈμ§ν©λλ€.
.npmignore
νμΌμ λ΄μ©μ
λλ€.
__test__/
src/
.jest/
.eslintignore
.eslintrc
.prettierrc
tsconfig.json
npm ν¨ν€μ§μμ μ μΈνλ μ΄μ λ μλμ κ°μ΅λλ€.
__test__ λλ ν°λ¦¬λ jest μ μ ꡬμ±μ μν μ½λκ° μμ΅λλ€.
src λλ ν°λ¦¬λ νμ μ€ν¬λ¦½νΈλ‘ μμ±λ μμ€μ½λκ° μμ΅λλ€.
.jest λλ ν°λ¦¬λ jest ν μ€νΈμ μΊμ νμΌμ΄ μμ΅λλ€.
npm ν¨ν€μ§ μ 보μ λ©μΈ νμΌμ΄λ¦κ³Ό νμ νμΌμ΄λ¦μ μΆκ°ν©λλ€.
package.json νμΌμ λ΄μ©μ λλ€.
{
// ...μ΄μ λ΄μ©
"main": "dist/index.js",
"types": "dist/index.d.ts"
}
NPM ν¨ν€μ§ κ²μ
npm ν¨ν€μ§λ₯Ό κ²μνκΈ° μν΄ μΈμ¦ μ 보λ₯Ό μ μ₯ν©λλ€.
npm login
λͺ
λ ΉμΌλ‘ μΈμ¦μ 보λ₯Ό μ μ₯ν μ μμ΅λλ€.
$ npm login
κ³μ μ΄λ¦, λΉλ°λ²νΈ, μ μμ°νΈμ£Όμ, λ€μ€μΈμ¦μ μ¬μ©μ€μ΄λ©΄ λ€μ€μΈμ¦μ 보λ₯Ό μ λ ₯νλ©΄ μΈμ¦μ λ³΄κ° μ μ₯λ©λλ€.
npm config ls
λͺ
λ ΉμΌλ‘ μ 보λ₯Ό νμΈν μ μμ΅λλ€.
$ npm config ls
λ‘κ·ΈμΈμ΄ λμμΌλ©΄, μ€λΉν΄λ npm μ€ν¬λ¦½νΈλ‘ λΉλν©λλ€.
$ npm run build
dist λλ ν°λ¦¬μ νμΌ μμ±λ κ²μ νμΈν©λλ€.
NPM ν¨ν€μ§ μ΅μ΄ κ²μ
λ¬Έμ κ° μμΌλ©΄ npm publish λͺ λ ΉμΌλ‘ κ²μν©λλ€.
μ΄ λ, μ€μ½ν ν¨ν€μ§λ κΈ°λ³Έμ μΌλ‘ λΉκ³΅κ° ν¨ν€μ§λ‘ κ²μλ©λλ€. μ λ κ³΅κ° ν¨ν€μ§λ‘ κ²μν κ²μ΄λ―λ‘ --access public
μ΅μ
μ μ¬μ©ν©λλ€.
$ npm publish --access public
μ μμ μΌλ‘ κ²μλλ©΄ npm μ¬μ΄νΈμμ κ²μλ ν¨ν€μ§λ₯Ό νμΈν μ μμ΅λλ€.
@bbon/formatter νμ΄μ§μ κ°μ΄ μ λ³΄κ° μ 곡λ©λλ€.
NPM ν¨ν€μ§ νμ¬λ¦Ό
μ΄ν λ³κ²½λ λ΄μ©μΌλ‘ NPM ν¨ν€μ§λ₯Ό μ λ°μ΄νΈνλ €λ©΄ package.json νμΌμ λ²μ μ λ³κ²½ν΄μ κ²μν΄μΌ ν©λλ€.
{
// ... μ΄μ λ΄μ©
"version": "1.0.1"
}
λΉλ μ€ν¬λ¦½νΈλ₯Ό μ€νν΄μ λ³κ²½λ λ΄μ©μ dist λλ ν°λ¦¬ νμΌμ λ°μν©λλ€.
λ¬Έμ κ° μμΌλ©΄ npm publish λͺ λ ΉμΌλ‘ κ²μν©λλ€.
μ΄ λ, μ€μ½ν ν¨ν€μ§λ κΈ°λ³Έμ μΌλ‘ λΉκ³΅κ° ν¨ν€μ§λ‘ κ²μλ©λλ€. μ λ κ³΅κ° ν¨ν€μ§λ‘ κ²μν κ²μ΄λ―λ‘ --access public
μ΅μ
μ μ¬μ©ν©λλ€.
$ npm publish --access public
Creating and publishing scoped public packages νμ΄μ§μμ κ΄λ ¨ μ 보λ₯Ό νμΈν μ μμ΅λλ€.
μ μμ μΌλ‘ κ²μλλ©΄ npm μ¬μ΄νΈμμ κ²μλ ν¨ν€μ§λ₯Ό νμΈν μ μμ΅λλ€.
@bbon/formatter νμ΄μ§μ κ°μ΄ μ λ³΄κ° μ 곡λ©λλ€.
NPM ν¨ν€μ§ μ¬μ©
κ²μν NPM ν¨ν€μ§λ λ€λ₯Έ ν¨ν€μ§ μ¬μ©κ³Ό λμΌνκ² μ¬μ©ν μ μμ΅λλ€.
μ νλ‘μ νΈλ₯Ό μ€λΉνκ³ , μλ λͺ λ ΉμΌλ‘ ν¨ν€μ§λ₯Ό μ€μΉν©λλ€.
$ npm install --save @bbon/formatter
μ€μΉλ ν¨ν€μ§μ λ΄μ©μ νμΈν©λλ€.
node_modules/@bbon/formatter λλ ν°λ¦¬μμ νμΈν μ μμ΅λλ€.
dist λλ ν°λ¦¬μ λΌμ΄μ μ€ νμΌ, ν¨ν€μ§ μ 보, README.md νμΌλ§ ν¬ν¨λμ΄ μμμ νμΈν μ μμ΅λλ€.
νλ‘μ νΈ λλ ν°λ¦¬
β index.js
β package-lock.json
β package.json
β
ββnode_modules
ββ@bbon
ββformatter
β LICENSE
β package.json
β README.md
β
ββdist
index.d.ts
index.js
StringFormatter.d.ts
StringFormatter.js
λ§μΉ¨
μ 체 μ½λλ GitHub: bbon-formatter μμ νμΈν μ μμ΅λλ€.