@getsoren/create-boilerplate-vite-react-ts 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @getsoren/create-boilerplate-vite-react-ts might be problematic. Click here for more details.

Files changed (48) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.json +6 -0
  3. package/.github/pull_request_template.md +2 -0
  4. package/.github/workflows/release.yml +66 -0
  5. package/.husky/pre-commit +8 -0
  6. package/CHANGELOG.md +6 -0
  7. package/README.md +97 -0
  8. package/bin/create-app.cjs +269 -0
  9. package/bun.lockb +0 -0
  10. package/index.html +13 -0
  11. package/index.tsx +9 -0
  12. package/package.json +64 -0
  13. package/public/.readme.md +1 -0
  14. package/public/favicon.ico +0 -0
  15. package/src/App.test.tsx +10 -0
  16. package/src/App.tsx +3 -0
  17. package/src/assets/.readme.md +1 -0
  18. package/src/components/.readme.md +4 -0
  19. package/src/components/DataDisplay/.readme.md +1 -0
  20. package/src/components/Feedback/.readme.md +1 -0
  21. package/src/components/Inputs/.readme.md +1 -0
  22. package/src/components/Layout/.readme.md +1 -0
  23. package/src/components/Navigation/.readme.md +1 -0
  24. package/src/components/Surfaces/.readme.md +1 -0
  25. package/src/components/Utils/.readme.md +1 -0
  26. package/src/components/Utils/Router.tsx +17 -0
  27. package/src/constants/.readme.md +3 -0
  28. package/src/constants/routes.ts +6 -0
  29. package/src/context/.readme.md +3 -0
  30. package/src/features/.readme.md +12 -0
  31. package/src/hooks/.readme.md +1 -0
  32. package/src/locales/.readme.md +1 -0
  33. package/src/locales/en.ts +3 -0
  34. package/src/locales/fr.ts +3 -0
  35. package/src/pages/.readme.md +6 -0
  36. package/src/pages/Contact.tsx +12 -0
  37. package/src/pages/Home.tsx +12 -0
  38. package/src/services/.readme.md +3 -0
  39. package/src/stores/.readme.md +2 -0
  40. package/src/test.config.ts +4 -0
  41. package/src/types/.readme.md +2 -0
  42. package/src/types/dependencies.d.ts +8 -0
  43. package/src/types/i18next.d.ts +10 -0
  44. package/src/types/vite-env.d.ts +1 -0
  45. package/src/utils/.readme.md +2 -0
  46. package/tsconfig.json +46 -0
  47. package/tsconfig.node.json +15 -0
  48. package/vite.config.ts +19 -0
