2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【TypeScript】はじめてのnpm package公開

Last updated at Posted at 2021-01-29

パッケージを自作したら、思いのほか簡単だったので共有。typeScriptでurlを生成する便利関数をつくります。

typeScriptでつくらないよ〜って方も特に手順は変わらないのでみていただけると幸いです

最終的なディレクトリはこんな感じ


📦url-generator
 ┣ 📂__tests__
 ┣ 📂lib
 ┃ ┣ 📜index.d.ts
 ┃ ┗ 📜index.js
 ┣ 📂node_modules
 ┣ 📜.gitignore
 ┣ 📜.npmignore
 ┣ 📜LICENSE
 ┣ 📜README.md
 ┣ 📜index.ts
 ┣ 📜package-lock.json
 ┣ 📜package.json
 ┗ 📜tsconfig.json

フォルダを作成

$ mkdir url-generator

TypeScriptをインストール

devDependenciesに追加

$ npm install -D typescript

tsconfig.jsonを生成、編集

$ tsc --init

中身はこんな感じ。

tsconfig.json
{
  "compilerOptions": {
    "target": "es2015",
    "module": "commonJS",
    "outDir": "./lib",
    "declaration": true,
    "strict": true,
  },
  "include": ["index.ts"]
}

"target"

どのバージョンでjsを出力するか。

"module"

出力するjsのモジュールの仕組みとして何を使用するか。

"outDir"

出力するディレクトリーを指定

何も指定しない場合、roodディレクトリーに出力される

"declaration"

タイプ定義ファイルを生成するか。

こんな感じで、1ファイルにつき定義ファイルが生成される


📦lib
┣ 📂utils
┃ ┣ 📜foo.d.ts
┃ ┗ 📜foo.js
┣ 📜hoo.d.ts
┣ 📜hoo.js
┣ 📜index.d.ts
┗ 📜index.js

"strict"


--noImplicitAny
--noImplicitThis
--alwaysStrict
--strictBindCallApply
--strictNullChecks
--strictFunctionTypes
--strictPropertyInitialization

が全てtrueになる。

"include"

コンパイルする対象のファイルを指定。

他にオプションを詳しく知りたい方は、こちらを参照

package.jsonを生成、編集

$ npm init

中身がこんな感じ

package.json
{
  "name": "パッケージの名前",
  "version": "1.0.0",
  "description": "パッケージの説明",
  "main": "lib/index.js",
  "types": "lib/index.d.ts",
  "keywords": [
    "typescipt",
    "url",
    "url-generator",
    "params"
  ],
  "files": [
    "lib"
  ],
  "repository": {
    "type": "git",
    "url": "githubレポjと"
  },
  "dependencies": {},
  "devDependencies": {
    "typescript": "^4.1.3"
  },
  "scripts": {
    "build": "tsc",
    "prepublishOnly": "npm run build"
  },
  "author": "taichi-t",
  "license": "MIT",
}

"name"

モジュールの名前

他のモジュールと名前が被ってはいけないから、npmのウェブサイトで検索してから決めるとよい
npmの検索バー
@taichi-t/moduleNameのようにスコープをつけることもできる。

ただしスコープをつけた場合、自動でprivateパッケージになってしまい公開する際に金を払えとエラーが出る。その対処法は後述。

"version"

モジュールのバージョン

パッケージを変更する際は、バージョンを書き換えないと公開する時にエラーを吐く。

"description"

npm searchした際や検索エンジンの説明欄に表示される。
descriptionの表示場所1

descriptionの表示場所2

"main"

モジュールをimportした際、一番初めに呼ばれるファイルを指定。

"types"

型定義ファイルを指定。

"keywords"

npmのpackageページのkeyword欄に表示される
keywordsの表示場所

"repository"

ソースコードが管理されているURLを指定。

"author"

複数の場合配列で指定。

"license"

よく使われる寛容なライセンスはMIT、Apache2.0、ISC、BSD。
MITをよくみる気がする。

オープンソースライセンスについて詳しく知りたい方は、こちらを参考

"files"

公開する際に、ここで指定したファイルは.npmignore、.gitignoreに記載されていても除外されることはない。
詳しくはこちらを参照

ほかにもプロパティを知りたい方はこちらにまとめられています。

