Enhance project structure and styling for landing page. Add detailed file structure documentation in cloud.md. Update webpack configuration to support CSS Modules and SCSS. Introduce new styles for terms page and integrate them into the build process. Update package.json and package-lock.json with new dependencies for improved styling capabilities.
All checks were successful
platform/bro-js/bro.landing/pipeline/head This commit looks good
All checks were successful
platform/bro-js/bro.landing/pipeline/head This commit looks good
This commit is contained in:
parent
6e55a331cb
commit
ebf0daacce
26
cloud.md
26
cloud.md
@ -33,6 +33,32 @@
|
||||
|
||||
---
|
||||
|
||||
## Структура файлов
|
||||
|
||||
```
|
||||
bro.landing/
|
||||
├── src/
|
||||
│ ├── styles/
|
||||
│ │ ├── main.module.scss # CSS Modules для React компонентов
|
||||
│ │ ├── main.module.scss.d.ts # TypeScript типы для CSS Modules
|
||||
│ │ └── terms.scss # Обычный SCSS для статической страницы
|
||||
│ ├── pages/
|
||||
│ │ └── under-construction/ # Главная страница (React)
|
||||
│ ├── index.tsx # Entry point для главной страницы
|
||||
│ ├── terms.js # Entry point для стилей Terms
|
||||
│ ├── terms.html # Статический HTML Terms страницы
|
||||
│ ├── index.ejs # HTML шаблон для React страницы
|
||||
│ └── app.tsx # React приложение
|
||||
├── dist/ # Собранные файлы
|
||||
│ ├── index.html # Главная (с React)
|
||||
│ ├── index.js + index.css # Бандлы главной
|
||||
│ ├── terms.html # Terms (чистый HTML + CSS)
|
||||
│ └── terms.css # Стили Terms
|
||||
├── ijl.config.js # Webpack конфигурация
|
||||
└── package.json
|
||||
|
||||
```
|
||||
|
||||
## Структура проекта
|
||||
|
||||
```
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
const path = require('path');
|
||||
const pkg = require('./package');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const isProd = process.env.NODE_ENV === 'production';
|
||||
@ -18,7 +19,7 @@ module.exports = {
|
||||
webpackConfig: {
|
||||
entry: {
|
||||
index: './src/index.tsx',
|
||||
// terms страница не нужен JS, только HTML
|
||||
terms: './src/terms.js', // Entry для стилей terms
|
||||
},
|
||||
output: {
|
||||
publicPath: isProd
|
||||
@ -26,6 +27,34 @@ module.exports = {
|
||||
: `/static/${pkg.name}/${process.env.VERSION || pkg.version}/`,
|
||||
filename: '[name].js?[contenthash]',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.module\.scss$/,
|
||||
use: [
|
||||
isProd ? MiniCssExtractPlugin.loader : 'style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
modules: {
|
||||
localIdentName: isProd ? '[hash:base64:8]' : '[name]__[local]--[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
},
|
||||
'sass-loader'
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
exclude: /\.module\.scss$/,
|
||||
use: [
|
||||
isProd ? MiniCssExtractPlugin.loader : 'style-loader',
|
||||
'css-loader',
|
||||
'sass-loader'
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
// Главная страница (с React)
|
||||
new HtmlWebpackPlugin({
|
||||
@ -33,12 +62,21 @@ module.exports = {
|
||||
filename: 'index.html',
|
||||
chunks: ['index'],
|
||||
}),
|
||||
// Terms страница (чистый HTML без JS)
|
||||
// Terms страница (статика + SCSS)
|
||||
new HtmlWebpackPlugin({
|
||||
template: './src/terms.html',
|
||||
filename: 'terms.html',
|
||||
inject: false, // Не инжектим JS
|
||||
chunks: isProd ? [] : ['terms'], // В production не нужен JS
|
||||
cssPath: isProd
|
||||
? 'https://static.brojs.ru/landing/main/terms.css'
|
||||
: `/static/${pkg.name}/${process.env.VERSION || pkg.version}/terms.css`,
|
||||
}),
|
||||
// Извлечение CSS в отдельные файлы для production
|
||||
...(isProd ? [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].css',
|
||||
})
|
||||
] : []),
|
||||
new webpack.DefinePlugin({
|
||||
IS_PROD: process.env.NODE_ENV === 'production',
|
||||
}),
|
||||
|
||||
457
package-lock.json
generated
457
package-lock.json
generated
@ -32,13 +32,18 @@
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/jest": "^29.5.12",
|
||||
"babel-jest": "^29.7.0",
|
||||
"css-loader": "^7.1.2",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-react": "^7.35.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"globals": "^15.9.0",
|
||||
"html-webpack-plugin": "^5.6.0",
|
||||
"jest": "^29.7.0",
|
||||
"mini-css-extract-plugin": "^2.9.4",
|
||||
"puppeteer": "^24.26.1",
|
||||
"sass": "^1.93.2",
|
||||
"sass-loader": "^16.0.6",
|
||||
"style-loader": "^4.0.0",
|
||||
"ts-jest": "^29.2.3",
|
||||
"typescript-eslint": "^8.1.0"
|
||||
}
|
||||
@ -3144,6 +3149,316 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
|
||||
"integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"is-glob": "^4.0.3",
|
||||
"micromatch": "^4.0.5",
|
||||
"node-addon-api": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@parcel/watcher-android-arm64": "2.5.1",
|
||||
"@parcel/watcher-darwin-arm64": "2.5.1",
|
||||
"@parcel/watcher-darwin-x64": "2.5.1",
|
||||
"@parcel/watcher-freebsd-x64": "2.5.1",
|
||||
"@parcel/watcher-linux-arm-glibc": "2.5.1",
|
||||
"@parcel/watcher-linux-arm-musl": "2.5.1",
|
||||
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
|
||||
"@parcel/watcher-linux-arm64-musl": "2.5.1",
|
||||
"@parcel/watcher-linux-x64-glibc": "2.5.1",
|
||||
"@parcel/watcher-linux-x64-musl": "2.5.1",
|
||||
"@parcel/watcher-win32-arm64": "2.5.1",
|
||||
"@parcel/watcher-win32-ia32": "2.5.1",
|
||||
"@parcel/watcher-win32-x64": "2.5.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-android-arm64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
|
||||
"integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-darwin-arm64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
|
||||
"integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-darwin-x64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
|
||||
"integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-freebsd-x64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
|
||||
"integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm-glibc": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
|
||||
"integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm-musl": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
|
||||
"integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm64-glibc": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
|
||||
"integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm64-musl": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
|
||||
"integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-x64-glibc": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
|
||||
"integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-x64-musl": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
|
||||
"integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-win32-arm64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
|
||||
"integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-win32-ia32": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
|
||||
"integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-win32-x64": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
|
||||
"integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
@ -5607,6 +5922,20 @@
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"detect-libc": "bin/detect-libc.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-newline": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
|
||||
@ -8024,6 +8353,13 @@
|
||||
"url": "https://opencollective.com/immer"
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz",
|
||||
"integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
@ -9839,6 +10175,27 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/mini-css-extract-plugin": {
|
||||
"version": "2.9.4",
|
||||
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz",
|
||||
"integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"schema-utils": "^4.0.0",
|
||||
"tapable": "^2.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"webpack": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
@ -9943,6 +10300,14 @@
|
||||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
@ -11698,6 +12063,98 @@
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.93.2",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.93.2.tgz",
|
||||
"integrity": "sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chokidar": "^4.0.0",
|
||||
"immutable": "^5.0.2",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"sass": "sass.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@parcel/watcher": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/sass-loader": {
|
||||
"version": "16.0.6",
|
||||
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.6.tgz",
|
||||
"integrity": "sha512-sglGzId5gmlfxNs4gK2U3h7HlVRfx278YK6Ono5lwzuvi1jxig80YiuHkaDBVsYIKFhx8wN7XSCI0M2IDS/3qA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"neo-async": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@rspack/core": "0.x || 1.x",
|
||||
"node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
|
||||
"sass": "^1.3.0",
|
||||
"sass-embedded": "*",
|
||||
"webpack": "^5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@rspack/core": {
|
||||
"optional": true
|
||||
},
|
||||
"node-sass": {
|
||||
"optional": true
|
||||
},
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"sass-embedded": {
|
||||
"optional": true
|
||||
},
|
||||
"webpack": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/sass/node_modules/chokidar": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readdirp": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.16.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/sass/node_modules/readdirp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14.18.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.23.2",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
||||
|
||||
@ -42,13 +42,18 @@
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/jest": "^29.5.12",
|
||||
"babel-jest": "^29.7.0",
|
||||
"css-loader": "^7.1.2",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-react": "^7.35.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"globals": "^15.9.0",
|
||||
"html-webpack-plugin": "^5.6.0",
|
||||
"jest": "^29.7.0",
|
||||
"mini-css-extract-plugin": "^2.9.4",
|
||||
"puppeteer": "^24.26.1",
|
||||
"sass": "^1.93.2",
|
||||
"sass-loader": "^16.0.6",
|
||||
"style-loader": "^4.0.0",
|
||||
"ts-jest": "^29.2.3",
|
||||
"typescript-eslint": "^8.1.0"
|
||||
}
|
||||
|
||||
140
readme.md
140
readme.md
@ -1,45 +1,129 @@
|
||||
# BROJS.RU Landing Page
|
||||
# BROJS.RU Landing
|
||||
|
||||
Лендинг платформы обучения фронтенд-разработке.
|
||||
Лендинг платформы для обучения фронтенд-разработке
|
||||
|
||||
## 🚀 Быстрый старт
|
||||
## 🚀 Особенности v3.0
|
||||
|
||||
- ⚡ **Минимальные зависимости** - только необходимое
|
||||
- 📄 **Статический HTML** для идеального SEO
|
||||
- 🎨 **SCSS + CSS Modules** для гибких стилей
|
||||
- 📱 **Адаптивный дизайн** с responsive шрифтами
|
||||
- 🎯 **React** только там, где нужна динамика
|
||||
- 🔥 **Легкий bundle** terms.html (10 KB + 1.5 KB CSS, **без JS!**)
|
||||
|
||||
## 📦 Установка
|
||||
|
||||
```bash
|
||||
# Установка
|
||||
npm install
|
||||
```
|
||||
|
||||
# Разработка
|
||||
npm start
|
||||
# → http://localhost:8099/
|
||||
## 🛠️ Разработка
|
||||
|
||||
# Сборка
|
||||
npm run build:prod
|
||||
```bash
|
||||
npm start # Dev сервер на http://localhost:8099
|
||||
```
|
||||
|
||||
## 🏗️ Сборка
|
||||
|
||||
```bash
|
||||
npm run build:prod # Production сборка в ./dist
|
||||
```
|
||||
|
||||
## 📄 Страницы
|
||||
|
||||
- `/` - главная (в разработке)
|
||||
- `/terms` - пользовательское соглашение
|
||||
### Главная `/`
|
||||
- **React** приложение с анимацией Lottie
|
||||
- Динамическая страница "В разработке"
|
||||
- Файлы: `index.html` + `index.js` (916 KB) + `index.css` (190 B)
|
||||
|
||||
## 🔧 Команды
|
||||
### Terms `/terms`
|
||||
- **Чистый HTML** без JavaScript
|
||||
- Полный текст пользовательского соглашения
|
||||
- SEO-оптимизирован
|
||||
- Адаптивный дизайн
|
||||
- Файлы: `terms.html` (10.5 KB) + `terms.css` (1.5 KB)
|
||||
|
||||
| Команда | Описание |
|
||||
|---------|----------|
|
||||
| `npm start` | Dev сервер |
|
||||
| `npm run build` | Dev сборка |
|
||||
| `npm run build:prod` | Production + SSG |
|
||||
| `npm run build:prod:ssr` | Production + SSR |
|
||||
## 🎨 Стилизация
|
||||
|
||||
## 📦 Результат сборки
|
||||
|
||||
```
|
||||
dist/
|
||||
├── index.html # Главная страница (SSG)
|
||||
├── terms.html # Пользовательское соглашение (SEO)
|
||||
├── index.js # React bundle
|
||||
└── locales/ # i18n файлы
|
||||
### CSS Modules (для React компонентов)
|
||||
```typescript
|
||||
import * as styles from './styles/main.module.scss';
|
||||
element.className = styles.app;
|
||||
```
|
||||
|
||||
---
|
||||
**Преимущества:**
|
||||
- Изоляция стилей
|
||||
- Автоматические уникальные имена классов
|
||||
- TypeScript поддержка
|
||||
|
||||
📚 Полная документация: **cloud.md**
|
||||
### Обычный SCSS (для статических страниц)
|
||||
```scss
|
||||
// terms.scss
|
||||
$mobile: 768px;
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
@media (max-width: $mobile) {
|
||||
font-size: 1.75rem; // Адаптивный шрифт
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📱 Адаптивность
|
||||
|
||||
Все размеры шрифтов автоматически уменьшаются на мобильных устройствах (< 768px):
|
||||
- H1: 2.5rem → 1.75rem
|
||||
- H2: 1.75rem → 1.5rem
|
||||
- H3: 1.25rem → 1.1rem
|
||||
- Body: 1rem → 0.95rem
|
||||
|
||||
## 🗂️ Структура
|
||||
|
||||
```
|
||||
src/
|
||||
├── styles/
|
||||
│ ├── main.module.scss # CSS Modules для React
|
||||
│ ├── main.module.scss.d.ts # TypeScript типы
|
||||
│ └── terms.scss # SCSS для статики
|
||||
├── pages/
|
||||
│ └── under-construction/ # Главная страница
|
||||
├── index.tsx # Entry для React
|
||||
├── terms.js # Entry для CSS
|
||||
├── terms.html # Статический HTML
|
||||
└── index.ejs # Шаблон для React
|
||||
```
|
||||
|
||||
## 🌐 Деплой
|
||||
|
||||
После `npm run build:prod`:
|
||||
- `index.html` → `brojs.ru/`
|
||||
- `terms.html` → `brojs.ru/terms`
|
||||
- Статика → `static.brojs.ru/landing/main/`
|
||||
|
||||
## 🔧 Технологии
|
||||
|
||||
### Core
|
||||
- **React 18** - только для динамических частей
|
||||
- **TypeScript** - типизация
|
||||
- **Webpack 5** - сборка с multiple entry points
|
||||
- **SCSS** - препроцессор
|
||||
- **CSS Modules** - изоляция стилей
|
||||
|
||||
### Библиотеки
|
||||
- **React Router DOM** - клиентский роутинг
|
||||
- **i18next** - интернационализация
|
||||
- **Lottie React** - анимации
|
||||
|
||||
### Dev зависимости
|
||||
- **sass** + **sass-loader** - компиляция SCSS
|
||||
- **css-loader** - обработка CSS (с поддержкой CSS Modules)
|
||||
- **style-loader** - инжект CSS в dev режиме
|
||||
- **mini-css-extract-plugin** - извлечение CSS в production
|
||||
|
||||
## 📚 Документация
|
||||
|
||||
Полная документация в [cloud.md](./cloud.md)
|
||||
|
||||
## 🤝 Участие
|
||||
|
||||
Проект использует минималистичный подход - добавляем зависимости только по мере необходимости!
|
||||
|
||||
@ -4,11 +4,17 @@ import { i18nextReactInitConfig } from '@brojs/cli';
|
||||
import { createRoot, hydrateRoot } from 'react-dom/client'
|
||||
|
||||
import App from './app';
|
||||
import * as styles from './styles/main.module.scss';
|
||||
|
||||
i18next.t = i18next.t.bind(i18next);
|
||||
const i18nextPromise = i18nextReactInitConfig(i18next);
|
||||
const MOUNT_NODE = document.getElementById('app');
|
||||
|
||||
// Применяем класс к app контейнеру
|
||||
if (MOUNT_NODE) {
|
||||
MOUNT_NODE.className = styles.app || 'app';
|
||||
}
|
||||
|
||||
(async () => {
|
||||
await Promise.all([i18nextPromise]);
|
||||
|
||||
|
||||
13
src/styles/main.module.scss
Normal file
13
src/styles/main.module.scss
Normal file
@ -0,0 +1,13 @@
|
||||
// Main styles for the landing page
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.app {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
2
src/styles/main.module.scss.d.ts
vendored
Normal file
2
src/styles/main.module.scss.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export const app: string;
|
||||
|
||||
157
src/styles/terms.scss
Normal file
157
src/styles/terms.scss
Normal file
@ -0,0 +1,157 @@
|
||||
// Terms page styles
|
||||
$primary-color: #1a202c;
|
||||
$bg-color: #f7fafc;
|
||||
$white: #fff;
|
||||
$text-secondary: #4a5568;
|
||||
$text-muted: #718096;
|
||||
$text-light: #a0aec0;
|
||||
$border-color: #e2e8f0;
|
||||
$link-color: #3182ce;
|
||||
|
||||
$container-max-width: 1200px;
|
||||
$border-radius: 8px;
|
||||
$spacing-base: 1rem;
|
||||
|
||||
// Breakpoints
|
||||
$mobile: 768px;
|
||||
$tablet: 1024px;
|
||||
|
||||
// Reset
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: $primary-color;
|
||||
background: $bg-color;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: $container-max-width;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.terms-doc {
|
||||
background: $white;
|
||||
padding: 60px 80px;
|
||||
border-radius: $border-radius;
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
||||
|
||||
@media (max-width: 768px) {
|
||||
padding: 40px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
color: #2d3748;
|
||||
text-align: center;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
@media (max-width: $mobile) {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: center;
|
||||
color: $text-muted;
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: $spacing-base;
|
||||
|
||||
@media (max-width: $mobile) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.date {
|
||||
text-align: center;
|
||||
color: $text-light;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid $border-color;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
color: #2d3748;
|
||||
margin: 2rem 0 $spacing-base;
|
||||
|
||||
@media (max-width: $mobile) {
|
||||
font-size: 1.5rem;
|
||||
margin: 1.5rem 0 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: $text-secondary;
|
||||
margin: 1.5rem 0 0.75rem;
|
||||
|
||||
@media (max-width: $mobile) {
|
||||
font-size: 1.1rem;
|
||||
margin: 1.25rem 0 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: $spacing-base;
|
||||
color: $text-secondary;
|
||||
font-size: 1rem;
|
||||
|
||||
@media (max-width: $mobile) {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: $spacing-base 0 $spacing-base 2rem;
|
||||
color: $text-secondary;
|
||||
font-size: 1rem;
|
||||
|
||||
@media (max-width: $mobile) {
|
||||
font-size: 0.95rem;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: $link-color;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
color: #2d3748;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
margin-top: 3rem;
|
||||
padding-top: 2rem;
|
||||
border-top: 1px solid $border-color;
|
||||
color: $text-light;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@ -8,95 +8,7 @@
|
||||
<meta name="description" content="Пользовательское соглашение для платформы обучения фронтенд-разработке BROJS.RU. Условия использования, обработка персональных данных, права и обязанности сторон.">
|
||||
<meta name="yandex-verification" content="98f7e15d1ad66018">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700,900&subset=cyrillic,cyrillic-ext" rel="stylesheet">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #1a202c;
|
||||
background: #f7fafc;
|
||||
}
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
.terms-doc {
|
||||
background: white;
|
||||
padding: 60px 80px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.terms-doc { padding: 40px 24px; }
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
color: #2d3748;
|
||||
text-align: center;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.subtitle {
|
||||
text-align: center;
|
||||
color: #718096;
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.date {
|
||||
text-align: center;
|
||||
color: #a0aec0;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
color: #2d3748;
|
||||
margin: 2rem 0 1rem;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #4a5568;
|
||||
margin: 1.5rem 0 0.75rem;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
color: #4a5568;
|
||||
}
|
||||
ul {
|
||||
margin: 1rem 0 1rem 2rem;
|
||||
color: #4a5568;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
a {
|
||||
color: #3182ce;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
strong {
|
||||
font-weight: 600;
|
||||
color: #2d3748;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
margin-top: 3rem;
|
||||
padding-top: 2rem;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
color: #a0aec0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cssPath %>">
|
||||
</head>
|
||||
<body>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/87860751" style="position:absolute; left:-9999px;" alt=""></div></noscript>
|
||||
|
||||
3
src/terms.js
Normal file
3
src/terms.js
Normal file
@ -0,0 +1,3 @@
|
||||
// Entry point for terms page styles
|
||||
import './styles/terms.scss';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user