react like bro view

This commit is contained in:
Primakov Alexandr Alexandrovich 2024-10-17 20:09:08 +03:00
parent 7eb2fb7326
commit cf269ff227
13 changed files with 2705 additions and 56 deletions

7
babel.config.json Normal file
View File

@ -0,0 +1,7 @@
{
"presets": ["@babel/preset-env", "@babel/preset-typescript"],
"plugins": [["@babel/plugin-transform-react-jsx", {
"pragma": "createElement",
"pragmaFrag": "createFragment"
}]]
}

1
dist/bundle.js vendored
View File

@ -1 +0,0 @@
(()=>{"use strict";const e=(e,t,...c)=>{const n=document.createElement(e);for(const e in t){const c=t[e];if("style"===e)for(const e in c)n.style[e]=c[e];else n[e]=c}return n.append(...c),n};document.getElementById("app").append(e("div",{style:{padding:"30px",backgroundColor:"#ccc"}},e("h1",{style:{color:"green"}},"Привет мир"),e("img",{src:"/dist-off/images/1150e57a6c2fd37e2d0c.jpg"})))})();

121
dist/main.bundle.js vendored Normal file
View File

@ -0,0 +1,121 @@
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/bro-view.ts":
/*!*************************!*\
!*** ./src/bro-view.ts ***!
\*************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createElement: () => (/* binding */ createElement),\n/* harmony export */ createFragment: () => (/* binding */ createFragment)\n/* harmony export */ });\nconst createFragment = _ref => {\n let {\n children\n } = _ref;\n return children;\n};\nconst createElement = function (type, props) {\n for (var _len = arguments.length, children = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n children[_key - 2] = arguments[_key];\n }\n if (typeof type === 'function') {\n return type({\n ...props,\n children\n });\n }\n const element = document.createElement(type);\n for (const key in props) {\n const value = props[key];\n if (key === 'style') {\n for (const styleKey in value) {\n element.style[styleKey] = value[styleKey];\n }\n } else {\n element[key] = value;\n }\n }\n const flatChilds = children.reduce((acc, child) => {\n if (Array.isArray(child)) {\n acc.push(...child);\n } else {\n acc.push(child);\n }\n return acc;\n }, []);\n element.append(...flatChilds);\n return element;\n};\n\n//# sourceURL=webpack://webpack-test/./src/bro-view.ts?");
/***/ }),
/***/ "./src/index.tsx":
/*!***********************!*\
!*** ./src/index.tsx ***!
\***********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _bro_view__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bro-view */ \"./src/bro-view.ts\");\n/* harmony import */ var _assets_cat_jpg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./assets/cat.jpg */ \"./src/assets/cat.jpg\");\n/* harmony import */ var _text_txt__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./text.txt */ \"./src/text.txt\");\n/** @jsx createElement */\n/** @jsxFrag createFragment */\n\n\n\nconst app = document.getElementById('app');\nconst Cat = () => (0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(_bro_view__WEBPACK_IMPORTED_MODULE_0__.createFragment, null, (0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"img\", {\n src: _assets_cat_jpg__WEBPACK_IMPORTED_MODULE_1__\n}), (0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"img\", {\n src: _assets_cat_jpg__WEBPACK_IMPORTED_MODULE_1__\n}));\nconst TagName = 'a';\napp.append((0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", {\n style: {\n padding: '30px',\n backgroundColor: '#ccc'\n }\n}, (0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"h1\", {\n style: {\n color: 'green'\n }\n}, _text_txt__WEBPACK_IMPORTED_MODULE_2__), (0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(TagName, {\n href: \"#\"\n}, \"adsasdas\"), (0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(Cat, null), (0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"ul\", null, [(0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"img\", {\n src: _assets_cat_jpg__WEBPACK_IMPORTED_MODULE_1__\n}), (0,_bro_view__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"img\", {\n src: _assets_cat_jpg__WEBPACK_IMPORTED_MODULE_1__\n})])));\n\n// app.append(\n// createElement('div', { style: { padding: '30px', backgroundColor: '#ccc' } },\n// createElement('h1', {\n// style: {\n// color: 'green'\n// }\n// },\n// text\n// ),\n// createElement('img', {\n// src: cat,\n// })\n// )\n// );\n\n//# sourceURL=webpack://webpack-test/./src/index.tsx?");
/***/ }),
/***/ "./src/assets/cat.jpg":
/*!****************************!*\
!*** ./src/assets/cat.jpg ***!
\****************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
eval("module.exports = __webpack_require__.p + \"images/1150e57a6c2fd37e2d0c.jpg\";\n\n//# sourceURL=webpack://webpack-test/./src/assets/cat.jpg?");
/***/ }),
/***/ "./src/text.txt":
/*!**********************!*\
!*** ./src/text.txt ***!
\**********************/
/***/ ((module) => {
eval("module.exports = \"Привет мир\";\n\n//# sourceURL=webpack://webpack-test/./src/text.txt?");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/publicPath */
/******/ (() => {
/******/ __webpack_require__.p = "/dist/";
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/ var __webpack_exports__ = __webpack_require__("./src/index.tsx");
/******/
/******/ })()
;

9
index.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
declare module '*.jpg' {
const path: string;
export default path;
}
declare module '*.txt' {
const path: string;
export default path;
}

View File

@ -7,6 +7,6 @@
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<script src="dist/bundle.js"></script> <script src="dist/main.bundle.js"></script>
</body> </body>
</html> </html>

2358
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,19 @@
"license": "ISC", "license": "ISC",
"description": "", "description": "",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.25.8",
"@babel/preset-env": "^7.25.8",
"@babel/preset-typescript": "^7.25.7",
"babel-loader": "^9.2.1",
"webpack": "^5.95.0", "webpack": "^5.95.0",
"webpack-cli": "^5.1.4" "webpack-cli": "^5.1.4"
},
"dependencies": {
"@babel/plugin-transform-react-jsx": "^7.25.7",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"typescript": "^5.6.3"
} }
} }