package/.eslintignore ADDED
@@ -0,0 +1,2 @@
1
+ dist
2
+ node_modules
package/.eslintrc.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "@getsoren/eslint-config-react-soren",
3
+ "rules": {
4
+ "import/no-extraneous-dependencies": "off"
5
+ }
6
+ }
@@ -0,0 +1,2 @@
1
+ - [ ] Add your new version inside [package.json](package.json)
2
+ - [ ] Change version & describe your change inside [CHANGELOG.md](CHANGELOG.md)
@@ -0,0 +1,66 @@
1
+ name: 🚀 Release
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ release:
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: 🛎️ Checkout
18
+ uses: actions/checkout@v4
19
+ with:
20
+ fetch-depth: 0
21
+
22
+ - name: 🐰 Setup Bun
23
+ uses: oven-sh/setup-bun@v1
24
+
25
+ - name: 📦 Install dependencies
26
+ run: bun install
27
+
28
+ - name: 🧑 Configure Git identity
29
+ run: |
30
+ git config --local user.name "github-actions[bot]"
31
+ git config --local user.email "github-actions[bot]@users.noreply.github.com"
32
+
33
+ - name: 🏷️ Bump version & generate changelog
34
+ id: bump
35
+ run: |
36
+ PREV_VERSION=$(jq -r .version package.json)
37
+ bun run release
38
+ NEW_VERSION=$(jq -r .version package.json)
39
+ echo "prev_version=$PREV_VERSION" >> $GITHUB_OUTPUT
40
+ echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
41
+
42
+ - name: 🚀 Push changes and tags
43
+ if: steps.bump.outputs.prev_version != steps.bump.outputs.new_version
44
+ run: |
45
+ git push origin HEAD:${{ github.ref }}
46
+ git push --tags
47
+
48
+ - name: 🏗️ Build
49
+ if: steps.bump.outputs.prev_version != steps.bump.outputs.new_version
50
+ run: bun run build
51
+
52
+ - name: 📝 Create GitHub Release
53
+ if: steps.bump.outputs.prev_version != steps.bump.outputs.new_version
54
+ run: gh release create "${{ steps.bump.outputs.new_version }}" -F CHANGELOG.md
55
+ env:
56
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57
+
58
+ - name: 🔐 Setup npm auth
59
+ if: steps.bump.outputs.prev_version != steps.bump.outputs.new_version
60
+ run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" > ~/.npmrc
61
+
62
+ - name: 📤 Publish to npm
63
+ if: steps.bump.outputs.prev_version != steps.bump.outputs.new_version
64
+ env:
65
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
66
+ run: npm publish --access public
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env sh
2
+ . "$(dirname -- "$0")/_/husky.sh"
3
+
4
+ echo "\033[32m Running linters... \033[0m";
5
+ yarn lint
6
+
7
+ echo "\033[32m Running test... \033[0m";
8
+ yarn test --watch=false
package/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # [Versions](https://github.com/Tracktor/eslint-config-react-tracktor/releases)
2
+
3
+
4
+ ## v2.7.1
5
+ - **[fix]** : fix install dependency command
6
+ - **[fix]** : remove lock file after install dependency command
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # @getsoren/create-boilerplate-vite-react-ts
2
+
3
+ > Create quickly a skeleton of `Vite React TypeScript`
4
+ application with amazing configuration.
5
+
6
+ - [Quick Start](#Quick-Start)
7
+ - [Optional params](#Optional-params)
8
+ - [Files structure](#Files-structure)
9
+
10
+ ## Quick Start
11
+
12
+ **bun:**
13
+ ```bash
14
+ bun create @getsoren/boilerplate-vite-react-ts YOUR_APP_NAME
15
+ ```
16
+
17
+ **npm:**
18
+ ```bash
19
+ npm create @getsoren/boilerplate-vite-react-ts YOUR_APP_NAME
20
+ ```
21
+ **yarn**:
22
+ ```bash
23
+ yarn create @getsoren/boilerplate-vite-react-ts YOUR_APP_NAME
24
+ ```
25
+ **pnpm**:
26
+ ```bash
27
+ pnpm create @getsoren/boilerplate-vite-react-ts YOUR_APP_NAME
28
+ ```
29
+
30
+ > Note: `npm create @scope/foo` is equivalent to `npm init @scope/foo`, which resolves to the package `@scope/create-foo`.
31
+
32
+ ## Optional params
33
+
34
+ You can add some params to install and configure automatically
35
+ some popular libraries.
36
+
37
+ | Name | Description | Documentation |
38
+ |----------------|------------------------------|-------------------------------------------------|
39
+ | `axios` | Install axios library | [axios](https://axios-http.com/fr/docs/intro) |
40
+ | `i18next` | Install i18next library | [i18next](https://www.i18next.com) |
41
+ | `react-query` | Install react query library | [react-query](https://react-query.tanstack.com) |
42
+ | `react-router` | Install react router library | [react-router](https://reactrouter.com) |
43
+ <br>
44
+ example:
45
+
46
+ ```console
47
+ npm create @getsoren/boilerplate-vite-react-ts YOUR_APP_NAME --axios --i18next
48
+ ```
49
+
50
+ ## Files structure
51
+
52
+ ```
53
+ ├── .husky
54
+ pre-commit
55
+ ├── public
56
+ favicon.ico
57
+ └── src
58
+ └── assets
59
+ └── components
60
+ └── DataDisplay
61
+ └── Feedback
62
+ └── Inputs
63
+ └── Layout
64
+ └── Navigation
65
+ └── Surfaces
66
+ └── Utils
67
+ Router.tsx (optional if react-router is installed)
68
+ └── constants
69
+ routes.ts (optional if react-router is installed)
70
+ └── context
71
+ └── features
72
+ └── hooks
73
+ └── locales
74
+ └── pages
75
+ Contact.tsx (optional if react-router is installed)
76
+ Home.tsx (optional if react-router is installed)
77
+ └── services
78
+ └── stores
79
+ └── types
80
+ i18next.d.ts (optional if i18next is installed)
81
+ vite-env.d.ts
82
+ └── utils
83
+ App.test.tsx
84
+ App.tsx
85
+ test.config.ts
86
+ .eslintignore
87
+ .eslintrc.json
88
+ .gitignore
89
+ index.html
90
+ index.tsx
91
+ package.json
92
+ README.md
93
+ tsconfig.json
94
+ tsconfig.node.json
95
+ vite.config.ts
96
+ [yarn.lock|pnpm-lock.yaml|package-lock.json|bun.lockb]
97
+ ```
@@ -0,0 +1,269 @@
1
+ #!/usr/bin/env node
2
+ const yargs = require("yargs")
3
+ const {join} = require("path");
4
+ const {execSync} = require("child_process");
5
+ const {mkdirSync, rmSync, openSync, writeFileSync, close, writeSync, appendFileSync} = require("fs");
6
+ const packageJson = require("../package.json");
7
+ const eslintrcJson = require("../.eslintrc.json");
8
+
9
+ const ENCODED_FILE = "utf8";
10
+
11
+ const PROJECT_NAME = process.argv[2];
12
+ const CURRENT_PATH = process.cwd();
13
+ const PROJECT_PATH = join(CURRENT_PATH, PROJECT_NAME);
14
+ const REPOSITORY_URL = packageJson.repository.url;
15
+ const PACKAGE_INFO = pkgFromUserAgent(process.env.npm_config_user_agent);
16
+
17
+ const PACKAGE_MANAGER = PACKAGE_INFO ? PACKAGE_INFO : "npm";
18
+
19
+ // Optional parameters
20
+ const AXIOS_PARAM = "axios";
21
+ const I18NEXT_PARAM = "i18next";
22
+ const REACT_QUERY_PARAM = "react-query";
23
+ const REACT_ROUTER_PARAM = "react-router";
24
+
25
+ if (process.argv.length < 3) {
26
+ console.log("\x1b[31m", "You have to provide name to your app.");
27
+ console.log("For example: ");
28
+ console.log(PACKAGE_MANAGER + " create boilerplate-vite-react-ts YOUR_APP_NAME", "\x1b[0m");
29
+ process.exit(1);
30
+ }
31
+
32
+ try {
33
+ mkdirSync(PROJECT_PATH);
34
+ } catch (error) {
35
+ if (error?.code === "EEXIST") {
36
+ console.log(`The file ${PROJECT_NAME} already exist in the current directory, please give it another name.`);
37
+ } else {
38
+ console.log(error);
39
+ }
40
+ process.exit(1);
41
+ }
42
+
43
+ function pkgFromUserAgent(userAgent) {
44
+ if (!userAgent) return undefined;
45
+ const pkgSpec = userAgent.split(' ')[0];
46
+ return pkgSpec.split('/')[0];
47
+ }
48
+
49
+ const buildPackageJson = ({packageJson, argv}) => {
50
+ // Filters package.json
51
+ const {
52
+ bin,
53
+ keywords,
54
+ homepage,
55
+ repository,
56
+ bugs,
57
+ version,
58
+ description,
59
+ ...packageJsonFilter
60
+ } = packageJson;
61
+
62
+ // Filters dependencies
63
+ const {
64
+ yargs,
65
+ [!argv?.[AXIOS_PARAM] && "axios"]: axiosRemoved,
66
+ [!argv?.[I18NEXT_PARAM] && "i18next"]: i18nextRemoved,
67
+ [!argv?.[I18NEXT_PARAM] && "react-i18next"]: reactI18nextRemoved,
68
+ [!argv?.[I18NEXT_PARAM] && "i18next-browser-languagedetector"]: i18nextBrowserLanguageDetectorRemoved,
69
+ [!argv?.[REACT_QUERY_PARAM] && "@tanstack/react-query"]: reactQueryRemoved,
70
+ ...dependenciesFilter
71
+ } = packageJson.dependencies;
72
+
73
+ // Filters scripts
74
+ const {
75
+ create,
76
+ ...scriptFilter
77
+ } = packageJson.scripts
78
+
79
+ const newPackage = {
80
+ ...packageJsonFilter,
81
+ name: argv._[0],
82
+ license: "UNLICENSED",
83
+ dependencies: {
84
+ ...dependenciesFilter,
85
+ },
86
+ scripts: {
87
+ ...scriptFilter,
88
+ }
89
+ };
90
+
91
+ writeFileSync(`${process.cwd()}/package.json`, JSON.stringify(newPackage, null, 2), ENCODED_FILE);
92
+ };
93
+
94
+ const buildEslintJson = (eslintrcJson) => {
95
+ const {rules, ...eslintrcJsonFilter} = eslintrcJson
96
+
97
+ writeFileSync(`${process.cwd()}/.eslintrc.json`, JSON.stringify(eslintrcJsonFilter, null, 2), ENCODED_FILE);
98
+ };
99
+
100
+ const buildSetupTest = () => {
101
+
102
+ if (yargs.argv?.[I18NEXT_PARAM]) {
103
+ const data = `\n` +
104
+ `// Mock translation` + `\n` +
105
+ `vi.mock("react-i18next", async () => {` + `\n` +
106
+ ` const actual: any = await vi.importActual("react-i18next");` + `\n` +
107
+ ` return {` + `\n` +
108
+ ` ...actual,` + `\n` +
109
+ ` useTranslation: () => ({` + `\n` +
110
+ ` i18n: {` + `\n` +
111
+ ` changeLanguage: () => new Promise(() => {}),` + `\n` +
112
+ ` },` + `\n` +
113
+ ` t: (str: string) => str,` + `\n` +
114
+ ` }),` + `\n` +
115
+ ` };` + `\n` +
116
+ `});`;
117
+
118
+ appendFileSync("src/test.config.ts", data);
119
+ }
120
+ };
121
+
122
+
123
+ const removeUselessFiles = () => {
124
+ execSync("npx rimraf ./.git");
125
+ rmSync(join(PROJECT_PATH, ".github"), {recursive: true});
126
+ rmSync(join(PROJECT_PATH, ".circleci"), {recursive: true});
127
+ rmSync(join(PROJECT_PATH, "bin"), {recursive: true});
128
+ rmSync(join(PROJECT_PATH, "CHANGELOG.md"), {recursive: true});
129
+ rmSync(join(PROJECT_PATH, "src/types/dependencies.d.ts"), {recursive: true});
130
+
131
+
132
+ // Remove i18next files
133
+ if (!yargs.argv?.[I18NEXT_PARAM]) {
134
+ rmSync(join(PROJECT_PATH, "src/locales/en.ts"), {recursive: true});
135
+ rmSync(join(PROJECT_PATH, "src/locales/fr.ts"), {recursive: true});
136
+ rmSync(join(PROJECT_PATH, "src/types/i18next.d.ts"), {recursive: true});
137
+ }
138
+
139
+ // Remove react router dom files
140
+ if (!yargs.argv?.[REACT_ROUTER_PARAM]) {
141
+ rmSync(join(PROJECT_PATH, "src/components/Utils/Router.tsx"), {recursive: true});
142
+ rmSync(join(PROJECT_PATH, "src/constants/routes.ts"), {recursive: true});
143
+ rmSync(join(PROJECT_PATH, "src/pages/Contact.tsx"), {recursive: true});
144
+ rmSync(join(PROJECT_PATH, "src/pages/Home.tsx"), {recursive: true});
145
+ }
146
+ };
147
+
148
+ const getAppData = () => {
149
+ let data = [];
150
+ const children = yargs.argv?.[REACT_ROUTER_PARAM] ? "<Router />" : `<h1>${packageJson.name}</h1>`;
151
+
152
+ if (yargs.argv?.[REACT_QUERY_PARAM]) {
153
+ data.push(`import { QueryClientProvider } from "@tanstack/react-query";\n`)
154
+ }
155
+
156
+ if (yargs.argv?.[REACT_ROUTER_PARAM]) {
157
+ data.push(`import Router from "@/components/Utils/Router";\n`)
158
+ }
159
+
160
+ if (yargs.argv?.[REACT_QUERY_PARAM]) {
161
+ data.push(`import reactQueryConfig from "@/config/reactQuery.config";\n`)
162
+ }
163
+
164
+ if (yargs.argv?.[AXIOS_PARAM]) {
165
+ data.push(`import "@/config/axios.config";\n`)
166
+ }
167
+
168
+ if (yargs.argv?.[I18NEXT_PARAM]) {
169
+ data.push(`import "@/config/i18next.config";\n`)
170
+ }
171
+
172
+ if (yargs.argv?.[REACT_QUERY_PARAM]) {
173
+ data.push(
174
+ `\nconst App = () => (` +
175
+ `\n <QueryClientProvider client={reactQueryConfig}>` +
176
+ `\n ${children}` +
177
+ `\n </QueryClientProvider>` +
178
+ `\n);`
179
+ )
180
+ } else {
181
+ const breakLine = data.length === 0 ? "" : "\n";
182
+ data.push(`${breakLine}const App = () => ${children};`);
183
+ }
184
+
185
+ data.push(`\n\nexport default App;`)
186
+
187
+ return data.join("") + "\n";
188
+ }
189
+
190
+ const buildAppFile = () => {
191
+ const file = "src/App.tsx";
192
+ const fd = openSync(file, "w+");
193
+ const data = getAppData();
194
+ const buffer = Buffer.from(data);
195
+
196
+ writeSync(fd, buffer, 0, buffer.length, 0); //write new data
197
+ close(fd);
198
+ };
199
+
200
+ const installDependencies = () => {
201
+ const installDependencyCommand = PACKAGE_MANAGER === "npm" ? "install" : "add";
202
+
203
+ execSync(`${PACKAGE_MANAGER} install`);
204
+
205
+ if (yargs.argv?.[AXIOS_PARAM]) {
206
+ execSync(`${PACKAGE_MANAGER} ${installDependencyCommand} axios`);
207
+ }
208
+
209
+ if (yargs.argv?.[I18NEXT_PARAM]) {
210
+ execSync(`${PACKAGE_MANAGER} ${installDependencyCommand} i18next`);
211
+ execSync(`${PACKAGE_MANAGER} ${installDependencyCommand} react-i18next`);
212
+ execSync(`${PACKAGE_MANAGER} ${installDependencyCommand} i18next-browser-languagedetector`);
213
+ }
214
+
215
+ if (yargs.argv?.[REACT_QUERY_PARAM]) {
216
+ execSync(`${PACKAGE_MANAGER} ${installDependencyCommand} @tanstack/react-query`);
217
+ }
218
+
219
+ if (yargs.argv?.[REACT_ROUTER_PARAM]) {
220
+ execSync(`${PACKAGE_MANAGER} ${installDependencyCommand} react-router-dom`);
221
+ }
222
+
223
+ // Remove lock file before install, user don't need it
224
+ rmSync(join(PROJECT_PATH, "bun.lockb"), {recursive: true});
225
+ };
226
+
227
+ const main = async () => {
228
+ try {
229
+ // Clear npx cache
230
+ console.log("\n\x1b[36m%s\x1b[0m", "Clear npx cache...");
231
+ execSync("rm -rf ~/.npm/_npx");
232
+
233
+ // Download files
234
+ console.log("\x1b[36m%s\x1b[0m", "Downloading files...");
235
+ execSync(`git clone --depth 1 ${REPOSITORY_URL} ${PROJECT_PATH}`);
236
+
237
+ // Change directory
238
+ process.chdir(PROJECT_PATH);
239
+
240
+ // Create package.json & .eslintrc.json
241
+ console.log("\x1b[36m%s\x1b[0m", "Create package.json & .eslintrc.json...");
242
+ buildPackageJson({packageJson, argv: yargs.argv});
243
+
244
+ // Install dependencies
245
+ console.log("\x1b[36m%s\x1b[0m", "Installing dependencies...");
246
+ installDependencies();
247
+
248
+ // Generate Files.tsx
249
+ console.log("\x1b[36m%s\x1b[0m", "Generate Files...");
250
+ buildAppFile();
251
+ buildEslintJson(eslintrcJson);
252
+ buildSetupTest();
253
+
254
+ // Remove useless files
255
+ console.log("\x1b[36m%s\x1b[0m", "Clean up unused file...");
256
+ removeUselessFiles();
257
+
258
+ // Create empty README.md
259
+ console.log("\x1b[36m%s\x1b[0m", "Create empty README.md...");
260
+ openSync("README.md", "w");
261
+
262
+ // Done
263
+ console.log("\x1b[32m%s\x1b[0m", "Your application is ready, enjoy to use !");
264
+ } catch (error) {
265
+ console.log(error);
266
+ }
267
+ };
268
+
269
+ main().then();
package/bun.lockb ADDED
Binary file
package/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Vite + React + TS</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/index.tsx"></script>
12
+ </body>
13
+ </html>
package/index.tsx ADDED
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom/client";
3
+ import App from "./src/App";
4
+
5
+ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
6
+ <React.StrictMode>
7
+ <App />
8
+ </React.StrictMode>,
9
+ );
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@getsoren/create-boilerplate-vite-react-ts",
3
+ "description": "Start a Vite React TypeScript project in few second !",
4
+ "private": false,
5
+ "license": "ISC",
6
+ "version": "2.7.1",
7
+ "type": "module",
8
+ "author": "Mickaël Austoni",
9
+ "homepage": "https://github.com/getsoren/create-boilerplate-vite-react-ts#readme",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/getsoren/create-boilerplate-vite-react-ts.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/getsoren/create-boilerplate-vite-react-ts/issues"
16
+ },
17
+ "bin": {
18
+ "create-boilerplate-vite-react-ts": "bin/create-app.cjs"
19
+ },
20
+ "scripts": {
21
+ "dev": "vite",
22
+ "build": "tsc && vite build",
23
+ "create": "node bin/create-app.cjs dist --axios --i18next --react-query --react-router",
24
+ "lint": "eslint . --max-warnings=0 && tsc --noEmit",
25
+ "preview": "vite preview",
26
+ "test": "yarn lint && vitest",
27
+ "prepare": "husky install",
28
+ "release": "commit-and-tag-version"
29
+ },
30
+ "dependencies": {
31
+ "react": "^18.2.0",
32
+ "react-dom": "^18.2.0",
33
+ "yargs": "^17.7.2"
34
+ },
35
+ "devDependencies": {
36
+ "@testing-library/jest-dom": "^5.16.5",
37
+ "@testing-library/react": "^14.0.0",
38
+ "@testing-library/user-event": "^14.4.3",
39
+ "@types/react": "^18.2.14",
40
+ "@types/react-dom": "^18.2.6",
41
+ "@vitejs/plugin-react": "^3.1.0",
42
+ "@getsoren/eslint-config-react-soren": "^1.14.0",
43
+ "husky": "^8.0.3",
44
+ "jsdom": "^22.1.0",
45
+ "typescript": "^4.9.5",
46
+ "vite": "^4.3.9",
47
+ "vitest": "^0.32.2",
48
+ "commit-and-tag-version": "^12.6.0"
49
+ },
50
+ "keywords": [
51
+ "react",
52
+ "react create app",
53
+ "vite create app",
54
+ "react router",
55
+ "i18next",
56
+ "react-query",
57
+ "javascript",
58
+ "typescript"
59
+ ],
60
+ "commit-and-tag-version": {
61
+ "releaseCommitMessageFormat": "chore(release): {{currentTag}} [skip ci]",
62
+ "tagPrefix": ""
63
+ }
64
+ }
@@ -0,0 +1 @@
1
+ **_Public folder_**
Binary file
@@ -0,0 +1,10 @@
1
+ import { render } from "@testing-library/react";
2
+ import { expect, test } from "vitest";
3
+ import App from "@/App";
4
+
5
+ test("render <App />", () => {
6
+ const { getByText } = render(<App />);
7
+ const title = getByText("create-boilerplate-vite-react-ts");
8
+
9
+ expect(title).toBeInTheDocument();
10
+ });
package/src/App.tsx ADDED
@@ -0,0 +1,3 @@
1
+ const App = () => <h1>create-boilerplate-vite-react-ts</h1>;
2
+
3
+ export default App;
@@ -0,0 +1 @@
1
+ **_This directory contains assets files like images, fonts, ..._**
@@ -0,0 +1,4 @@
1
+ **_This directory contains reusable components that are
2
+ most often used to compose Feature or Page components.
3
+ These components are almost always pure and presentational,
4
+ with no side-effects._**
@@ -0,0 +1 @@
1
+ **_This directory contains all data display components_**
@@ -0,0 +1 @@
1
+ **_This directory contains all feedback components_**
@@ -0,0 +1 @@
1
+ **_This directory contains all inputs components_**
@@ -0,0 +1 @@
1
+ **_This directory contains all layouts components_**
@@ -0,0 +1 @@
1
+ **_This directory contains all navigation components_**
@@ -0,0 +1 @@
1
+ **_This directory contains all surfaces components_**
@@ -0,0 +1 @@
1
+ **_This directory contains all utils components_**
@@ -0,0 +1,17 @@
1
+ import { createBrowserRouter, createRoutesFromElements, Route, RouterProvider } from "react-router-dom";
2
+ import ROUTES from "@/constants/routes";
3
+ import Contact from "@/pages/Contact";
4
+ import Home from "@/pages/Home";
5
+
6
+ const router = createBrowserRouter(
7
+ createRoutesFromElements(
8
+ <>
9
+ <Route path={ROUTES.home} element={<Home />} />
10
+ <Route path={ROUTES.contact} element={<Contact />} />
11
+ </>,
12
+ ),
13
+ );
14
+
15
+ const Router = () => <RouterProvider router={router} />;
16
+
17
+ export default Router;
@@ -0,0 +1,3 @@
1
+ **_This directory contains reusable & immutable
2
+ constant like URL, regex, ..._**
3
+ `
@@ -0,0 +1,6 @@
1
+ const ROUTES = {
2
+ contact: "/contact",
3
+ home: "/",
4
+ } as const;
5
+
6
+ export default ROUTES;
@@ -0,0 +1,3 @@
1
+ **_This directory contains reusable contexts used to provide data through
2
+ a tree of components. If using Redux or React Sweet State this
3
+ directory is likely not needed._**
@@ -0,0 +1,12 @@
1
+ **_This directory contains reusable Feature Components.
2
+ A Feature Component is a concept inspired by Redux in which
3
+ all logic required for a feature is co-located to a single directory.
4
+ A Feature Component is often composed of many other components,
5
+ either local or shared. The same is true for all resources:
6
+ utils, types, hooks, and so on._**
7
+
8
+ **_Feature Components often include side effects._**
9
+
10
+ **_f using Redux, and interacts with the Store,
11
+ the Feature Component will include a slice file
12
+ that defines the “slice” of the Redux Store the feature represents._**
@@ -0,0 +1 @@
1
+ **_This directory contains reusable React Hooks._**
@@ -0,0 +1 @@
1
+ **_This directory contains translation files._**
@@ -0,0 +1,3 @@
1
+ const en = {};
2
+
3
+ export default en;
@@ -0,0 +1,3 @@
1
+ const fr = {};
2
+
3
+ export default fr;
@@ -0,0 +1,6 @@
1
+ **_This directory contains Page Components.
2
+ Each Page Component is associated with a route.
3
+ Page Components compose the content of a page by importing
4
+ Components and Feature Components. A Page Component
5
+ should rarely include side effects, and should instead
6
+ delegate side effects to Feature Components_**
@@ -0,0 +1,12 @@
1
+ import { Link } from "react-router-dom";
2
+ import ROUTES from "@/constants/routes";
3
+
4
+ const Contact = () => (
5
+ <>
6
+ <h1>create-boilerplate-vite-react-ts</h1>
7
+ <h2>Contact</h2>
8
+ <Link to={ROUTES.home}>Go to home</Link>
9
+ </>
10
+ );
11
+
12
+ export default Contact;
@@ -0,0 +1,12 @@
1
+ import { Link } from "react-router-dom";
2
+ import ROUTES from "@/constants/routes";
3
+
4
+ const Home = () => (
5
+ <>
6
+ <h1>create-boilerplate-vite-react-ts</h1>
7
+ <h2>Home</h2>
8
+ <Link to={ROUTES.contact}>Go to contact</Link>
9
+ </>
10
+ );
11
+
12
+ export default Home;
@@ -0,0 +1,3 @@
1
+ **\*This directory contains reusable code for interacting with an API,
2
+ often in the form of hooks or fetcher. This directory
3
+ should only contain code for interacting with an API.\*\***
@@ -0,0 +1,2 @@
1
+ **_This directory contains all global states that can be
2
+ accessed from any component within the application from store._**
@@ -0,0 +1,4 @@
1
+ // jest-dom adds custom jest matchers for asserting on DOM nodes.
2
+ // allows you to do things like:
3
+ // expect(element).toHaveTextContent(/react/i)
4
+ import "@testing-library/jest-dom";
@@ -0,0 +1,2 @@
1
+ **_This directory contains reusable types for projects
2
+ utilizing TypeScript or Flow._**
@@ -0,0 +1,8 @@
1
+ // This resolves the issue of typescript
2
+ // not recognizing the types of the dependencies
3
+ declare module "@tanstack/react-query";
4
+ declare module "axios";
5
+ declare module "i18next";
6
+ declare module "i18next-browser-languagedetector";
7
+ declare module "react-i18next";
8
+ declare module "react-router-dom";
@@ -0,0 +1,10 @@
1
+ import en from "@/locales/en";
2
+
3
+ declare module "i18next" {
4
+ interface CustomTypeOptions {
5
+ returnNull: false;
6
+ resources: {
7
+ translation: typeof en;
8
+ };
9
+ }
10
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,2 @@
1
+ **_This directory contains reusable utility functions.
2
+ These functions should always be pure and produce no side effects._**
package/tsconfig.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "target": "ESNext",
5
+ "useDefineForClassFields": true,
6
+ "lib": [
7
+ "DOM",
8
+ "DOM.Iterable",
9
+ "ESNext"
10
+ ],
11
+ "allowJs": false,
12
+ "skipLibCheck": true,
13
+ "esModuleInterop": false,
14
+ "allowSyntheticDefaultImports": true,
15
+ "strict": true,
16
+ "forceConsistentCasingInFileNames": true,
17
+ "module": "ESNext",
18
+ "moduleResolution": "Node",
19
+ "resolveJsonModule": true,
20
+ "isolatedModules": true,
21
+ "importsNotUsedAsValues": "error",
22
+ "noUnusedParameters": true,
23
+ "noEmit": true,
24
+ "noFallthroughCasesInSwitch": true,
25
+ "jsx": "react-jsx",
26
+ "paths": {
27
+ "@/*": [
28
+ "src/*"
29
+ ],
30
+ "~/*": [
31
+ "./*"
32
+ ]
33
+ },
34
+ "types": [
35
+ "vitest/globals"
36
+ ]
37
+ },
38
+ "include": [
39
+ "src"
40
+ ],
41
+ "references": [
42
+ {
43
+ "path": "./tsconfig.node.json"
44
+ }
45
+ ]
46
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "module": "ESNext",
5
+ "moduleResolution": "Node",
6
+ "allowSyntheticDefaultImports": true,
7
+ "resolveJsonModule": true
8
+ },
9
+ "files": [
10
+ "package.json"
11
+ ],
12
+ "include": [
13
+ "vite.config.ts"
14
+ ]
15
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { resolve } from "path";
2
+ import react from "@vitejs/plugin-react";
3
+ import { defineConfig } from "vitest/config";
4
+
5
+ // https://vitejs.dev/config/
6
+ export default defineConfig({
7
+ plugins: [react()],
8
+ resolve: {
9
+ alias: [
10
+ { find: "@", replacement: resolve(__dirname, "src") },
11
+ { find: "~", replacement: resolve(__dirname) },
12
+ ],
13
+ },
14
+ test: {
15
+ environment: "jsdom",
16
+ globals: true,
17
+ setupFiles: "src/test.config.ts",
18
+ },
19
+ });