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
.npmrcincluding following.- Place
.npmrcin every application pacakges and monorepo root. engine-strict=truefor all non-library packages including subdirectories.strict-peer-dependencies=truefor root.save-prefix=for application pacakges.
- Place
- Use
commitlintwith'@commitlint/config-conventional'. - Use
eslnitwith'@luma-dev/base'and correspoing ones.- Avoid using
eslint-disabledirectives.
- Avoid using
- Use
prettierwith"@luma-dev/prettier-config".- File types except JavaScript and TypeScript, run
prettierby itself.
- File types except JavaScript and TypeScript, run
- Never use
enginesinpackage.jsonandengine-strcit=truefor library projects.- It causes errors when used by other package managers even if used as dependency.
- Use
jestfor testing framework. - Place ignore files (
.gitignore,.eslintignore,.dockerignore) only in root if possible.- Distributed ignore files are troublesome to maintain.
.gitignorecan 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
.gitignoreshould 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.jsonif possible. - Write
"type": "commonjs"explicitly. - Use ESModule rather than CommonJS in setting files.
- Use
.jsinstead of.mjsif"type": "module"set in manifest. - Follow Airbnb JavaScript Style Guide preceded by
@luma-dev/prettier-config.
- Use
~4.0style 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',
],
}],[](https://github.com/luma-dev/luma-style-guide#readme)You can find the real examples by searching topics/luma-style.