{"id":458705,"date":"2025-05-06T03:02:24","date_gmt":"2025-05-06T03:02:24","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=458705"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=458705","title":{"rendered":"<span>\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 React c \u043d\u0443\u043b\u044f \u0434\u043e \u0434\u0435\u043f\u043b\u043e\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Cursor \u0431\u0435\u0437 \u0441\u0442\u0440\u043e\u0447\u043a\u0438 \u043a\u043e\u0434\u0430<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0421\u0430\u043c\u043e\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 Hello World \u043d\u0430 react &#8212; \u044d\u0442\u043e \u043b\u0438\u0447\u043d\u044b\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0437\u0430\u0434\u0430\u0447 Todolist \u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0441\u0438\u043b\u044c\u043d\u043e \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0438\u0447\u0430\u0442\u044c \u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0435\u0433\u043e \u0441 \u043d\u0443\u043b\u044f \u043d\u0430 react. \u0420\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0438 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u0432 \u044d\u0442\u043e\u043c Cursor AI IDE, \u0430 \u0442\u043e\u0447\u043d\u0435\u0435 <strong>\u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0441\u0435 \u0437\u0430 \u043d\u0430\u0441<\/strong>.<\/p>\n<p>\u0420\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u043c \u0432 \u041e\u0421 Windows 10, \u0443\u043f\u0430\u043a\u0443\u0435\u043c \u0432 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0438 \u043f\u043e\u0441\u043b\u0435 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u043d\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435.<\/p>\n<p>\u0421\u043a\u0430\u0447\u0430\u0435\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c <a href=\"https:\/\/www.cursor.com\/downloads\" rel=\"noopener noreferrer nofollow\">Cursor IDE<\/a>.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/342\/21e\/198\/34221e1984963b5887050e0de8da9aca.png\" width=\"1695\" height=\"950\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/342\/21e\/198\/34221e1984963b5887050e0de8da9aca.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/342\/21e\/198\/34221e1984963b5887050e0de8da9aca.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c Node.js \u043d\u0430 Windows, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043a\u0430\u0447\u0430\u0435\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c <a href=\"https:\/\/nodejs.org\/en\/\" rel=\"noopener noreferrer nofollow\">Node.js LTS<\/a>, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:<\/p>\n<pre><code>node -v<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0440\u043e\u0448\u043b\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f Node.js, \u0442\u0435\u043f\u0435\u0440\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code>npm create vite@latest todolist -- --template react<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 <code>UnauthorizedAccess<\/code> \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u0435\u043a\u0441\u0442<\/summary>\n<div class=\"spoiler__content\">\n<ol>\n<li>\n<p>\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 PowerShell \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0422\u0435\u043a\u0443\u0449\u0443\u044e \u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0443 \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/p>\n<p><code>Get-ExecutionPolicy<\/code><\/p>\n<p>\u0415\u0441\u043b\u0438 \u043e\u043d \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 &#171;\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e&#187;, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0435\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u041d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u0443\u044e<\/p>\n<p><code>Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned<\/code><\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435: \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 cmd<\/p>\n<p><code>enter code here<\/code><\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b<\/p>\n<p>npm create vite@latest todolist &#8212; &#8212;template react<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 <code>npm start<\/code>\u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u044b\u0432\u043e\u0434:<\/p>\n<p>You can now view <strong>todolist<\/strong> in the browser.<\/p>\n<p>Local:            <a href=\"http:\/\/localhost:3000%EF%BF%BC\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:3000<\/a><\/p>\n<p>Note that the development build is not optimized.<br \/>To create a production build, use npm run build.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f2d\/1e1\/0f8\/f2d1e10f8b66627859b18cb60feb3b88.png\" width=\"1920\" height=\"950\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/f2d\/1e1\/0f8\/f2d1e10f8b66627859b18cb60feb3b88.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f2d\/1e1\/0f8\/f2d1e10f8b66627859b18cb60feb3b88.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 react, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 react.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0438 \u043e\u0437\u0430\u0434\u0430\u0447\u0438\u043c \u0447\u0430\u0442, \u043d\u0430\u043f\u0438\u0441\u0430\u0432 \u0435\u043c\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/92a\/533\/cd3\/92a533cd31d67da27fe01d1b51850085.png\" width=\"394\" height=\"155\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/92a\/533\/cd3\/92a533cd31d67da27fe01d1b51850085.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/92a\/533\/cd3\/92a533cd31d67da27fe01d1b51850085.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u043a\u0443\u0447\u0443 \u043e\u0448\u0438\u0431\u043e\u043a<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u0435\u043a\u0441\u0442<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">ERROR in src\/App.tsx:1:33 TS7016: Could not find a declaration file for module 'react'. 'C:\/\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\/todolist\/node_modules\/react\/index.js' implicitly has an 'any' type.   Try `npm i --save-dev @types\/react` if it exists or add a new declaration (.d.ts) file containing `declare module 'react';`   &gt; 1 | import React, { useState } from 'react';       |                                 ^^^^^^^     2 | import '.\/App.css';     3 |     4 | interface Todo { ERROR in src\/App.tsx:31:24 TS7006: Parameter 'todo' implicitly has an 'any' type.     29 |     30 |   const handleToggleTodo = (id: number) =&gt; {   &gt; 31 |     setTodos(todos.map(todo =&gt;        |                        ^^^^     32 |       todo.id === id ? { ...todo, completed: !todo.completed } : todo     33 |     ));     34 |   }; ERROR in src\/App.tsx:37:27 TS7006: Parameter 'todo' implicitly has an 'any' type.     35 |     36 |   const handleDeleteTodo = (id: number) =&gt; {   &gt; 37 |     setTodos(todos.filter(todo =&gt; todo.id !== id));        |                           ^^^^     38 |   };     39 |     40 |   const filteredTodos = todos.filter(todo =&gt; { ERROR in src\/App.tsx:40:38 TS7006: Parameter 'todo' implicitly has an 'any' type.     38 |   };     39 |   &gt; 40 |   const filteredTodos = todos.filter(todo =&gt; {        |                                      ^^^^     41 |     if (filter === 'active') return !todo.completed;     42 |     if (filter === 'completed') return todo.completed;     43 |     return true; ERROR in src\/App.tsx:46:39 TS7006: Parameter 'todo' implicitly has an 'any' type.     44 |   });     45 |   &gt; 46 |   const remainingTasks = todos.filter(todo =&gt; !todo.completed).length;        |                                       ^^^^     47 |     48 |   return (     49 |     &lt;div className=\"App\"&gt; ERROR in src\/App.tsx:49:5 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     47 |     48 |   return (   &gt; 49 |     &lt;div className=\"App\"&gt;        |     ^^^^^^^^^^^^^^^^^^^^^     50 |       &lt;div className=\"container\"&gt;     51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;     52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt; ERROR in src\/App.tsx:49:5 TS7016: Could not find a declaration file for module 'react\/jsx-runtime'. 'C:\/\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\/todolist\/node_modules\/react\/jsx-runtime.js' implicitly has an 'any' type.   Try `npm i --save-dev @types\/react` if it exists or add a new declaration (.d.ts) file containing `declare module 'react\/jsx-runtime';`      47 |      48 |   return (   &gt;  49 |     &lt;div className=\"App\"&gt;         |     ^^^^^^^^^^^^^^^^^^^^^   &gt;  50 |       &lt;div className=\"container\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  53 |           &lt;input         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  54 |             type=\"text\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  55 |             value={inputValue}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  56 |             onChange={(e) =&gt; setInputValue(e.target.value)}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  57 |             placeholder=\"Add a new task...\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  58 |             className=\"todo-input\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  59 |           \/&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  60 |           &lt;button type=\"submit\" className=\"add-button\"&gt;Add&lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  61 |         &lt;\/form&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  62 |                  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  63 |         &lt;div className=\"filters\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  64 |           &lt;button         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  65 |             className={`filter-button ${filter === 'all' ? 'active' : ''}`}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  66 |             onClick={() =&gt; setFilter('all')}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  67 |           &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  68 |             All         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  69 |           &lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  70 |           &lt;button         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  71 |             className={`filter-button ${filter === 'active' ? 'active' : ''}`}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  72 |             onClick={() =&gt; setFilter('active')}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  73 |           &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  74 |             Active         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  75 |           &lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  76 |           &lt;button         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  77 |             className={`filter-button ${filter === 'completed' ? 'active' : ''}`}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  78 |             onClick={() =&gt; setFilter('completed')}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  79 |           &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  80 |             Completed         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  81 |           &lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  82 |         &lt;\/div&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  83 |         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  84 |         &lt;div className=\"todo-stats\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  85 |           {remainingTasks} {remainingTasks === 1 ? 'task' : 'tasks'} remaining         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  86 |         &lt;\/div&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  87 |         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  88 |         &lt;ul className=\"todo-list\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  89 |           {filteredTodos.map(todo =&gt; (         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  90 |             &lt;li key={todo.id} className={`todo-item ${todo.completed ? 'completed' : ''}`}&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  91 |               &lt;span         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  92 |                 onClick={() =&gt; handleToggleTodo(todo.id)}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  93 |                 className=\"todo-text\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  94 |               &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  95 |                 {todo.text}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  96 |               &lt;\/span&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  97 |               &lt;button         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  98 |                 onClick={() =&gt; handleDeleteTodo(todo.id)}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  99 |                 className=\"delete-button\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 100 |               &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 101 |                 Delete         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 102 |               &lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 103 |             &lt;\/li&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 104 |           ))}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 105 |         &lt;\/ul&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 106 |       &lt;\/div&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 107 |     &lt;\/div&gt;         | ^^^^^^^^^^^     108 |   );     109 | }     110 | ERROR in src\/App.tsx:50:7 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     48 |   return (     49 |     &lt;div className=\"App\"&gt;   &gt; 50 |       &lt;div className=\"container\"&gt;        |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^     51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;     52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt;     53 |           &lt;input ERROR in src\/App.tsx:51:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     49 |     &lt;div className=\"App\"&gt;     50 |       &lt;div className=\"container\"&gt;   &gt; 51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;        |         ^^^^     52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt;     53 |           &lt;input     54 |             type=\"text\" ERROR in src\/App.tsx:51:22 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     49 |     &lt;div className=\"App\"&gt;     50 |       &lt;div className=\"container\"&gt;   &gt; 51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;        |                      ^^^^^     52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt;     53 |           &lt;input     54 |             type=\"text\" ERROR in src\/App.tsx:52:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     50 |       &lt;div className=\"container\"&gt;     51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;   &gt; 52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt;        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     53 |           &lt;input     54 |             type=\"text\"     55 |             value={inputValue} ERROR in src\/App.tsx:53:11 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;     52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt;   &gt; 53 |           &lt;input        |           ^^^^^^   &gt; 54 |             type=\"text\"        | ^^^^^^^^^^^^^^^^^^^^^^^   &gt; 55 |             value={inputValue}        | ^^^^^^^^^^^^^^^^^^^^^^^   &gt; 56 |             onChange={(e) =&gt; setInputValue(e.target.value)}        | ^^^^^^^^^^^^^^^^^^^^^^^   &gt; 57 |             placeholder=\"Add a new task...\"        | ^^^^^^^^^^^^^^^^^^^^^^^   &gt; 58 |             className=\"todo-input\"        | ^^^^^^^^^^^^^^^^^^^^^^^   &gt; 59 |           \/&gt;        | ^^^^^^^^^^^^^     60 |           &lt;button type=\"submit\" className=\"add-button\"&gt;Add&lt;\/button&gt;     61 |         &lt;\/form&gt;     62 |          ERROR in src\/App.tsx:56:24 TS7006: Parameter 'e' implicitly has an 'any' type.     54 |             type=\"text\"     55 |             value={inputValue}   &gt; 56 |             onChange={(e) =&gt; setInputValue(e.target.value)}        |                        ^     57 |             placeholder=\"Add a new task...\"     58 |             className=\"todo-input\"     59 |           \/&gt; ERROR in src\/App.tsx:60:11 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     58 |             className=\"todo-input\"     59 |           \/&gt;   &gt; 60 |           &lt;button type=\"submit\" className=\"add-button\"&gt;Add&lt;\/button&gt;        |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     61 |         &lt;\/form&gt;     62 |              63 |         &lt;div className=\"filters\"&gt; ERROR in src\/App.tsx:60:59 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     58 |             className=\"todo-input\"     59 |           \/&gt;   &gt; 60 |           &lt;button type=\"submit\" className=\"add-button\"&gt;Add&lt;\/button&gt;        |                                                           ^^^^^^^^^     61 |         &lt;\/form&gt;     62 |              63 |         &lt;div className=\"filters\"&gt; ERROR in src\/App.tsx:61:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     59 |           \/&gt;     60 |           &lt;button type=\"submit\" className=\"add-button\"&gt;Add&lt;\/button&gt;   &gt; 61 |         &lt;\/form&gt;        |         ^^^^^^^     62 |              63 |         &lt;div className=\"filters\"&gt;     64 |           &lt;button ERROR in src\/App.tsx:63:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     61 |         &lt;\/form&gt;     62 |            &gt; 63 |         &lt;div className=\"filters\"&gt;        |         ^^^^^^^^^^^^^^^^^^^^^^^^^     64 |           &lt;button     65 |             className={`filter-button ${filter === 'all' ? 'active' : ''}`}     66 |             onClick={() =&gt; setFilter('all')} ERROR in src\/App.tsx:64:11 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     62 |              63 |         &lt;div className=\"filters\"&gt;   &gt; 64 |           &lt;button        |           ^^^^^^^   &gt; 65 |             className={`filter-button ${filter === 'all' ? 'active' : ''}`}        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 66 |             onClick={() =&gt; setFilter('all')}        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 67 |           &gt;        | ^^^^^^^^^^^^     68 |             All     69 |           &lt;\/button&gt;     70 |           &lt;button ERROR in src\/App.tsx:69:11 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     67 |           &gt;     68 |             All   &gt; 69 |           &lt;\/button&gt;        |           ^^^^^^^^^     70 |           &lt;button     71 |             className={`filter-button ${filter === 'active' ? 'active' : ''}`}     72 |             onClick={() =&gt; setFilter('active')} ERROR in src\/App.tsx:70:11 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     68 |             All     69 |           &lt;\/button&gt;   &gt; 70 |           &lt;button        |           ^^^^^^^   &gt; 71 |             className={`filter-button ${filter === 'active' ? 'active' : ''}`}        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 72 |             onClick={() =&gt; setFilter('active')}        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 73 |           &gt;        | ^^^^^^^^^^^^     74 |             Active     75 |           &lt;\/button&gt;     76 |           &lt;button ERROR in src\/App.tsx:75:11 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     73 |           &gt;     74 |             Active   &gt; 75 |           &lt;\/button&gt;        |           ^^^^^^^^^     76 |           &lt;button     77 |             className={`filter-button ${filter === 'completed' ? 'active' : ''}`}     78 |             onClick={() =&gt; setFilter('completed')} ERROR in src\/App.tsx:76:11 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     74 |             Active     75 |           &lt;\/button&gt;   &gt; 76 |           &lt;button        |           ^^^^^^^   &gt; 77 |             className={`filter-button ${filter === 'completed' ? 'active' : ''}`}        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 78 |             onClick={() =&gt; setFilter('completed')}        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 79 |           &gt;        | ^^^^^^^^^^^^     80 |             Completed     81 |           &lt;\/button&gt;     82 |         &lt;\/div&gt; ERROR in src\/App.tsx:81:11 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     79 |           &gt;     80 |             Completed   &gt; 81 |           &lt;\/button&gt;        |           ^^^^^^^^^     82 |         &lt;\/div&gt;     83 |     84 |         &lt;div className=\"todo-stats\"&gt; ERROR in src\/App.tsx:82:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     80 |             Completed     81 |           &lt;\/button&gt;   &gt; 82 |         &lt;\/div&gt;        |         ^^^^^^     83 |     84 |         &lt;div className=\"todo-stats\"&gt;     85 |           {remainingTasks} {remainingTasks === 1 ? 'task' : 'tasks'} remaining ERROR in src\/App.tsx:84:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     82 |         &lt;\/div&gt;     83 |   &gt; 84 |         &lt;div className=\"todo-stats\"&gt;        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^     85 |           {remainingTasks} {remainingTasks === 1 ? 'task' : 'tasks'} remaining     86 |         &lt;\/div&gt;     87 | ERROR in src\/App.tsx:86:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     84 |         &lt;div className=\"todo-stats\"&gt;     85 |           {remainingTasks} {remainingTasks === 1 ? 'task' : 'tasks'} remaining   &gt; 86 |         &lt;\/div&gt;        |         ^^^^^^     87 |     88 |         &lt;ul className=\"todo-list\"&gt;     89 |           {filteredTodos.map(todo =&gt; ( ERROR in src\/App.tsx:88:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     86 |         &lt;\/div&gt;     87 |   &gt; 88 |         &lt;ul className=\"todo-list\"&gt;        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^     89 |           {filteredTodos.map(todo =&gt; (     90 |             &lt;li key={todo.id} className={`todo-item ${todo.completed ? 'completed' : ''}`}&gt;     91 |               &lt;span ERROR in src\/App.tsx:89:30 TS7006: Parameter 'todo' implicitly has an 'any' type.     87 |     88 |         &lt;ul className=\"todo-list\"&gt;   &gt; 89 |           {filteredTodos.map(todo =&gt; (        |                              ^^^^     90 |             &lt;li key={todo.id} className={`todo-item ${todo.completed ? 'completed' : ''}`}&gt;     91 |               &lt;span     92 |                 onClick={() =&gt; handleToggleTodo(todo.id)} ERROR in src\/App.tsx:90:13 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     88 |         &lt;ul className=\"todo-list\"&gt;     89 |           {filteredTodos.map(todo =&gt; (   &gt; 90 |             &lt;li key={todo.id} className={`todo-item ${todo.completed ? 'completed' : ''}`}&gt;        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     91 |               &lt;span     92 |                 onClick={() =&gt; handleToggleTodo(todo.id)}     93 |                 className=\"todo-text\" ERROR in src\/App.tsx:91:15 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     89 |           {filteredTodos.map(todo =&gt; (     90 |             &lt;li key={todo.id} className={`todo-item ${todo.completed ? 'completed' : ''}`}&gt;   &gt; 91 |               &lt;span        |               ^^^^^   &gt; 92 |                 onClick={() =&gt; handleToggleTodo(todo.id)}        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 93 |                 className=\"todo-text\"        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 94 |               &gt;        | ^^^^^^^^^^^^^^^^     95 |                 {todo.text}     96 |               &lt;\/span&gt;     97 |               &lt;button ERROR in src\/App.tsx:96:15 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     94 |               &gt;     95 |                 {todo.text}   &gt; 96 |               &lt;\/span&gt;        |               ^^^^^^^     97 |               &lt;button     98 |                 onClick={() =&gt; handleDeleteTodo(todo.id)}     99 |                 className=\"delete-button\" ERROR in src\/App.tsx:97:15 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.      95 |                 {todo.text}      96 |               &lt;\/span&gt;   &gt;  97 |               &lt;button         |               ^^^^^^^   &gt;  98 |                 onClick={() =&gt; handleDeleteTodo(todo.id)}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  99 |                 className=\"delete-button\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 100 |               &gt;         | ^^^^^^^^^^^^^^^^     101 |                 Delete     102 |               &lt;\/button&gt;     103 |             &lt;\/li&gt; ERROR in src\/App.tsx:102:15 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     100 |               &gt;     101 |                 Delete   &gt; 102 |               &lt;\/button&gt;         |               ^^^^^^^^^     103 |             &lt;\/li&gt;     104 |           ))}     105 |         &lt;\/ul&gt; ERROR in src\/App.tsx:103:13 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     101 |                 Delete     102 |               &lt;\/button&gt;   &gt; 103 |             &lt;\/li&gt;         |             ^^^^^     104 |           ))}     105 |         &lt;\/ul&gt;     106 |       &lt;\/div&gt; ERROR in src\/App.tsx:105:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     103 |             &lt;\/li&gt;     104 |           ))}   &gt; 105 |         &lt;\/ul&gt;         |         ^^^^^     106 |       &lt;\/div&gt;     107 |     &lt;\/div&gt;     108 |   ); ERROR in src\/App.tsx:106:7 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     104 |           ))}     105 |         &lt;\/ul&gt;   &gt; 106 |       &lt;\/div&gt;         |       ^^^^^^     107 |     &lt;\/div&gt;     108 |   );     109 | } ERROR in src\/App.tsx:107:5 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     105 |         &lt;\/ul&gt;     106 |       &lt;\/div&gt;   &gt; 107 |     &lt;\/div&gt;         |     ^^^^^^     108 |   );     109 | }     110 | ERROR in src\/index.tsx:1:19 TS7016: Could not find a declaration file for module 'react'. 'C:\/\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\/todolist\/node_modules\/react\/index.js' implicitly has an 'any' type.   Try `npm i --save-dev @types\/react` if it exists or add a new declaration (.d.ts) file containing `declare module 'react';`   &gt; 1 | import React from 'react';       |                   ^^^^^^^     2 | import ReactDOM from 'react-dom\/client';     3 | import '.\/index.css';     4 | import App from '.\/App'; ERROR in src\/index.tsx:2:22 TS7016: Could not find a declaration file for module 'react-dom\/client'. 'C:\/\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\/todolist\/node_modules\/react-dom\/client.js' implicitly has an 'any' type.   Try `npm i --save-dev @types\/react-dom` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-dom\/client';`     1 | import React from 'react';   &gt; 2 | import ReactDOM from 'react-dom\/client';       |                      ^^^^^^^^^^^^^^^^^^     3 | import '.\/index.css';     4 | import App from '.\/App';     5 | ERROR in src\/index.tsx:11:3 TS7016: Could not find a declaration file for module 'react\/jsx-runtime'. 'C:\/\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\/todolist\/node_modules\/react\/jsx-runtime.js' implicitly has an 'any' type.   Try `npm i --save-dev @types\/react` if it exists or add a new declaration (.d.ts) file containing `declare module 'react\/jsx-runtime';`      9 |     10 | root.render(   &gt; 11 |   &lt;React.StrictMode&gt;        |   ^^^^^^^^^^^^^^^^^^   &gt; 12 |     &lt;App \/&gt;        | ^^^^^^^^^^^   &gt; 13 |   &lt;\/React.StrictMode&gt;        | ^^^^^^^^^^^^^^^^^^^^^^     14 | ); <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041d\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b \u043d\u0438\u0447\u0435\u0433\u043e \u043b\u0443\u0447\u0448\u0435, \u043a\u0430\u043a \u0441\u043a\u043e\u0440\u043c\u0438\u0442\u044c \u0438\u0445 \u0432\u0441\u0435 \u0432 \u0447\u0430\u0442 Cursor<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/737\/b55\/e65\/737b55e6571e7a2774e5b8d95f4c1c0d.png\" width=\"1920\" height=\"1050\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/737\/b55\/e65\/737b55e6571e7a2774e5b8d95f4c1c0d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/737\/b55\/e65\/737b55e6571e7a2774e5b8d95f4c1c0d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0438 \u043d\u0435 \u043f\u043e\u0432\u0435\u0440\u0438\u0442\u0435 \u043e\u043d \u0432\u0441\u0435 \u0442\u0443\u0442 \u0436\u0435 \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043b, \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043e\u0442\u043a\u0440\u044b\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a4d\/829\/2f2\/a4d8292f212d66571ec859233323ae7a.png\" width=\"1920\" height=\"950\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/a4d\/829\/2f2\/a4d8292f212d66571ec859233323ae7a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a4d\/829\/2f2\/a4d8292f212d66571ec859233323ae7a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0438 \u043e\u0442\u0447\u0438\u0442\u0430\u043b\u0441\u044f, \u0447\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/580\/96b\/d0d\/58096bd0d43aad4a1c5166438d1fecf6.png\" width=\"636\" height=\"320\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/580\/96b\/d0d\/58096bd0d43aad4a1c5166438d1fecf6.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/580\/96b\/d0d\/58096bd0d43aad4a1c5166438d1fecf6.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0430\u0442\u044c \u0438 \u0434\u043e\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c, \u0434\u0430\u0432\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0418\u0418, \u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e. \u041e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u0438 \u043e\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043b\u043e\u0441\u044c.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u044b \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043b\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443, \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c docker \u043d\u0430 \u043f\u0440\u043e\u0434\u0430\u043a\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b91\/979\/2b7\/b919792b787fcba54edb4a075a726967.png\" width=\"1920\" height=\"1050\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/b91\/979\/2b7\/b919792b787fcba54edb4a075a726967.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b91\/979\/2b7\/b919792b787fcba54edb4a075a726967.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u043e\u043f\u0440\u043e\u0441\u0438\u043c \u0447\u0430\u0442 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c dockerfile \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0434\u043e\u043a\u0435\u0440 \u043e\u0431\u0440\u0430\u0437\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u043a\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 \u043e\u0434\u0438\u043d \u043a\u043b\u0438\u043a.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u0435\u043a\u0441\u0442<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\"># Build stage FROM node:18-alpine as build  WORKDIR \/app  # Copy package files COPY package*.json .\/  # Install dependencies RUN npm ci  # Copy source code COPY . .  # Build the application RUN npm run build  # Production stage FROM nginx:alpine  # Copy nginx configuration COPY nginx.conf \/etc\/nginx\/conf.d\/default.conf  # Copy built files from build stage COPY --from=build \/app\/build \/usr\/share\/nginx\/html  # Expose port 80 EXPOSE 80  # Start nginx CMD [\"nginx\", \"-g\", \"daemon off;\"] <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0418\u0418 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b dockerfile \u0438 \u043a\u043e\u043d\u0444\u0438\u0433 nginx.conf, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 GitHub, \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0445\u043e\u0441\u0442\u0438\u043d\u0433, \u0441\u0431\u0438\u043b\u0434\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0437 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c. \u0417\u0432\u0443\u0447\u0438\u0442 \u0441\u043b\u043e\u0436\u043d\u043e, \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e.<\/p>\n<p>\u041d\u0435 \u0431\u0443\u0434\u0443 \u0437\u0430\u043e\u0441\u0442\u0440\u044f\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043a\u0430\u043a \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 github, \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u043d\u043e\u0433\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u0438 \u0432\u0441\u0435 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 git \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0432 Cursor<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ec4\/b50\/001\/ec4b500012bbdbb864247c59181e5412.png\" width=\"1920\" height=\"1050\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/ec4\/b50\/001\/ec4b500012bbdbb864247c59181e5412.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ec4\/b50\/001\/ec4b500012bbdbb864247c59181e5412.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0417\u0430\u043f\u0443\u0448\u0438\u043c \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 <a href=\"https:\/\/github.com\/aleksandrvolk\/todo\" rel=\"noopener noreferrer nofollow\">Github<\/a>.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/913\/56f\/b4d\/91356fb4d8f5ad51e6e402bdb40d8a49.png\" width=\"1904\" height=\"950\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/913\/56f\/b4d\/91356fb4d8f5ad51e6e402bdb40d8a49.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/913\/56f\/b4d\/91356fb4d8f5ad51e6e402bdb40d8a49.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440, \u0434\u043b\u044f \u043f\u0440\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0437\u0430 1 \u0440\u0443\u0431\u043b\u044c \u0432 <a href=\"https:\/\/dockerhosting.ru\/\" rel=\"noopener noreferrer nofollow\">dockerhosting.ru<\/a>, \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0435 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d docker \u0438 portainer.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/40d\/00c\/9d0\/40d00c9d06a00d3bcc471ce357755e11.png\" width=\"1920\" height=\"950\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/40d\/00c\/9d0\/40d00c9d06a00d3bcc471ce357755e11.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/40d\/00c\/9d0\/40d00c9d06a00d3bcc471ce357755e11.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/938\/d25\/c77\/938d25c775805e77dffcd75a79ad3216.png\" width=\"1920\" height=\"950\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/938\/d25\/c77\/938d25c775805e77dffcd75a79ad3216.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/938\/d25\/c77\/938d25c775805e77dffcd75a79ad3216.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0441\u0431\u043e\u0440\u043a\u0443 \u043e\u0431\u0440\u0430\u0437\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u0421\u0431\u043e\u0440\u043a\u0443 \u043e\u0431\u0440\u0430\u0437\u0430 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0432 portainer<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c17\/434\/430\/c17434430ed93c29e9585d6cac189b27.png\" width=\"1662\" height=\"465\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/c17\/434\/430\/c17434430ed93c29e9585d6cac189b27.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c17\/434\/430\/c17434430ed93c29e9585d6cac189b27.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 portainer \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b <strong>images<\/strong> \u0438 \u043a\u043b\u0438\u043a\u043d\u0435\u043c <strong>Build a new image<\/strong><\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d47\/5ff\/61e\/d475ff61e2972bb4cd3f03a2023f6609.png\" width=\"1920\" height=\"792\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/d47\/5ff\/61e\/d475ff61e2972bb4cd3f03a2023f6609.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d47\/5ff\/61e\/d475ff61e2972bb4cd3f03a2023f6609.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0423\u043a\u0430\u0436\u0435\u043c \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 todolist \u0438 \u043f\u0443\u0442\u044c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044e <a href=\"https:\/\/github.com\/aleksandrvolk\/todo\" rel=\"noopener noreferrer nofollow\">Github<\/a>.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b5d\/ebc\/394\/b5debc394ca5941fb33e2a0188cbe59c.png\" width=\"1619\" height=\"950\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/b5d\/ebc\/394\/b5debc394ca5941fb33e2a0188cbe59c.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b5d\/ebc\/394\/b5debc394ca5941fb33e2a0188cbe59c.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041a\u043b\u0438\u043a\u0430\u0435\u043c <strong>Build the image<\/strong> \u0438 \u0436\u0434\u0435\u043c, \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/030\/8c2\/0a5\/0308c20a5746837c1afdf093f9f91639.png\" width=\"1920\" height=\"950\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/030\/8c2\/0a5\/0308c20a5746837c1afdf093f9f91639.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/030\/8c2\/0a5\/0308c20a5746837c1afdf093f9f91639.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u0430\u043b \u043d\u0430\u0448 \u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a, \u0432\u043e\u0439\u0434\u0435\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e ssh, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"bash\">docker run -p 80:80 todolist<\/code><\/pre>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6d5\/994\/5f8\/6d59945f8332d71d9aa399f670d7dc11.png\" width=\"609\" height=\"1050\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/6d5\/994\/5f8\/6d59945f8332d71d9aa399f670d7dc11.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6d5\/994\/5f8\/6d59945f8332d71d9aa399f670d7dc11.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0437\u0430\u043f\u0443\u0449\u0435\u043d:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cf7\/5d7\/0cb\/cf75d70cb7122ba900db25baf144100e.png\" width=\"1245\" height=\"667\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/cf7\/5d7\/0cb\/cf75d70cb7122ba900db25baf144100e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cf7\/5d7\/0cb\/cf75d70cb7122ba900db25baf144100e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0432 portainer, \u0447\u0442\u043e \u043d\u0430\u0448 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c02\/b70\/b71\/c02b70b71df2d91c9685119140841cd1.png\" width=\"1920\" height=\"950\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/c02\/b70\/b71\/c02b70b71df2d91c9685119140841cd1.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c02\/b70\/b71\/c02b70b71df2d91c9685119140841cd1.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e IP \u0430\u0434\u0440\u0435\u0441\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/256\/165\/472\/25616547216c49d4b8883c5e30fac27a.png\" width=\"1089\" height=\"403\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/256\/165\/472\/25616547216c49d4b8883c5e30fac27a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/256\/165\/472\/25616547216c49d4b8883c5e30fac27a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0438 \u0440\u0430\u0437\u0443 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044f \u0441 react. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043c\u043e\u0433\u0443 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c &#171;\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f&#187;, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0432 \u0431\u044d\u043a \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0443\u0442 \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u043c\u043e\u0439 <a href=\"https:\/\/t.me\/aleksandr1c\" rel=\"noopener noreferrer nofollow\">\u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/905736\/\"> https:\/\/habr.com\/ru\/articles\/905736\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0421\u0430\u043c\u043e\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 Hello World \u043d\u0430 react &#8212; \u044d\u0442\u043e \u043b\u0438\u0447\u043d\u044b\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0437\u0430\u0434\u0430\u0447 Todolist \u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0441\u0438\u043b\u044c\u043d\u043e \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0438\u0447\u0430\u0442\u044c \u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0435\u0433\u043e \u0441 \u043d\u0443\u043b\u044f \u043d\u0430 react. \u0420\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0438 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u0432 \u044d\u0442\u043e\u043c Cursor AI IDE, \u0430 \u0442\u043e\u0447\u043d\u0435\u0435 <strong>\u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0441\u0435 \u0437\u0430 \u043d\u0430\u0441<\/strong>.<\/p>\n<p>\u0420\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u043c \u0432 \u041e\u0421 Windows 10, \u0443\u043f\u0430\u043a\u0443\u0435\u043c \u0432 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0438 \u043f\u043e\u0441\u043b\u0435 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u043d\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435.<\/p>\n<p>\u0421\u043a\u0430\u0447\u0430\u0435\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c <a href=\"https:\/\/www.cursor.com\/downloads\" rel=\"noopener noreferrer nofollow\">Cursor IDE<\/a>.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c Node.js \u043d\u0430 Windows, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043a\u0430\u0447\u0430\u0435\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c <a href=\"https:\/\/nodejs.org\/en\/\" rel=\"noopener noreferrer nofollow\">Node.js LTS<\/a>, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:<\/p>\n<pre><code>node -v<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0440\u043e\u0448\u043b\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f Node.js, \u0442\u0435\u043f\u0435\u0440\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code>npm create vite@latest todolist -- --template react<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 <code>UnauthorizedAccess<\/code> \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u0435\u043a\u0441\u0442<\/summary>\n<div class=\"spoiler__content\">\n<ol>\n<li>\n<p>\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 PowerShell \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0422\u0435\u043a\u0443\u0449\u0443\u044e \u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0443 \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/p>\n<p><code>Get-ExecutionPolicy<\/code><\/p>\n<p>\u0415\u0441\u043b\u0438 \u043e\u043d \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 &#171;\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e&#187;, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0435\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u041d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u0443\u044e<\/p>\n<p><code>Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned<\/code><\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435: \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 cmd<\/p>\n<p><code>enter code here<\/code><\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b<\/p>\n<p>npm create vite@latest todolist &#8212; &#8212;template react<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 <code>npm start<\/code>\u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u044b\u0432\u043e\u0434:<\/p>\n<p>You can now view <strong>todolist<\/strong> in the browser.<\/p>\n<p>Local:            <a href=\"http:\/\/localhost:3000%EF%BF%BC\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:3000<\/a><\/p>\n<p>Note that the development build is not optimized.<br \/>To create a production build, use npm run build.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 react, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 react.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0438 \u043e\u0437\u0430\u0434\u0430\u0447\u0438\u043c \u0447\u0430\u0442, \u043d\u0430\u043f\u0438\u0441\u0430\u0432 \u0435\u043c\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<figure class=\"\"><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u043a\u0443\u0447\u0443 \u043e\u0448\u0438\u0431\u043e\u043a<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u0435\u043a\u0441\u0442<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">ERROR in src\/App.tsx:1:33 TS7016: Could not find a declaration file for module 'react'. 'C:\/\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\/todolist\/node_modules\/react\/index.js' implicitly has an 'any' type.   Try `npm i --save-dev @types\/react` if it exists or add a new declaration (.d.ts) file containing `declare module 'react';`   &gt; 1 | import React, { useState } from 'react';       |                                 ^^^^^^^     2 | import '.\/App.css';     3 |     4 | interface Todo { ERROR in src\/App.tsx:31:24 TS7006: Parameter 'todo' implicitly has an 'any' type.     29 |     30 |   const handleToggleTodo = (id: number) =&gt; {   &gt; 31 |     setTodos(todos.map(todo =&gt;        |                        ^^^^     32 |       todo.id === id ? { ...todo, completed: !todo.completed } : todo     33 |     ));     34 |   }; ERROR in src\/App.tsx:37:27 TS7006: Parameter 'todo' implicitly has an 'any' type.     35 |     36 |   const handleDeleteTodo = (id: number) =&gt; {   &gt; 37 |     setTodos(todos.filter(todo =&gt; todo.id !== id));        |                           ^^^^     38 |   };     39 |     40 |   const filteredTodos = todos.filter(todo =&gt; { ERROR in src\/App.tsx:40:38 TS7006: Parameter 'todo' implicitly has an 'any' type.     38 |   };     39 |   &gt; 40 |   const filteredTodos = todos.filter(todo =&gt; {        |                                      ^^^^     41 |     if (filter === 'active') return !todo.completed;     42 |     if (filter === 'completed') return todo.completed;     43 |     return true; ERROR in src\/App.tsx:46:39 TS7006: Parameter 'todo' implicitly has an 'any' type.     44 |   });     45 |   &gt; 46 |   const remainingTasks = todos.filter(todo =&gt; !todo.completed).length;        |                                       ^^^^     47 |     48 |   return (     49 |     &lt;div className=\"App\"&gt; ERROR in src\/App.tsx:49:5 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     47 |     48 |   return (   &gt; 49 |     &lt;div className=\"App\"&gt;        |     ^^^^^^^^^^^^^^^^^^^^^     50 |       &lt;div className=\"container\"&gt;     51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;     52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt; ERROR in src\/App.tsx:49:5 TS7016: Could not find a declaration file for module 'react\/jsx-runtime'. 'C:\/\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\/todolist\/node_modules\/react\/jsx-runtime.js' implicitly has an 'any' type.   Try `npm i --save-dev @types\/react` if it exists or add a new declaration (.d.ts) file containing `declare module 'react\/jsx-runtime';`      47 |      48 |   return (   &gt;  49 |     &lt;div className=\"App\"&gt;         |     ^^^^^^^^^^^^^^^^^^^^^   &gt;  50 |       &lt;div className=\"container\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  53 |           &lt;input         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  54 |             type=\"text\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  55 |             value={inputValue}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  56 |             onChange={(e) =&gt; setInputValue(e.target.value)}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  57 |             placeholder=\"Add a new task...\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  58 |             className=\"todo-input\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  59 |           \/&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  60 |           &lt;button type=\"submit\" className=\"add-button\"&gt;Add&lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  61 |         &lt;\/form&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  62 |                  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  63 |         &lt;div className=\"filters\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  64 |           &lt;button         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  65 |             className={`filter-button ${filter === 'all' ? 'active' : ''}`}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  66 |             onClick={() =&gt; setFilter('all')}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  67 |           &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  68 |             All         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  69 |           &lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  70 |           &lt;button         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  71 |             className={`filter-button ${filter === 'active' ? 'active' : ''}`}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  72 |             onClick={() =&gt; setFilter('active')}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  73 |           &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  74 |             Active         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  75 |           &lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  76 |           &lt;button         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  77 |             className={`filter-button ${filter === 'completed' ? 'active' : ''}`}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  78 |             onClick={() =&gt; setFilter('completed')}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  79 |           &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  80 |             Completed         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  81 |           &lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  82 |         &lt;\/div&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  83 |         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  84 |         &lt;div className=\"todo-stats\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  85 |           {remainingTasks} {remainingTasks === 1 ? 'task' : 'tasks'} remaining         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  86 |         &lt;\/div&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  87 |         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  88 |         &lt;ul className=\"todo-list\"&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  89 |           {filteredTodos.map(todo =&gt; (         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  90 |             &lt;li key={todo.id} className={`todo-item ${todo.completed ? 'completed' : ''}`}&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  91 |               &lt;span         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  92 |                 onClick={() =&gt; handleToggleTodo(todo.id)}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  93 |                 className=\"todo-text\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  94 |               &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  95 |                 {todo.text}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  96 |               &lt;\/span&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  97 |               &lt;button         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  98 |                 onClick={() =&gt; handleDeleteTodo(todo.id)}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt;  99 |                 className=\"delete-button\"         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 100 |               &gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 101 |                 Delete         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 102 |               &lt;\/button&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 103 |             &lt;\/li&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 104 |           ))}         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 105 |         &lt;\/ul&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 106 |       &lt;\/div&gt;         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   &gt; 107 |     &lt;\/div&gt;         | ^^^^^^^^^^^     108 |   );     109 | }     110 | ERROR in src\/App.tsx:50:7 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     48 |   return (     49 |     &lt;div className=\"App\"&gt;   &gt; 50 |       &lt;div className=\"container\"&gt;        |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^     51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;     52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt;     53 |           &lt;input ERROR in src\/App.tsx:51:9 TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.     49 |     &lt;div className=\"App\"&gt;     50 |       &lt;div className=\"container\"&gt;   &gt; 51 |         &lt;h1&gt;Todo List&lt;\/h1&gt;        |         ^^^^     52 |         &lt;form onSubmit={handleAddTodo} className=\"todo-form\"&gt;     53 |           &lt;input     54 |             type=\"text\"<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-458705","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/458705","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=458705"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/458705\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=458705"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=458705"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=458705"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}