はじめに
- Webpack も Rollup も Babel も使わない
- tsconfig.json も使わない。コマンドライン引数だけを利用する
- React はパッケージ利用者側のものを使用する
- パッケージを公開するときに必要な認証周りについては特に触れていない
内容
まず最小の npm パッケージを作成し、徐々に拡張していく。
1. 最小の npm パッケージ
package.json
{
"name": "@penguinshunya/hoge",
"version": "0.0.1"
}
index.js
たった4行で npm パッケージを完成させられる。
2. GitHub Packages に publish
package.json
{
"name": "@penguinshunya/hoge",
"version": "0.0.2",
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
}
}
index.js
もしくは、次のコマンドでレジストリを設定する。
npm config set @penguinshunya:registry=https://npm.pkg.github.com/
この設定を行えば "publishConfig"
の設定は不要になる。
3. React
package.json
{
"name": "@penguinshunya/hoge",
"version": "0.0.3",
"peerDependencies": {
"react": "^18.2.0"
}
}
index.js
const { createElement } = require("react");
exports.HelloWorld = () => createElement("div", null, "hello, world");
4. React + TypeScript
package.json
{
"name": "@penguinshunya/hoge",
"version": "0.0.4",
"peerDependencies": {
"react": "^18.2.0"
},
"devDependencies": {
"@types/node": "^20.4.1",
"@types/react": "^18.2.14",
"typescript": "^5.1.6"
}
}
index.ts
import { createElement } from "react";
export const HelloWorld = () => {
return createElement("div", null, "hello, world");
}
次のコマンドで index.js を作成する。
npx tsc index.ts
5. React + TypeScript + JSX
package.json
{
"name": "@penguinshunya/hoge",
"version": "0.0.5",
"peerDependencies": {
"react": "^18.2.0"
},
"devDependencies": {
"@types/node": "^20.4.1",
"@types/react": "^18.2.14",
"typescript": "^5.1.6"
}
}
index.tsx
import * as React from "react";
export function HelloWorld() {
return <div>hello, world</div>;
}
次のコマンドで index.js を作成する。
npx tsc index.tsx --jsx react
tsc
コマンドだけで .tsx から .js に変換できる。
6. React + TypeScript + JSX + MUI
package.json
{
"name": "@penguinshunya/hoge",
"version": "0.0.6",
"peerDependencies": {
"react": "^18.2.0"
},
"devDependencies": {
"@types/node": "^20.4.1",
"@types/react": "^18.2.14",
"typescript": "^5.1.6"
},
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.14.0"
}
}
index.tsx
import { Button, ButtonProps } from "@mui/material";
import * as React from "react";
export type MyButtonProps = ButtonProps;
export function MyButton({ ...props }: MyButtonProps) {
return <Button variant="outlined" size="small" {...props} />
}
次のコマンドで index.js を作成する。
npx tsc index.tsx --jsx react --allowSyntheticDefaultImports
# --allowSyntheticDefaultImports を付けないと以下のエラーが発生する
# Module '"/path/to/hoge/node_modules/@types/prop-types/index"' has no default export.
7. React + TypeScript + JSX + MUI + React Query
package.json
{
"name": "@penguinshunya/hoge",
"version": "0.0.7",
"peerDependencies": {
"react": "^18.2.0"
},
"devDependencies": {
"@types/node": "^20.4.1",
"@types/react": "^18.2.14",
"typescript": "^5.1.6"
},
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.14.0",
"@tanstack/react-query": "^4.29.19"
}
}
index.tsx
import {
QueryClient,
QueryClientProvider,
useQuery,
} from "@tanstack/react-query";
import * as React from "react";
const queryClient = new QueryClient();
export interface APIProviderProps {
children?: React.ReactNode;
}
export function APIProvider({ children }: APIProviderProps) {
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
}
export function useListMember() {
return useQuery(["ListMember"], async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return [
{ id: 1, name: "foo" },
{ id: 2, name: "bar" },
];
});
}
次のコマンドで index.js を作成する。
npx tsc index.tsx --jsx react --allowSyntheticDefaultImports