Luma coding style guide, specifically for frontend, JavaScript and TypeScript projects.
NOTICE: Are you about to contirubte the projects with this style? If we're in owners of that project, please make PR at first and I will refer to the rules violated in your PR, so it's unnecessary to read this.
pnpm add @luma-dev/eslint-config-base -D
pnpm add @luma-dev/eslint-config-jest -D
pnpm add @luma-dev/eslint-config-next -D
pnpm add @luma-dev/eslint-config-react -D
@luma-dev/eslint-config-unstyle
pnpm add @luma-dev/eslint-config-unstyle -D
pnpm add @luma-dev/prettier-config -D
We define 3 types for npm packages.
- Monorepo Root
- Application
- Library
And root refers to monorepo root if monorepo, otherwise the single directory including the package manifest.
- Use tools as newer as possible.
- Keep consistent, simple and verifiable.
- Use pnpm as a package manager.
- Regard build steps as development step, so dependencies only used in dev and build should in
devDependencies
. - Use TypeScript rather than JavaScript anywhere if possible.
- Use
.npmrc
including following.- Place
.npmrc
in every application pacakges and monorepo root. engine-strict=true
for all non-library packages including subdirectories.strict-peer-dependencies=true
for root.save-prefix=
for application pacakges.
- Place
- Use
commitlint
with'@commitlint/config-conventional'
. - Use
eslnit
with'@luma-dev/base'
and correspoing ones.- Avoid using
eslint-disable
directives.
- Avoid using
- Use
prettier
with"@luma-dev/prettier-config"
.- File types except JavaScript and TypeScript, run
prettier
by itself.
- File types except JavaScript and TypeScript, run
- Never use
engines
inpackage.json
andengine-strcit=true
for library projects.- It causes errors when used by other package managers even if used as dependency.
- Use
jest
for testing framework. - Place ignore files (
.gitignore
,.eslintignore
,.dockerignore
) only in root if possible.- Distributed ignore files are troublesome to maintain.
.gitignore
can include following.- (ignore/a) Files that may be generated by scripts in project.
- e.g.
node_modules/
,dist/
,.pnpm-debug.log
- e.g.
- (ignore/b) Files used for locally controlling behavior only in specific occasion.
*.local
- (ignore/c) Files generally known as generated in some environments following.
.DS_Store
.vscode/
.idea/
- (ignore/a) Files that may be generated by scripts in project.
- Ignore files should suffix iff target may be directory generally, if possible.
- e.g.
node_modules/
(acceptable) vsnode_modules
- e.g.
- Never include trailing spaces.
- Ignore files except
.gitignore
should never include (ignore/b) and (ignore/c).- Build steps should run in reproducable environments like CI or Container.
- Keep top level directory simple, so prefer to pack sources in
src/
directory. - Use
"type": "module"
inpackage.json
if possible. - Write
"type": "commonjs"
explicitly. - Use ESModule rather than CommonJS in setting files.
- Use
.js
instead of.mjs
if"type": "module"
set in manifest. - Follow Airbnb JavaScript Style Guide preceded by
@luma-dev/prettier-config
.
- Use
~4.0
style for TypeScript. - Use
^
+ fully stated version style for libraries. - Use pinned version for applications.
save-prefix=
helps to achieve this.
TBD. Here's draft based on @twada 's tweet.
- WHAT for tests.
- WHY for commit messages.
- HOW for function level code comments (
// ...
or/* ... */
). - WHY NOT for line level code comments.
- Non-code comments (
/** .. */
) are documentation, so write WHAT.
// .eslintrc.cjs
const configureBase = require('@luma-dev/eslint-config-base/configure');
/** @type {import('eslint').Linter.Config} */
module.exports = {
extends: ['@luma-dev/base', '@luma-dev/jest'],
overrides: [...configureBase(__dirname)],
};
; .npmrc
engine-strict=true
strict-peer-dependencies=true
shamefully-hoist=false
save-prefix=
// .prettierrc.json
"@luma-dev/prettier-config"
// .eslintrc.cjs
const configureBase = require('@luma-dev/eslint-config-base/configure');
/** @type {import('eslint').Linter.Config} */
module.exports = {
overrides: [...configureBase(__dirname)],
};
; .npmrc
engine-strict=true
save-prefix=
; .npmrc
save-prefix=^
Version Fixer
// .pnpmfile.cjs
const { esbuild } = require('./package.json').devDependencies;
function readPackage(pkg) {
for (const section of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
if (pkg[section].esbuild) {
pkg[section].esbuild = esbuild;
}
}
return pkg;
}
module.exports = {
hooks: {
readPackage,
},
};
'import/no-unresolved': ['error', {
ignore: [
'monaco-editor',
],
}],
[![Luma Style Guide](https://img.shields.io/badge/styled%20with-luma-%23c5ebeb?style=flat-square)](https://github.com/luma-dev/luma-style-guide#readme)
You can find the real examples by searching topics/luma-style.