初期化　ゼロからReact コンポーネントライブラリ(1)


最近、自分のReactコンポーネントライブラリを作ってみたいと思います。
**千里の旅も一歩から、始めましょう。**

### storybook プロジェクト　初期化
```cmd:npm
npm init
```

アップロード
```cmd:git
git init
git commit -m "first commit"
git branch -M master
git remote add origin git@github.com:***/***.git
git push -u origin master
```

.gitignore
```bat:cmd-cli
echo // project> .gitignore
echo node_modules> .gitignore
echo;>> .gitignore
echo // vscode>> .gitignore
echo .history>> .gitignore
```

webpack
```cmd:npm
npm install webpack webpack-cli --save-dev
```

```cmd:npm
npm i typescript ts-loader --save-dev
npx tsc --init
npx storybook@latest init
```

storybook スタイルの配置 [storybook:theme](https://storybook.js.org/docs/configure/theming)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/68553d3c-8589-65e8-6dc7-f08930b27ad1.png)

:::note alert
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
:::

[storybook loader](https://storybook.js.org/docs/builders/webpack#override-the-default-configuration)
1.ローダーを追加する
```cmd:npm
npm install --save-dev css-loader sass-loader
```
2.配置を追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/cd21fd5b-1711-5f02-b774-961d9752a4b7.png)
<details><summary>./storybook/main.ts</summary>

```typescript:./storybook/main.ts
import type { StorybookConfig } from "@storybook/react-webpack5";
import { Configuration } from "webpack";

const config: StorybookConfig = {
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-onboarding",
    "@storybook/addon-interactions",
  ],
  framework: {
    name: "@storybook/react-webpack5",
    options: {
      builder: {
        useSWC: true,
      },
    },
  },
  docs: {
    autodocs: "tag",
  },
  webpackFinal: async (config: Configuration) => {
    const { module = {} } = config;
    const { rules = [] } = module;
    return {
      ...config,
      module: {
        ...module, rules: [
          ...rules,
          {
            test: /\.sass$/,
            use: [
              { loader: 'style-loader' },
              {
                loader: 'css-loader',
                options: {
                  modules: true,
                },
              },
              { loader: 'sass-loader' },
            ],
          },
        ]
      },
    };
  },
};
export default config;
```
</details>

::: note alert
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
Error: Cannot find module 'sass'
:::
```cmd:npm
npm install --save-dev sass
```

成功して実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/929d7f22-1521-cd9b-8eed-735c1808cafa.png)

ログイン[chromatic](https://www.chromatic.com/) プロジェクトtokenを作成する
npx chromatic --project-token=token

::: note alert
Cannot find module './Button.sass' or its corresponding type declarations.ts(2307)
:::

```typescript:global.d.ts
declare module '*.sass' {
    const content: Record<string, string>;
    export default content;
}
```

::: note alert
No inputs were found in config file 'd:/coding/choas-react/tsconfig.json'. Specified 'include' paths were '[]' and 'exclude' paths were '["node_modules"]'.ts
:::

```json:tsconfig.json
"include": [
    "./src/**/*"
]
  ```
-------------------------------------------------
### コンポーネント プロジェクト　初期化

```cmd:init
npm init
npx tsc init
git init
npm i --save-dev webpack webpack-cli react-dom react sass typescript
npm i --save-dev css-loader style-loader ts-loader sass-loader
npm i --save-dev fs path
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/8dedab33-abf4-c773-0b6f-06d5d0122be5.png)

```javascript:build.js
const { exec } = require('child_process');
const path = require('path');

exec('npx webpack --config ' + path.resolve(__dirname, './webpack/common.js'), console.log);
```

```javascript:webpack/common.js
const path = require('path');
const TerserWebpack =  require("terser-webpack-plugin");
const { createEntries } = require('./function');

module.exports = {
    entry: createEntries(),
    mode: "production",
    output: {
        path: path.join(__dirname, '../../lib'),
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                test: /\.sass$/,
                use: [
                    { loader: 'style-loader' },
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true,
                        },
                    },
                    { loader: 'sass-loader' },
                ],
            },
            {
                test: /\.tsx?$/,
                use: [
                    { loader: 'ts-loader' },
                ]
            }
        ]
    },
    plugins:[
        new TerserWebpack({
            extractComments: false,
        })
    ],
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
    },
};
```

```javascript:webpack/function.js
const path = require('path');

const createEntries = () => {
    const jsonConfig = require('../component/list.json');
    let entries = {};
    Object.keys(jsonConfig).forEach(key => {
        entries[key] = './src/' + jsonConfig[key];
    })
    return entries;
}

module.exports = {
    createEntries
}
```

```cmd:init
npm run build
npm whoami
npm publish
```

LICENSE ファイルがremove
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/99921ced-6026-5c2a-a859-9cfb2073eb25.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/e0bfede1-ab51-9bc3-e967-9eff7eba85d0.png)

----------------------
### 新しいtest-projectを作成する

```tsx: App.tsx
import React from 'react';
import {Button}  from '../../choas-react/src/Button'

function App() {
  return (
    <Button>123</Button>
  );
}

export default App;
```

::: note alert
You can either move it inside src/, or add a symlink to it from project's node_modules/
:::

[stackoverflow - imports-restriction-outside-of-src-directory](https://stackoverflow.com/questions/44114436/the-create-react-app-imports-restriction-outside-of-src-directory)

```json: package.json
"dependencies": {
  "app-b-dashboard": "file:./packages/app-b-dashboard"
}
```
```cmd: npm
npm i 
```

::: note alert
Module parse failed: The keyword 'interface' is reserved (7:0)
File was processed with these loaders:
 * ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
 * ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| import styles from './index.sass';
| 
> interface ButtonProps {
|   children: React.ReactNode,
|   type?: 'primary' | 'danger' | 'normal' | 'dot' | 'link',
:::

node_modulesの方法でインポートして、コンパイルされていないとおもいます。
そして、**include**ファイルを**削除**する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/1f156420-76b0-1220-cc38-3f2327145c9b.png)

実装できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/39c3f32b-9e7e-e249-a886-ae1d81c37f08.png)

良さはコンポネント　プロジェクトの**変化**に伴い変化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/e0c866d0-c367-7727-d34e-297a3a378d63.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/02d220f6-494a-bc09-5faf-0f65ec768855.png)

今三つのプロジェクトがあります。
**react-component**
**react-storybook**
**react-test**


https://qiita.com/faliye/items/5d69350cdeaa40a48b97