index.tsに関数を定義

index.ts
const isNumber = (value: number | string): value is number =>
  typeof value === 'number';

const generateUrl = (
  baseUrl: string,
  params: { [key: string]: string | number }
): string => {
  const url = new URL(baseUrl);
  Object.keys(params).forEach((key) => {
    const value = params[key];
    if (isNumber(value)) {
      return url.searchParams.set(key, String(value));
    } else {
      url.searchParams.set(key, value);
    }
  });
  return url.toString();
};

export default generateUrl;

コンパイルしてみる

$ tsc

tscofigで指定したディレクトリーにファイルが生成されてる。
libファイルの生成の確認

.npmignore生成、編集

パッケージを公開する際に除外するファイルを指定

$ touch .npmignore

中身はこんな感じ

.npmignore
.gitignore
package-lock.json
node_modules
index.ts
tsconfig.json
__tests__

パッケージを公開する際、.gitignoreと.npmignoreがある場合
.npmignoreが適用される。つまりfiles>.npmignore>.gitignoreの順で優先される。

README.mdの追加

少なくともタイトル、インストール方法、使い方、ライセンスを記述するとよい

こんな感じ。

README.md
# <img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/typescript/typescript-original.svg" alt="typescript" width="35" height="35"/> @taichi-t/url-generator
Generate urls with params.
## Installaion
`$ npm i @taichi-t/url-generator`
## Usage
```javascript
import urlGenerator from '@taichi-t/url-generator';
urlGenerator('http://www.example.com', { foo: 1, hoo: '2' });
// http://www.example.com/?foo=1&hoo=2

LICENCEをGitリポジトリのメインページから作成

ここからコピペできるが、Gitリポジトリのメインページから自動生成する方法を紹介。

  1. Gitリポジトリのメインページから__Add file__を選択
  2. __Creat new file__を選択
  3. 入力欄に__LICENCE__と記入すると画面右側に__Choose a licence template__が現れるので選択。
  4. 好みのライセンスを選んぶと自動生成されるので、画面上でコミットしマージ。

これでLICENCEファイル作成完了、メインブランチにPullするのを忘れずに!!

これでコードを書く部分は終了

npmアカウントを作成

こちらからアカウントを作成

ターミナルからログインしてpublish

プロジェクトルートで下記コマンドを実行。すると__Username__、Password、__Email__を尋ねられるので先ほど登録した情報を入力。

shell
$ npm login
Username:
Password:
Email:

ログインした状態で、
$ npm publish

スコープネーム(@yourname/modulename)を使っている場合は、デフォルトでprivateになっている為公開できない。なので $ npm publish --access=publicを実行

これで終わり!簡単ですね!

おまけ

人に使ってもらうものだからテストをしてしておきたい!今回はjestを使用

各パッケージをインストール

devDependenciesに追加

$ npm install --D jest @types/jest ts-jest

package.jsonを編集

  • jestのconfigを記述する
package.json
  "jest": {
    "moduleFileExtensions": [
      "ts",
      "js"//jsがないとエラーになる
    ],
    "transform": {
      "^.+\\.ts$": "ts-jest"
    },
    "globals": {
      "ts-jest": {
        "tsconfig": "tsconfig.json"
      }
    }
  }

jest.config.jsに書いてもOK

  • scriptにtestを追加
package.json
  "scripts": {
    "test": "jest",
    "build": "tsc",
    "prepublishOnly": "npm run test && npm run build"
  },

毎回公開する前にテストが走るようになってる。

テストを作成

デフォルトで__tests__フォルダー内の.js、.jsx、.ts、および.tsxファイルと、サフィックスが.testまたは.specのファイルを検索するようになってるので、__tests__フォルダ内に、index.test.tsファイルをつくる。

__tests__/index.test.ts
import generateUrl from '../index';

describe('generateUrl', () => {
  it('receives invalid url', () => {
    const baseUrl = 'this is not url';
    const params = { foo: '1', hoo: 2 };
    expect(() => generateUrl(baseUrl, params)).toThrow();
  });
});

まとめ

作ってみると意外と簡単なnpm package。公開して使ってもらえると嬉しい。毎日weekly Downloadsみちゃう。

リソース

2
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?