基本テンプレートの作成#
グローバルインストールスクリプトの作成#
yarn global add create-vite
プロジェクトの初期化#
vite-create <product-name>
git の追加#
git init
コードフォーマットの検証を追加#
ESLint の追加#
パッケージのインストール#
npm i eslint eslint-plugin-vue @vue/eslint-config-prettier @vue/eslint-config-typescript -D
eslint の設定#
.eslintrc
{
"root": true,
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"plugin:vue/vue3-recommended",
"eslint:recommended",
"@vue/typescript/recommended",
"@vue/prettier"
],
"plugins": ["vue"],
"settings": {
"import/resolver": {
"node": { "extensions": [".js", ".mjs", ".ts", ".d.ts", ".tsx"] }
}
},
"overrides": [
{
"files": ["*.json", "*.json5", "*.jsonc"],
"parser": "jsonc-eslint-parser"
},
{
"files": ["*.ts", "*.vue"],
"rules": {
"no-undef": "off"
}
},
{
"files": ["**/__tests__/**"],
"rules": {
"no-console": "off",
"vue/one-component-per-file": "off"
}
},
{
"files": ["*.d.ts"],
"rules": {
"import/no-duplicates": "off"
}
},
{
"files": ["*.js"],
"rules": {
"@typescript-eslint/no-var-requires": "off"
}
},
{
"files": ["*.vue"],
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": "@typescript-eslint/parser",
"extraFileExtensions": [".vue"],
"ecmaVersion": "latest",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"no-undef": "off"
}
}
],
"rules": {
"no-console": ["warn", { "allow": ["error"] }],
"no-debugger": "warn"
}
}
Prettier のインストール#
パッケージのインストール#
npm i prettier -D
正常であれば、prettier
はこれだけでインストールできますが、[email protected]
は @vue/eslint-config-prettier
の eslint-plugin-prettier
と互換性がないため、低バージョンの eslint-plugin-prettier
をインストールする必要があります:npm i [email protected] -D
。
prettier のバージョンを下げることもできますが、推奨はしません。stylelint をインストールする際に、
stylelint-prettier
に影響を与える可能性があります。もちろん、低バージョンのstylelint-prettier
をインストールすることもできますが、prettier
とのフォーマットの衝突問題が発生します。この場合、stylelint-config-prettier
を導入して解決しようとするかもしれませんが、それはstylelint
のバージョンが15.0.0
未満であることを要求します。そのため、stylelint
のバージョンを下げる必要があり、依存関係の互換性の問題が徐々に発生します。
prettier の設定#
.prettierrc
{
"singleQuote": true,
"semi": false,
"vueIndentScriptAndStyle": true
}
StyleLint の追加#
パッケージのインストール#
npm i stylelint stylelint-config-standard stylelint-config-standard-scss stylelint-config-standard-vue stylelint-order stylelint-prettier -D
stylelint の設定#
.stylelintrc
{
"extends": [
"stylelint-config-standard",
"stylelint-config-standard-scss",
"stylelint-config-standard-vue/scss",
"stylelint-prettier/recommended"
],
"plugins": ["stylelint-order"],
"customSyntax": "postcss-scss",
"rules": {
"order/order": ["custom-properties", "declarations"],
"order/properties-order": [
"position",
"top",
"right",
"bottom",
"left",
"z-index",
"display",
"justify-content",
"align-items",
"float",
"clear",
"overflow",
"overflow-x",
"overflow-y",
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"border",
"border-style",
"border-width",
"border-color",
"border-top",
"border-top-style",
"border-top-width",
"border-top-color",
"border-right",
"border-right-style",
"border-right-width",
"border-right-color",
"border-bottom",
"border-bottom-style",
"border-bottom-width",
"border-bottom-color",
"border-left",
"border-left-style",
"border-left-width",
"border-left-color",
"border-radius",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height",
"font-size",
"font-family",
"font-weight",
"text-align",
"text-justify",
"text-indent",
"text-overflow",
"text-decoration",
"white-space",
"color",
"background",
"background-position",
"background-repeat",
"background-size",
"background-color",
"background-clip",
"opacity",
"filter",
"list-style",
"outline",
"visibility",
"box-shadow",
"text-shadow",
"resize",
"transition"
]
},
"ignoreFiles": ["node_modules/**", "dist/**", "build/**", ".git/**", "*.js"],
"overrides": [
{
"files": ["*.(html|vue)", "**/*.(html|vue)"],
"rules": {
"unit-allowed-list": ["em", "rem", "px", "%", "s", "vw", "vh", "ms"]
},
"customSyntax": "postcss-html"
}
]
}
VSCode の設定#
プラグインのインストール#
プロジェクトの設定が完了した後、ターミナルコマンドを使用してフォーマット操作を実行できるようになりますが、IDE のフォーマット操作には対応するプラグインをインストールする必要があります。VSCode では、ESlint
、Prettier
、StyleLint
プラグインをインストールする必要があります。
プロジェクトの設定#
.vscode/settings.json
{
"css.validate": true,
"scss.validate": false,
"less.validate": false,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.fixAll.eslint": true
},
"eslint.probe": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"json",
"jsonc"
],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"json",
"jsonc"
],
"eslint.quiet": true, // 警告メッセージを表示しない
"stylelint.validate": ["css", "less", "postcss", "scss", "sass", "vue"],
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "stylelint.vscode-stylelint"
},
"[less]": {
"editor.defaultFormatter": "stylelint.vscode-stylelint"
},
"[scss]": {
"editor.defaultFormatter": "stylelint.vscode-stylelint"
},
"[sass]": {
"editor.defaultFormatter": "stylelint.vscode-stylelint"
}
}
editorconfig の追加#
異なるオペレーティングシステムでのエディタのフォーマットを一致させるために、一般的に EditorConfig for VS Code
プラグインを追加します。
設定#
.editorconfig
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
コミット検証#
パッケージのインストール#
npm i commitizen @commitlint/cli @commitlint/config-conventional @commitlint/cz-commitlint -D
コミットの設定#
.commitlintrc.json
{
"extends": ["@commitlint/config-conventional"],
"rules": {
"type-empty": [2, "never"],
"scope-enum": [2, "always", ["core", "style", "docs"]]
},
"prompt": {
"settings": {
"enableMultipleScopes": true,
"scopeEnumSeparator": ","
},
"messages": {
"skip": ":skip",
"max": "upper %d chars",
"min": "%d chars at least",
"emptyWarning": "can not be empty",
"upperLimitWarning": "over limit",
"lowerLimitWarning": "below limit"
},
"questions": {
"type": {
"description": "Select the type of change that you're committing:",
"enum": {
"feat": {
"description": "A new feature",
"title": "Features",
"emoji": "✨"
},
"fix": {
"description": "A bug fix",
"title": "Bug Fixes",
"emoji": "🐛"
},
"docs": {
"description": "Documentation only changes",
"title": "Documentation",
"emoji": "📚"
},
"style": {
"description": "Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)",
"title": "Styles",
"emoji": "💎"
},
"refactor": {
"description": "A code change that neither fixes a bug nor adds a feature",
"title": "Code Refactoring",
"emoji": "📦"
},
"perf": {
"description": "A code change that improves performance",
"title": "Performance Improvements",
"emoji": "🚀"
},
"test": {
"description": "Adding missing tests or correcting existing tests",
"title": "Tests",
"emoji": "🚨"
},
"build": {
"description": "Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)",
"title": "Builds",
"emoji": "🛠"
},
"ci": {
"description": "Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)",
"title": "Continuous Integrations",
"emoji": "⚙️"
},
"chore": {
"description": "Other changes that don't modify src or test files",
"title": "Chores",
"emoji": "♻️"
},
"revert": {
"description": "Reverts a previous commit",
"title": "Reverts",
"emoji": "🗑"
}
}
},
"scope": {
"description": "scope"
},
"subject": {
"description": "Write a short, imperative tense description of the change"
},
"body": {
"description": "Provide a longer description of the change"
},
"isBreaking": {
"description": "Are there any breaking changes?"
},
"breakingBody": {
"description": "A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself"
},
"breaking": {
"description": "Describe the breaking changes"
},
"isIssueAffected": {
"description": "Does this change affect any open issues?"
},
"issuesBody": {
"description": "If issues are closed, the commit requires a body. Please enter a longer description of the commit itself"
},
"issues": {
"description": "Add issue references (e.g. \"fix #123\", \"re #123\".)"
}
}
}
}
package.json
に以下の設定を追加:
"config": {
"commitizen": {
"path": "@commitlint/cz-commitlint"
}
}
scripts
にコマンド "commit": "git-cz"
を追加
プロセスの自動化#
パッケージのインストール#
npm i husky lint-staged -D
コマンドの追加#
package.json
の scripts
に以下のコマンドを追加:
"prepare": "husky install",
"lint": "eslint --ext .ts,vue,tsx --ignore-path .gitignore .",
"style": "stylelint src/**/*.{css,scss,vue}",
"tslint": "vue-tsc --noEmit"
husky
を使用して git hook
を追加:
# commit 前にコードフォーマットを実行
npx husky add .husky/pre-commit "npx lint-staged"
# commit msg の検証
npx husky add .husky/commit-msg "npx commitlint --edit $1"
# commit 後、自動でリモートブランチにプッシュ
npx husky add .husky/post-commit "branch=$(git symbolic-ref --short -q HEAD)
git pull origin $branch
if [ "$?" == "0" ]; then
git push origin $branch
if [ "$?" == "0" ]; then
echo "✨✨✨ プッシュ成功!"
else
echo 'プッシュに失敗しました!'
exit 1
fi
else
echo 'コードのプルに失敗しました!'
exit 1
fi"
TypeScript の設定#
パッケージのインストール#
npm i typescript vue-tsc -D
typescript の設定#
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"paths": {
"@/*": ["src/*"]
},
"types": [
"unplugin-vue-define-options",
"vitest/importMeta",
"unplugin-icons/types/vue",
"element-plus/global"
],
/* Bundler mode */
"moduleResolution": "node",
"allowImportingTsExtensions": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": [
"auto-imports.d.ts",
"components.d.ts",
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue"
],
"references": [{ "path": "./tsconfig.node.json" }]
}
tsconfig.node.json
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}
types/env.d.ts
/// <reference types="vite/client" />
import Http from '@/utils/Http'
declare module '*.vue' {
import type { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
declare module '@vue/runtime-core' {
export interface ComponentCustomProperties {
$http: typeof Http
}
}
コンポーネント、API、アイコンの自動インポートを追加#
パッケージのインストール#
npm i unplugin-auto-import unplugin-vue-components unplugin-icons unplugin-vue-define-options -D
設定#
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import DefineOptions from 'unplugin-vue-define-options/vite'
import Unocss from 'unocss/vite'
import Inspect from 'vite-plugin-inspect'
import VueJsx from '@vitejs/plugin-vue-jsx'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
// https://vitejs.dev/config/
export default defineConfig({
assetsInclude: ['**/*.JPG'],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
},
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
},
css: {
preprocessorOptions: {
scss: {
additionalData: `@use '@/style/variables.scss' as *;`,
},
},
},
build: {
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
},
plugins: [
vue(),
VueJsx(),
DefineOptions(),
Components({
dirs: ['src/components', 'main.ts'],
extensions: ['vue'],
deep: true,
dts: true,
resolvers: [
ElementPlusResolver(),
IconsResolver({
alias: {
park: 'icon-park',
},
customCollections: ['custom'],
}),
],
}),
AutoImport({
resolvers: [ElementPlusResolver()],
imports: ['vue', 'vue-router', '@vueuse/core', 'pinia', 'vitest'],
include: [/\.[tj]sx?$/, /\.vue$/, /\.vue\?vue/, /\.md$/],
dirs: ['./src/composables'],
eslintrc: {
enabled: true,
globalsPropValue: true,
},
}),
Unocss(),
Icons({
autoInstall: true,
compiler: 'vue3',
customCollections: {
custom: FileSystemIconLoader('./src/icon/svg', (svg) =>
svg
.replace(/(width|height)=['"](\w+)['"]/g, '')
.replace(/^<svg /, '<svg fill="currentColor"'),
),
},
iconCustomizer(collection, icon, props) {
props.width = '1.2em'
props.height = '1.2em'
},
}),
Inspect(),
]
})
テストの追加#
パッケージのインストール#
npm i vitest @vitest/ui @vitest/coverage-c8 jsdom -D
VSCode に Vitest
プラグインを追加
設定#
コマンドの追加#
"test": "vitest dev",
"ui": "vitest --ui",
"coverage": "vitest run --coverage"
vitest の設定#
vitest.config.ts
import { defineConfig, mergeConfig } from 'vitest/config'
import viteConfig from './vite.config'
export default mergeConfig(
viteConfig,
defineConfig({
define: {
'import.meta.vitest': 'undefined',
},
test: {
globals: true,
clearMocks: true,
environment: 'jsdom',
setupFiles: ['./vitest.setup.ts'],
transformMode: {
web: [/\.[jt]sx$/],
},
includeSource: ['src/**/*.{js,ts}'],
coverage: {
provider: 'c8',
reporter: ['text', 'json', 'html'],
},
},
}),
)
vitest.setup.ts
import { config } from '@vue/test-utils'
config.global.stubs = {}
完全なコード#
上記の設定プロセスを経て、エンジニアリングモジュールが構築されました。完全なコードは template-vite で確認できます。