Skip to main content
Liem Huynh
Backend Developer
View all authors

Code Convention Setup

· 6 min read
Liem Huynh
Backend Developer

1. Package Dependencies

First, install all necessary dependencies:

# Development dependencies
npm install --save-dev \
@typescript-eslint/eslint-plugin \
@typescript-eslint/parser \
eslint \
eslint-config-prettier \
eslint-plugin-prettier \
eslint-plugin-import \
eslint-plugin-simple-import-sort \
prettier \
husky \
lint-staged \
@commitlint/cli \
@commitlint/config-conventional \
commitizen \
cz-conventional-changelog

# Initialize husky
npx husky-init

2. Enhanced .eslintrc.js

module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: [
'@typescript-eslint/eslint-plugin',
'prettier',
'import',
'simple-import-sort',
],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:prettier/recommended',
'plugin:import/recommended',
'plugin:import/typescript',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js', 'dist/**/*', 'node_modules/**/*'],
rules: {
// Prettier
'prettier/prettier': [
'error',
{
endOfLine: 'auto',
},
],

// Import sorting
'simple-import-sort/imports': [
'error',
{
groups: [
// Side effect imports
['^\\u0000'],
// Node.js builtins
['^node:'],
// External packages
['^@?\\w'],
// NestJS specific imports
['^@nestjs/'],
// Internal packages
['^(@|@company|@app)(/.*|$)'],
// Parent imports
['^\\.\\.(?!/?$)', '^\\.\\./?$'],
// Other relative imports
['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
// Type imports
['^.+\\u0000$'],
],
},
],
'simple-import-sort/exports': 'error',

// Import rules
'import/first': 'error',
'import/newline-after-import': 'error',
'import/no-duplicates': 'error',
'import/no-unresolved': 'error',

// TypeScript specific rules
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],

// NestJS specific conventions
'@typescript-eslint/no-unsafe-assignment': 'warn',
'@typescript-eslint/no-unsafe-member-access': 'warn',
'@typescript-eslint/no-unsafe-call': 'warn',
'@typescript-eslint/no-unsafe-return': 'warn',
'@typescript-eslint/no-unsafe-argument': 'warn',

// Code quality
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/require-await': 'error',

// Naming conventions
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'default',
format: ['camelCase'],
},
{
selector: 'variable',
format: ['camelCase', 'UPPER_CASE'],
},
{
selector: 'parameter',
format: ['camelCase'],
leadingUnderscore: 'allow',
},
{
selector: 'memberLike',
format: ['camelCase'],
},
{
selector: 'typeLike',
format: ['PascalCase'],
},
{
selector: 'class',
format: ['PascalCase'],
},
{
selector: 'interface',
format: ['PascalCase'],
},
{
selector: 'enum',
format: ['PascalCase'],
},
{
selector: 'enumMember',
format: ['UPPER_CASE'],
},
],

// General best practices
'no-console': 'warn',
'no-debugger': 'error',
'no-duplicate-imports': 'error',
'no-unused-expressions': 'error',
'prefer-const': 'error',
'no-var': 'error',
},
settings: {
'import/resolver': {
typescript: {
alwaysTryTypes: true,
project: './tsconfig.json',
},
},
},
};

3. Enhanced .prettierrc

{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "auto"
}

4. .prettierignore

# Dependencies
node_modules/

# Build outputs
dist/
build/

# Environment files
.env
.env.local
.env.*.local

# Logs
*.log

# Coverage
coverage/

# IDE
.vscode/
.idea/

# OS
.DS_Store
Thumbs.db

# Generated files
*.generated.ts

5. Commitlint Configuration

Create commitlint.config.js:

module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feat', // New feature
'fix', // Bug fix
'docs', // Documentation
'style', // Code style changes
'refactor', // Code refactoring
'perf', // Performance improvements
'test', // Testing
'chore', // Maintenance
'ci', // CI/CD
'build', // Build system
'revert', // Revert changes
],
],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'scope-empty': [2, 'never'],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [2, 'always', 'lower-case'],
'subject-empty': [2, 'never'],
'subject-full-stop': [2, 'never', '.'],
'header-max-length': [2, 'always', 72],
'body-max-line-length': [2, 'always', 100],
},
};

6. Husky Configuration

Create .husky/pre-commit:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# Run lint-staged
npx lint-staged

Create .husky/commit-msg:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# Run commitlint
npx --no-install commitlint --edit "$1"

Create .husky/pre-push:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# Run tests before push
npm run test
npm run build

7. Lint-staged Configuration

Create .lintstagedrc.js:

export default {
'*.{ts,js}': [
'eslint --fix',
'prettier --write',
],
'*.{json,md,yml,yaml}': [
'prettier --write',
],
};

8. EditorConfig

Create .editorconfig:

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.{yml,yaml}]
indent_size = 2

[*.json]
indent_size = 2

9. VSCode Settings

Create .vscode/settings.json:

{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": true
},
"eslint.validate": [
"javascript",
"typescript"
],
"typescript.preferences.importModuleSpecifier": "relative",
"typescript.suggest.autoImports": true,
"files.exclude": {
"node_modules": true,
"dist": true,
"coverage": true
}
}