View File

@ -1,19 +0,0 @@
export const createElement = (type, props, ...children) => {
const element = document.createElement(type);
for (const key in props) {
const value = props[key];
if (key === 'style') {
for (const styleKey in value) {
element.style[styleKey] = value[styleKey];
}
} else {
element[key] = value;
}
}
element.append(...children);
return element
}

37
src/bro-view.ts Normal file
View File

@ -0,0 +1,37 @@
export const createFragment = ({ children }) => children
export const createElement = <Props extends Record<string, unknown>>
(type: string | ((props: Props) => HTMLElement), props: Props, ...children: HTMLElement[]) => {
if (typeof type === 'function') {
return type({ ...props, children });
}
const element = document.createElement(type);
for (const key in props) {
const value = props[key];
if (key === 'style') {
for (const styleKey in value) {
element.style[styleKey] = value[styleKey];
}
} else {
element[key] = value;
}
}
const flatChilds = children.reduce((acc, child) => {
if (Array.isArray(child)) {
acc.push(...child);
} else {
acc.push(child);
}
return acc;
}, [] as HTMLElement[]);
element.append(...flatChilds);
return element
}

View File

@ -1,21 +0,0 @@
import { createElement as ce } from './bro-view';
import cat from './assets/cat.jpg';
import text from './text.txt'
const app = document.getElementById('app');
app.append(
ce('div', { style: { padding: '30px', backgroundColor: '#ccc' } },
ce('h1', {
style: {
color: 'green'
}
},
text
),
ce('img', {
src: cat,
})
)
);

43
src/index.tsx Normal file
View File

@ -0,0 +1,43 @@
/** @jsx createElement */
/** @jsxFrag createFragment */
import { createElement, createFragment } from './bro-view';
import cat from './assets/cat.jpg';
import text from './text.txt'
const app = document.getElementById('app')!;
const Cat = () => <>
<img src={cat} />
<img src={cat} />
</>
const TagName = 'a'
app.append(
<div style={{ padding: '30px', backgroundColor: '#ccc' }}>
<h1 style={{ color: 'green' }}>{text}</h1>
<TagName href="#">adsasdas</TagName>
<Cat />
<ul>
{[<img src={cat} />,
<img src={cat} />]}
</ul>
</div>
)
// app.append(
// createElement('div', { style: { padding: '30px', backgroundColor: '#ccc' } },
// createElement('h1', {
// style: {
// color: 'green'
// }
// },
// text
// ),
// createElement('img', {
// src: cat,
// })
// )
// );

110
tsconfig.json Normal file
View File

@ -0,0 +1,110 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"jsx": "react", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

View File

@ -1,15 +1,32 @@
const path = require('node:path'); const path = require('node:path');
module.exports = { module.exports = {
entry: './src/index.js', mode: 'development',
entry: './src/index.tsx',
output: { output: {
path: path.resolve(__dirname, 'dist'), path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js', filename: '[name].bundle.js',
publicPath: '/dist/', publicPath: '/dist/',
assetModuleFilename: 'images/[hash][ext][query]' assetModuleFilename: 'images/[hash][ext][query]'
}, },
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx'],
},
module: { module: {
rules: [ rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
targets: "defaults",
presets: [
['@babel/preset-env']
]
}
}
},
{ {
test: /\.(png|svg|jpg|jpeg|gif)$/i, test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource', type: 'asset/resource',