{"id":19763089,"url":"https://github.com/fdiskas/devtalks-reusable-components","last_synced_at":"2026-04-17T18:01:11.049Z","repository":{"id":145457246,"uuid":"348872316","full_name":"FDiskas/devtalks-reusable-components","owner":"FDiskas","description":null,"archived":false,"fork":false,"pushed_at":"2021-03-18T10:14:35.000Z","size":111,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-28T10:17:06.670Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FDiskas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-17T22:43:20.000Z","updated_at":"2021-03-26T08:40:15.000Z","dependencies_parsed_at":"2023-04-06T05:16:59.560Z","dependency_job_id":null,"html_url":"https://github.com/FDiskas/devtalks-reusable-components","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/FDiskas/devtalks-reusable-components","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FDiskas%2Fdevtalks-reusable-components","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FDiskas%2Fdevtalks-reusable-components/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FDiskas%2Fdevtalks-reusable-components/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FDiskas%2Fdevtalks-reusable-components/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FDiskas","download_url":"https://codeload.github.com/FDiskas/devtalks-reusable-components/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FDiskas%2Fdevtalks-reusable-components/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31939788,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T17:29:20.459Z","status":"ssl_error","status_checked_at":"2026-04-17T17:28:47.801Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T04:08:07.929Z","updated_at":"2026-04-17T18:01:11.042Z","avatar_url":"https://github.com/FDiskas.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Next Project from scratch with reusable components\n\n\u003e Repository: https://github.com/FDiskas/devtalks-reusable-components\n\n## Requirements\n\n\u003e use google how to install or register\n\n- NodeJs\n- NPM + YARN\n- npmjs.com account\n- github.com account\n\n## Setup boilerplate\n\n### Create empty project\n\n1. `npx create-next-app --example with-typescript nextjs-blog`\n1. ` cd nextjs-blog`\n1. `code .`\n\n### Setup environment\n\n1. `npm i -g mrm`\n1. `mrm editorconfig -i`\n1. `mrm prettier -i`\n1. `mrm eslint -i` type `airbnb-typescript`\n1. `yarn add -D eslint-plugin-prettier`\n1. install other dependencies\n   ```\n   yarn add -D \\\n     eslint-plugin-import \\\n     eslint-plugin-jsx-a11y \\\n     eslint-plugin-react \\\n     eslint-plugin-react-hooks \\\n     @typescript-eslint/eslint-plugin \\\n     typescript-plugin-css-modules \\\n     rimraf \\\n     copyfiles\n   ```\n1. Create folder `src` and move the following `components`, `pages`, `interfaces`, `utils` folders with all contents to `src`\n\n```\n- src\n  |- components\n  |- interfaces\n  |- pages\n  |- utils\n\n```\n\n### Configure settings\n\n1. Edit `.gitignore` file and replace `/node_modules` with `node_modules/` and `/build` with `build/`\n   \u003e This will allow us to ignore such folders also deeper within nested folders\n1. Edit `.eslintrc.json` and replace `\"prettier/@typescript-eslint\",` with `\"plugin:prettier/recommended\"`\n1. Add new rule to `eslintrc.json`\n   ```json\n   \"react/prop-types\": \"off\", // Types are handled by typescript\n   \"jsx-a11y/anchor-is-valid\": [\n     \"error\",\n     {\n       \"components\": [\"Link\"],\n       \"specialLink\": [\"hrefLeft\", \"hrefRight\"],\n       \"aspects\": [\"invalidHref\", \"preferButton\"]\n     }\n   ]\n   ```\n1. Edit `.prettierrc` add to the top\n   ```\n     \"singleQuote\": true,\n     \"trailingComma\": \"es5\",\n     \"printWidth\": 100,\n   ```\n1. Edit `tsconfig.json` and add to \"compilerOptions\"\n   ```json\n   \"baseUrl\": \"./\",\n   \"plugins\": [\n     {\n       \"name\": \"typescript-plugin-css-modules\",\n       \"options\": {\n         \"classnameTransform\": \"camelCase\",\n         \"customMatcher\": \"\\\\.module\\\\.scss$\"\n       }\n     }\n   ]\n   ```\n\n### IDE Configs\n\n\u003e Restart your IDEA before starting\n\n#### vscode IDEA\n\n1. Create file `.vscode/extensions.json`\n   ```json\n   {\n     \"recommendations\": [\"dbaeumer.vscode-eslint\", \"esbenp.prettier-vscode\"]\n   }\n   ```\n1. Install thous extensions\n1. create file `.vscode/settings.json`\n   ```json\n   {\n     \"typescript.tsdk\": \"node_modules/typescript/lib\",\n     \"editor.formatOnSave\": true,\n     \"eslint.format.enable\": true,\n     \"[typescriptreact]\": {\n       \"editor.defaultFormatter\": \"dbaeumer.vscode-eslint\"\n     },\n     \"[json]\": {\n       \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n     },\n     \"[jsonc]\": {\n       \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n     },\n     \"eslint.probe\": [\n       \"javascript\",\n       \"javascriptreact\",\n       \"typescript\",\n       \"typescriptreact\",\n       \"html\",\n       \"markdown\"\n     ]\n   }\n   ```\n\n#### IntelliJ IDEA\n\n1. In the **Settings/Preferences** dialog \u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003eAlt\u003c/kbd\u003e + \u003ckbd\u003eS\u003c/kbd\u003e, go to **Languages and Frameworks | JavaScript | Prettier**.\n\n1. Choose the Node.js interpreter to use. This can be a local Node.js interpreter or a [Node.js on Windows Subsystem for Linux](https://www.jetbrains.com/help/idea/developing-node-js-applications.html#ws_node_wsl).\n\n1. From the Prettier package list, select the prettier installation to use.\n\n1. IntelliJ IDEA locates the prettier package itself and the field is filled in automatically.\n\n1. To run Prettier automatically against specific files, open the **Settings/Preferences** dialog \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eAlt\u003c/kbd\u003e+\u003ckbd\u003eS\u003c/kbd\u003e, go to **Languages and Frameworks | JavaScript | Prettier**, and use the **On code reformatting** and **On save** checkboxes to specify the actions that will trigger Prettier.\n\n## Setup workspace\n\nTo reuse our components in other projects we need make them independent from current project\n\n1. Create `package.json` within `src/components` directory\n   ```\n   yarn init -y\n   ```\n1. Open generated `package.json` and change package name to scoped name. Use your npmjs.com account username\n\n   ```json\n   \"name\": \"@fdiskas/devtalks-ui\",\n   ```\n\n1. Add `react` and `react-dom` as peer dependency. Thous packages should be installed in user side\n\n   ```json\n   \"peerDependencies\": {\n      \"@types/react\": \"^16.8.6 || ^17.0.0\",\n      \"react\": \"^16.8.0 || ^17.0.0\",\n      \"react-dom\": \"^16.8.0 || ^17.0.0\"\n   },\n   \"peerDependenciesMeta\": {\n    \"@types/react\": {\n      \"optional\": true\n    }\n   },\n   ```\n\n1. Create a workspace by adding to the root `package.json`. [More info about yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/)\n\n   ```json\n   \"private\": true,\n   \"workspaces\": [\n     \"src/components\"\n   ]\n   ```\n\n1. Create demo script at `src/components/package.json` add\n\n   ```json\n   \"scripts\": {\n     \"build\": \"echo 'yeee'\"\n   },\n   ```\n\n1. Test it - should print to console `yeee`\n   ```\n   yarn workspace @fdiskas/devtalks-ui build\n   ```\n\n## Prepare component to be build independent from main project\n\n1. Install rollup bundler and dependencies\n   ```\n   yarn workspace @fdiskas/devtalks-ui add -D \\\n     rollup \\\n     @rollup/plugin-commonjs \\\n     rollup-plugin-typescript2 \\\n     rollup-plugin-postcss \\\n     rollup-plugin-copy \\\n     @rollup/plugin-image \\\n     rollup-plugin-node-resolve \\\n     rollup-plugin-peer-deps-external\n   ```\n1. Create config file in `src/components/rollup.config.js`\n\n   ```js\n   import commonjs from '@rollup/plugin-commonjs';\n   import typescript from 'rollup-plugin-typescript2';\n   import postcss from 'rollup-plugin-postcss';\n   import copy from 'rollup-plugin-copy';\n   import image from '@rollup/plugin-image';\n   import resolve from 'rollup-plugin-node-resolve';\n   import peerDepsExternal from 'rollup-plugin-peer-deps-external';\n\n   let override = {\n     compilerOptions: {\n       jsx: 'react',\n       declaration: true,\n       module: 'ESNext',\n       declarationDir: 'src/components/typings'\n     }\n   };\n\n   export default {\n     input: './index.ts',\n     output: [\n       {\n         dir: 'build',\n         format: 'cjs',\n         sourcemap: false,\n         exports: 'named'\n       },\n       {\n         dir: 'build/esm',\n         format: 'esm',\n         sourcemap: false,\n         exports: 'named'\n       }\n     ],\n     preserveModules: true,\n     external: ['react', 'react-dom'],\n     plugins: [\n       peerDepsExternal(),\n       resolve({ browser: true }),\n       commonjs({\n         include: /node_modules/,\n         exclude: ['node_modules/process-es6/**'],\n         requireReturnsDefault: 'preferred',\n         esmExternals: true\n       }),\n       image(),\n       typescript({\n         tsconfig: '../../tsconfig.json',\n         useTsconfigDeclarationDir: true,\n         tsconfigOverride: override\n       }),\n       postcss({\n         modules: true,\n         inject: false,\n         extract: true,\n         config: { path: 'src/components/postcss.config.js' }\n       }),\n       copy({\n         targets: [\n           {\n             src: 'typings/components',\n             dest: 'build/typings'\n           }\n         ]\n       })\n     ]\n   };\n   ```\n\n1. Refactor `src/components` according to eslint rules.\n1. Refactor components as be as named export\n1. eslint will complain that preferred way is use default export - to fix that edit `.eslintrc.json` and add new rule: [more info here](https://basarat.gitbooks.io/typescript/docs/tips/defaultIsBad.html)\n\n   ```json\n   \"import/prefer-default-export\": \"off\",\n   ```\n\n1. Create build scripts at `src/components/package.json`\n\n   ```json\n     \"scripts\": {\n       \"prebuild\": \"rimraf build typings\",\n       \"build\": \"rollup -c\",\n       \"postbuild\": \"copyfiles -f 'typings/components/**/*' build/typings \u0026\u0026 rimraf typings\"\n     },\n   ```\n\n1. Specify where main files are\n\n   ```json\n    \"main\": \"build/index.js\",\n    \"module\": \"build/esm/index.js\",\n    \"typings\": \"build/typings/index.d.ts\",\n   ```\n\n1. Create `src/components/.npmignore` file\n\n   ```\n   *.ts\n   *.tsx\n   ```\n\n1. Test the build scripts - run from the root of your project\n\n   ```\n   yarn workspace @fdiskas/devtalks-ui build\n   ```\n\n1. Check contents of `src/components/build`\n   ```\n   npm pack\n   ```\n\n## Setup CD\n\nWe will use github to publish our component on git TAG\n\n1. Create new file `.github/workflows/npm-publish.yml`\n\n   ```yml\n   name: Publish Package\n\n   on:\n     create:\n       tags:\n         - v*\n\n   jobs:\n     build:\n       runs-on: ubuntu-latest\n       steps:\n         - uses: actions/checkout@v2\n         - uses: actions/setup-node@v2\n           with:\n             node-version: 14.x\n         - run: yarn install --frozen-lockfile\n         - run: yarn build\n         - run: yarn workspace @fdiskas/devtalks-ui build\n\n     publish-npm:\n       needs: build\n       runs-on: ubuntu-latest\n       steps:\n         - uses: actions/checkout@v2\n         - uses: actions/setup-node@v2\n           with:\n             node-version: 14.x\n             registry-url: https://registry.npmjs.org\n             always-auth: true\n         - run: yarn install --frozen-lockfile\n         - run: yarn workspace @fdiskas/devtalks-ui build\n         - run: yarn workspace @fdiskas/devtalks-ui version --new-version \"${GITHUB_REF:11}\" --no-git-tag-version\n         - run: yarn workspace @fdiskas/devtalks-ui publish --access public\n           env:\n             NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n\n     publish-gpr:\n       needs: build\n       runs-on: ubuntu-latest\n       steps:\n         - uses: actions/checkout@v2\n         - uses: actions/setup-node@v2\n           with:\n             node-version: 14.x\n             registry-url: https://npm.pkg.github.com\n         - run: yarn install --frozen-lockfile\n         - run: yarn workspace @fdiskas/devtalks-ui build\n         - run: yarn workspace @fdiskas/devtalks-ui version --new-version \"${GITHUB_REF:11}\" --no-git-tag-version\n         - run: yarn workspace @fdiskas/devtalks-ui publish --access public\n           env:\n             NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n   ```\n\n1. Login to npm\n\n   ```\n   npm login\n   ```\n\n1. Open file on your home directory `~/.npmrc` and copy value of:\n\n   ```\n   //registry.npmjs.org/:_authToken=********\n   ```\n\n1. Go to github repository settings `settings/secrets/actions/new`\n1. Create New secret Name: `NPM_TOKEN` value your auth token\n1. Go to github repository and create new release `releases/new`\n1. Add your first tag `v1.0.1` and additional release info\n1. Click \u003ckbd\u003ePublish release\u003c/kbd\u003e and check how CI is running `actions/`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffdiskas%2Fdevtalks-reusable-components","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffdiskas%2Fdevtalks-reusable-components","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffdiskas%2Fdevtalks-reusable-components/lists"}