Create .vscode/extensions.json:

{
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ms-vscode.vscode-typescript-next",
"editorconfig.editorconfig"
]
}

10. Package.json Scripts

Add these scripts to your package.json:

{
"scripts": {
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"lint:check": "eslint \"{src,apps,libs,test}/**/*.ts\"",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
"prepare": "husky install",
"commit": "git-cz",
"precommit": "lint-staged",
"type-check": "tsc --noEmit"
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
}
}

11. TypeScript Configuration Enhancement

Update your tsconfig.json:

{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": true,
"noImplicitAny": true,
"strictBindCallApply": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"paths": {
"@/*": ["src/*"],
"@app/*": ["src/app/*"],
"@modules/*": ["src/modules/*"],
"@shared/*": ["src/shared/*"],
"@config/*": ["src/config/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test"]
}

12. Git Hooks Setup Commands

Run these commands to set up everything:

# Install dependencies
npm install

# Initialize husky
npx husky-init

# Make hooks executable
chmod +x .husky/pre-commit
chmod +x .husky/commit-msg
chmod +x .husky/pre-push

# Test the setup
npm run lint
npm run format
npm run type-check

13. Usage Examples

Committing Code

# Stage your changes
git add .

# Use commitizen for standardized commits
npm run commit

# Or use git directly with proper format
git commit -m "feat(auth): add JWT token validation"

Commit Message Format

<type>(<scope>): <subject>

<body>

<footer>

Examples:

  • feat(auth): add JWT authentication middleware
  • fix(user): resolve user registration validation issue
  • docs(readme): update installation instructions
  • refactor(database): optimize query performance

Pre-commit Checks

The pre-commit hook will automatically:

  • Run ESLint and fix issues
  • Format code with Prettier
  • Check TypeScript compilation
  • Run tests (if configured)

14. Troubleshooting

Common Issues:

  1. Husky hooks not running: Ensure hooks are executable with chmod +x .husky/*
  2. ESLint errors: Run npm run lint to see and fix issues
  3. Prettier conflicts: Ensure ESLint and Prettier configs are compatible
  4. TypeScript errors: Run npm run type-check to see compilation issues

Bypassing Hooks (Emergency):

# Skip pre-commit hook
git commit --no-verify -m "emergency fix"

# Skip pre-push hook
git push --no-verify

This setup provides a complete, production-ready code convention system for your NestJS project with automated formatting, linting, and commit message validation.

[Meko Trading] Phòng Ban

· 2 min read
Liem Huynh
Backend Developer

Tính năng Phòng ban cho phép quản lý tập trung các yêu cầu và thông tin liên quan đến từng phòng ban trong công ty.

1. Lịch nghỉ phép

  • Xem và quản lý danh sách yêu cầu nghỉ phép của thành viên trong phòng ban do bạn quản lý.
  • Duyệt hoặc từ chối yêu cầu nghỉ phép.

  • Duyệt nghỉ phép: Yêu cầu nghỉ phép sẽ được xác nhận bởi trưởng phòng.

  • Từ chối: Yêu cầu nghỉ phép sẽ bị từ chối.

2. Nhân viên

  • Quản lý danh sách thành viên thuộc phòng ban của bạn.

3. Chi hằng ngày

  • Quản lý danh sách yêu cầu chi tiêu hằng ngày của các thành viên trong phòng ban.
  • Duyệt hoặc từ chối yêu cầu chi.

Tạo phiếu chi

Chi đơn hàng

  • Chọn đơn hàng cần chi
  • Chọn phòng ban phụ trách
  • Nhập chi phí đơn hàng
  • Xác nhận và Lưu

Chi khác

  • Chọn phòng ban phụ trách
  • Nhập diễn giải và chi phí
  • Xác nhận và Lưu

Phiếu chi sau khi tạo sẽ được duyệt theo quyền hiện tại của người tạo

4. Quản lý phòng ban

  • Quản lý danh sách các phòng ban trong công ty.
  • Thêm, chỉnh sửa hoặc xóa thành viên trong từng phòng ban.

Thêm phòng ban

  • Nhập tên, mã, mô tả phòng ban
  • Chọn danh sách thành viên
  • Chọn danh sách quản lý
  • Xác nhận thêm phòng ban

Chỉnh sửa phòng ban

  • Nhập thông tin cần chỉnh sửa
  • Xác nhận chỉnh sửa phòng ban

Lưu ý: Không thể di dời các thành viên có phòng ban chính là phòng ban hiện tại, cần quyền chỉnh sửa người dùng để chỉnh sửa thông tin người dùng

Welcome

· One min read
Liem Huynh
Backend Developer

Welcome to the blog section! This section covers technical and company updates, articles, and tutorials. Here, you'll find valuable insights and information to help you stay informed and enhance your skills.

What You Will Find

  • Technical Updates: Learn about the latest developments and changes in our technology stack.
  • Company News: Stay updated with announcements and news related to the company.
  • Articles and Tutorials: Explore informative articles and step-by-step tutorials to help you improve your knowledge and skills.

We encourage you to engage with the content and share your thoughts in the comments. Happy reading!