From 2a096edf6afdd56740c094d32cebe8800a9a55e0 Mon Sep 17 00:00:00 2001 From: yusukehirao Date: Tue, 7 May 2024 19:58:26 +0900 Subject: [PATCH] feat: first commit --- .editorconfig | 7 + .eslintrc | 3 + .github/renovate.json | 37 + .github/workflows/pages.yml | 44 + .gitignore | 79 + .prettierrc.mjs | 3 + .textlintrc.js | 9 + .vscode/extensions.json | 8 + .vscode/settings.json | 15 + LICENSE | 4 + README.md | 5 + cspell.json | 11 + lint-staged.config.mjs | 2 + package.json | 36 + src/.vitepress/config.js | 20 + src/.vitepress/theme/custom.css | 23 + src/.vitepress/theme/index.js | 4 + src/breakpoint.png | Bin 0 -> 28720 bytes src/css.md | 721 ++++ src/git.md | 56 + src/html.md | 964 +++++ src/index.md | 357 ++ src/js.md | 376 ++ src/media.md | 95 + src/naming.md | 112 + src/setup-volta.md | 3 + yarn.lock | 6372 +++++++++++++++++++++++++++++++ 27 files changed, 9366 insertions(+) create mode 100755 .editorconfig create mode 100644 .eslintrc create mode 100644 .github/renovate.json create mode 100644 .github/workflows/pages.yml create mode 100644 .gitignore create mode 100644 .prettierrc.mjs create mode 100644 .textlintrc.js create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 LICENSE create mode 100644 README.md create mode 100644 cspell.json create mode 100644 lint-staged.config.mjs create mode 100644 package.json create mode 100644 src/.vitepress/config.js create mode 100644 src/.vitepress/theme/custom.css create mode 100644 src/.vitepress/theme/index.js create mode 100644 src/breakpoint.png create mode 100644 src/css.md create mode 100644 src/git.md create mode 100644 src/html.md create mode 100644 src/index.md create mode 100644 src/js.md create mode 100644 src/media.md create mode 100644 src/naming.md create mode 100644 src/setup-volta.md create mode 100644 yarn.lock diff --git a/.editorconfig b/.editorconfig new file mode 100755 index 0000000..2f1404f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +# https://editorconfig.org +root = true +indent_style = tab +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..d14214a --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": ["@d-zero/eslint-config/base"] +} diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..d3f3d01 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "configMigration": true, + "extends": [ + "config:recommended", + "docker:pinDigests", + "helpers:pinGitHubActionDigests", + ":pinDevDependencies", + ":semanticCommitTypeAll(chore)" + ], + "lockFileMaintenance": { + "enabled": true, + "automerge": true + }, + "autoApprove": true, + "labels": ["Dependencies", "Renovate"], + "packageRules": [ + { + "matchDepTypes": ["optionalDependencies"], + "addLabels": ["Dependencies: Optional"] + }, + { + "matchDepTypes": ["devDependencies"], + "addLabels": ["Dependencies: Development"] + }, + { + "matchDepTypes": ["dependencies"], + "addLabels": ["Dependencies: Production"] + }, + { + "description": "Automerge non-major updates", + "matchUpdateTypes": ["minor", "patch", "pin", "digest"], + "matchCurrentVersion": "!/^0/", + "automerge": true + } + ] +} diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..68c073b --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,44 @@ +name: Deploy Pages + +on: + push: + branches: ['main'] + pull_request: + branches: + - main + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: 'pages' + cancel-in-progress: true + +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Use Node.js + uses: actions/setup-node@v1 + with: + node-version: 22 + - name: Install dependencies + run: yarn install + - name: Build Pages + run: yarn build + - name: Setup Pages + uses: actions/configure-pages@v2 + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: './dist' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d3df81 --- /dev/null +++ b/.gitignore @@ -0,0 +1,79 @@ +# macOS +.DS_Store + +# Dist *.js sources +lib + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# next.js build output +.next + +# TypeScript +*.tsbuildinfo + +# Secret Test +test/fixture/.__* + +# Vitepress +src/.vitepress/cache + +# Pages +.dist diff --git a/.prettierrc.mjs b/.prettierrc.mjs new file mode 100644 index 0000000..bb3531c --- /dev/null +++ b/.prettierrc.mjs @@ -0,0 +1,3 @@ +import config from '@d-zero/prettier-config'; + +export default config; diff --git a/.textlintrc.js b/.textlintrc.js new file mode 100644 index 0000000..9bd208e --- /dev/null +++ b/.textlintrc.js @@ -0,0 +1,9 @@ +module.exports = { + ...require('@d-zero/textlint-config'), + 'no-mix-dearu-desumasu': { + preferInHeader: 'である', + preferInBody: 'ですます', + preferInList: 'である', + strict: true, + }, +}; diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..1d6b1aa --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "editorconfig.editorconfig", + "esbenp.prettier-vscode", + "streetsidesoftware.code-spell-checker" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..de6ca8f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "editor.defaultFormatter": "esbenp.prettier-vscode", + "eslint.validate": ["javascript", "typescript"], + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "github.copilot.enable": { + "*": true, + "plaintext": false, + "log": false, + "dotenv": false + } +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0acb854 --- /dev/null +++ b/LICENSE @@ -0,0 +1,4 @@ +Copyright (c) 2024 D-ZERO Co., Ltd. + +Licensed under CC BY-NC-SA 4.0 +https://creativecommons.org/licenses/by-nc-sa/4.0/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..3fe0628 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# ディーゼロ コーディングガイドライン + +株式会社ディーゼロの主にフロントエンド開発のために規定しているコーディンガイドラインです。 + +Copyright (c) 2024 D-ZERO Co., Ltd. Licensed under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) diff --git a/cspell.json b/cspell.json new file mode 100644 index 0000000..b0b81f2 --- /dev/null +++ b/cspell.json @@ -0,0 +1,11 @@ +{ + "import": ["@d-zero/cspell-config"], + "words": [ + // + "huskyrc", + "nodist", + "Splide", + "splidejs", + "WCAG" + ] +} diff --git a/lint-staged.config.mjs b/lint-staged.config.mjs new file mode 100644 index 0000000..d0474bd --- /dev/null +++ b/lint-staged.config.mjs @@ -0,0 +1,2 @@ +import lintStagedConfigGenerator from '@d-zero/lint-staged-config'; +export default lintStagedConfigGenerator(); diff --git a/package.json b/package.json new file mode 100644 index 0000000..d72553f --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "@d-zero/frontend-guidelines", + "version": "5.0.0-alpha.0", + "description": "D-ZERO Frontend Developer's Guideline", + "repository": "https://github.com/d-zero-dev/frontend-env.git", + "author": "D-ZERO Co., Ltd.", + "license": "CC BY-NC-SA 4.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vitepress dev src", + "build": "vitepress build src", + "lint": "run-s lint:eslint lint:prettier lint:textlint lint:cspell", + "lint:cspell": "cspell --no-progress --show-suggestions \"{*,src/*}/\"", + "lint:eslint": "eslint --fix \"*.{js,cjs,mjs}\"", + "lint:prettier": "prettier --write \"{*,src/*}.{md,json,js,cjs,mjs,jsx,ts,cts,mts,tsx}\"", + "lint:textlint": "textlint --fix ./src/*.md; textlint ./src/*.md", + "up": "yarn upgrade-interactive --latest" + }, + "devDependencies": { + "@d-zero/cspell-config": "5.0.0-alpha.23", + "@d-zero/eslint-config": "5.0.0-alpha.23", + "@d-zero/lint-staged-config": "5.0.0-alpha.23", + "@d-zero/prettier-config": "5.0.0-alpha.23", + "@d-zero/textlint-config": "5.0.0-alpha.23", + "@d-zero/tsconfig": "0.2.0", + "mermaid": "10.9.0", + "npm-run-all2": "6.1.2", + "vitepress": "1.1.4", + "vitepress-plugin-mermaid": "2.0.16" + }, + "volta": { + "node": "22.1.0", + "yarn": "1.22.22" + } +} diff --git a/src/.vitepress/config.js b/src/.vitepress/config.js new file mode 100644 index 0000000..9960016 --- /dev/null +++ b/src/.vitepress/config.js @@ -0,0 +1,20 @@ +import { defineConfig } from 'vitepress'; +import { withMermaid } from 'vitepress-plugin-mermaid'; + +export default async () => { + return withMermaid( + defineConfig({ + outDir: process.cwd() + '/.dist', + lang: 'ja', + title: 'ディーゼロ コーディングガイドライン', + description: + '株式会社ディーゼロの主にフロントエンド開発のために規定しているコーディンガイドラインです。', + themeConfig: { + footer: { + message: 'Licensed under CC BY-NC-SA 4.0', + copyright: 'Copyright © 2024 D-ZERO Co., Ltd.', + }, + }, + }), + ); +}; diff --git a/src/.vitepress/theme/custom.css b/src/.vitepress/theme/custom.css new file mode 100644 index 0000000..7aa7bce --- /dev/null +++ b/src/.vitepress/theme/custom.css @@ -0,0 +1,23 @@ +.vp-doc div[class*='language-'] + div[class*='language-'], +.vp-doc div[class$='-api'] + div[class*='language-'], +.vp-doc div[class*='language-'] + div[class$='-api'] > div[class*='language-'] { + margin-block-start: 1em; +} + +@media print { + .VPNav { + position: relative !important; + } + + .VPLocalNav { + display: none !important; + } + + .vp-doc [class*='language-'] { + border: 1px solid gray; + } + + .vp-doc [class*='language-'] :is(pre, code) { + white-space: pre-wrap; + } +} diff --git a/src/.vitepress/theme/index.js b/src/.vitepress/theme/index.js new file mode 100644 index 0000000..149273e --- /dev/null +++ b/src/.vitepress/theme/index.js @@ -0,0 +1,4 @@ +import DefaultTheme from 'vitepress/theme'; +import './custom.css'; + +export default DefaultTheme; diff --git a/src/breakpoint.png b/src/breakpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..65f8879981cda03e74182f8be915ea5c8c9dbd61 GIT binary patch literal 28720 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 literal 0 HcmV?d00001 diff --git a/src/css.md b/src/css.md new file mode 100644 index 0000000..85661b7 --- /dev/null +++ b/src/css.md @@ -0,0 +1,721 @@ +# CSS ガイドライン + +🔰 当ドキュメントは「[コーディングガイドライン](./index.md)」の一部です。 +基本的なガイドライン・ルールについては先にそれから確認してください。 + +## 🎯 CSS ガイドラインの目的 + +CSSのガイドラインは次の3つを主な目的として策定されています。 + +- 確実性 + - 影響範囲が明瞭であること + - 確実に場所を特定して追加・変更ができること +- 機能性 + - 命名規則が機能的でその機能が予測し易くあること + - プロジェクトにヘルプアサインされてもほとんどが判断がつくこと +- 一貫性 + - 一貫した汎用ルールがあることでプロジェクト独自ルールの氾濫を避けられること + - プロジェクトをまたいでも混乱することがないこと + +### 作用をきちんと理解する + +「何故か解らないけど出来た」は一番やってはいけません。プロパティひとつひとつ、セレクタひとつひとつが、どういった作用をするかきちんと理解してコーディングすることを心掛けてください。 + +### 別解を用意すること + +ほとんどの場合、表現の方法はひとつではありません。メンテナンス性を優先させた方法、パフォーマンスを優先させた方法など、そのときそのときで最適な方法を探す必要があります。常にいくつかのパターンを考えながらコーディングできるように心掛けてください。また、万が一にブラウザの予期せぬバグに遭遇した際にも別解で解決する必要があります。 + +## 💅 コードスタイル + +*Stylelint*に設定されているルールに則って記述します。 + +::: danger リントエラーについて +例外なく必ずリントエラーを修正してください。**リンターのルールが現状にそぐわない場合はルールの見直しを行ってください**。 +::: + +::: warning Stylelintの`disable`コメント + +`disable`コメントを利用することで、ルールを無視することができますが**原則行わない**でください。 +`_content-main.scss` などのように既に`disable`コメントがある場合もあるがこれは特有の理由があるので削除しないようにしてください。 + +```scss +.c-header { + /* ❌ 実装上やむを得ない場合を除いてdisableコメントは使用しないこと */ + width: 100px !important; // stylelint-disable-line declaration-no-important +} +``` + +::: + +## 🍴 プリプロセッサー・コンパイル環境 + +11tyを介して[Viteの標準のCSS変換](https://ja.vitejs.dev/guide/features#css)を行います。プリプロセッサーはSASSを利用します。 + +```mermaid +flowchart LR + #in["*.scss"] + #out["*.css"] + #vite(["Vite"]) + + #in --> #dzBuilder --> #out + + subgraph #dzBuilder["@d-zero/builder"] + direction LR + + subgraph #11ty["11ty"] + subgraph #vite["vite"] + direction TB + #sass --> #postcss + end + end + end +``` + +### ベンダープレフィックス + +Autoprefixerを利用するのでベンダープレフィックス付きのプロパティは必要ありません。Stylelintによってベンダープレフィックス付きのプロパティは警告されます。 + +```scss +selector { + transition: opacity 300ms; + -webkit-transition: opacity 300ms; // ❌ 不要 + -moz-transition: opacity 300ms; // ❌ 不要 +} +``` + +ただしCSSの標準規格でないものについては必要なケースがあります。Stylelintはその点を考慮して警告を出すので心配はありません。 + +```scss +selector { + -moz-osx-font-smoothing: grayscale; // ✅ ブラウザ固有のプロパティのためプレフィックは必要 + -webkit-font-smoothing: antialiased; // ✅ ブラウザ固有のプロパティのためプレフィックは必要 +} +``` + +## 📂 ファイル構成 + +ファイルは以下の構成で管理します。 + +``` +# リソース管理 +📂 __assets/ +├── 📂 htdocs/ +│ └── 📂 theme/ +│ ├── style.scss +│ └── bge_style.scss +└── 📂 _libs/ + ├── 📂 component/ + │ ├── _component-name-a.scss + │ ︙ + │ └── _component-name-z.scss + └── 📂 style/ + ├── 📂 theme/ + │ ├── _index.scss + │ ├── _color.scss + │ ├── _demension.scss + │ └── _font.scss + ├── 📂 base/ + │ ├── _reset.scss + │ └── _root.scss + └── 📂 general/ + ├── _tag-name-a.scss + ︙ + └── _tag-name-z.scss + +# 公開ファイル +📂 htdocs/css/ +├── style.css +└── bge_style.css +``` + +`__assets/htdocs`フォルダの内容は**フォルダ構造をそのまま**にドキュメントルートの`htdocs`にCSSファイルとしてコンパイルされ出力されます。 + +SASSの機能に従って`@use`する断片ファイルは`_`で始まるファイル名とします。 + +### `__assets/htdocs/css/style.scss` + +`style.css`にコンパイルするSCSSファイルです。`@use`を利用して各断片ファイルをインポートし、ここにスタイルは定義しないようにしてください。 + +`base` → `general` → `component` の順にカスケードされるようにインポートしてください。 + +```scss +/* useの例 */ +@use 'base/reset'; +@use 'base/root'; +@use 'general/tag-name-a'; +@use 'general/tag-name-z'; +@use 'component/component-name-a'; +@use 'component/component-name-z'; +``` + +### `__assets/_libs/style/theme/` + +カラー・数値など、**SASS変数**やミックスインを定義します。 + +- `_color.scss`: カラーコードのSASS変数の定義 +- `_demension.scss`: 全体のレイアウトの寸法・マージン・パディングのSASS変数の定義 +- `_font.scss`: `@font-face`・フォントファミリーのSASS変数の定義、アイコンのコードポイントの変数・アイコン出力用のミックスインの定義 + +**カスタムプロパティは`base/_root.scss`などのスコープに応じたファイルに定義してください。** + +::: tip 他のSCSSファイル上での変数の利用 + +`@use '../theme' as *;`を記述することで`theme/_index.scss`を参照し`theme/`フォルダ内で定義した変数やミックスインを利用することができます。 + +```scss +@use '../theme' as *; // `_demension.scss`に`$root-font-size`が定義されているとする + +selector { + font-size: $root-font-size; +} +``` + +::: + +::: danger プレースホルダーの禁止 + +カスケード(定義の順番)が期待通りにしにくい問題があるので**プレースホルダー**を`__assets/_libs/style/theme/`内に定義するは原則禁止とします。 + +```scss +// ❌ プレースホルダーの利用は原則禁止 +%any-style { + any-property: any-value; +} + +// ✅ ミックスインを利用する +@mixin anyMixin { + any-property: any-value; +} +``` + +::: + +::: warning ミックスインの利用時の注意 + +タグやクラスに依存するミックスインは作らないようにしてください。影響範囲を予測できなくなるため`@mixin`のスコープ内に子孫セレクタをつくらないようにしてください。 + +```scss +// ❌ 特定のタグでしか利用できないミックスインは作らない +@mixin anyList { + display: flex; + + // ❌ ミックインのスコープ内に子孫セレクタをつくらない + li { + flex: 0 1 auto; + } +} +``` + +::: + +### `__assets/_libs/style/base/_reset.scss` + +リセット用のスタイルを定義します。デフォルトでは[Normalize.css](https://necolas.github.io/normalize.css/)を利用しています。 + +```scss +@import 'normalize.css' layer(reset); +``` + +カスケードレイヤーは`reset`として定義します。 + +### `__assets/_libs/style/base/_root.scss` + +ルート要素に対するスタイル定義を定義します。セレクタは`:root`だけで、他のセレクタを含めないようにしてください。 + +::: tip カスタムプロパティの定義 + +グローバルスコープのカスタムプロパティを定義する場合は、`:root`セレクタ内で行なってください。 + +::: + +### `__assets/_libs/style/general/` + +クラスやIDの付かない素の要素に対してスタイルを定義します。ファイル名はタグ名(要素名)となります。セレクタは当然タイプセレクタのみとなります。 + +- 例) `` → `_body.scss` +- 例) `` → `_a.scss` + +コンポーネントをまたいだ各要素、つまりページ全体に影響があることに注意してください。そのため必要最小限の定義に留めることを心掛けてください。コンポーネントで定義できるものはコンポーネント内で定義してください。 + +全要素対象の場合は`_all.scss`ファイルに`*`(全称セレクタ)で定義します。 + +```scss +// _all.scssの例 +* { + &, + &::before, + &::after { + box-sizing: border-box; + } +} +``` + +また、定義をしてよい理由は主に以下に限定する。 + +- サイト全体で共通すると断定できる場合。 **ただし、ほとんどの場合、その判断は失敗に終わるので推奨しない。** +- CMS などから入力された要素を、セレクターで判定できない場合(判定できない構造は、HTML と CSS の設計を見直す方を優先する) + +### `__assets/_libs/style/component/` + +要素はコンポーネント単位に分割して管理する。(👉[HTML ガイドライン > コンポーネント](./html.md#component)) +ファイル名はコンポーネント名とする。 **ひとつのファイルの中に複数のコンポーネントを定義してはいけない**。 + +- 例) `
` → `_header-page.scss` +- 例) `