Alexander Vassbotn Røyne-Helgesen PRO
Lover of life, technologist at heart
*
*
Alexander Vassbotn Røyne-Helgesen
Principal Engineer
ex-Vikinghorde
Hockey dad
Not a fan of Oilers
Alexander Vassbotn Røyne-Helgesen
Principal Engineer
Hockey dad
$ npm i @phun-ky/speccer
The importance of standards
The importance of standards
The importance of standards
Semantic Versioning (SemVer) consists of three numbers: MAJOR, MINOR, and PATCH. Each number is incremented in different circumstances:
The importance of standards
9.2.10
-alpha
+3284aea4
MAJOR
MINOR
PATCH
prerelease
build
⎧
⎨
⎩
⎪
⎪
version core
optional
⎩
⎪
⎪
⎪
⎪
⎨
⎪
⎪
⎪
⎪
⎪
⎧
⎪
The importance of standards
YEAR
MONTH
BUILD
status
2024.12.4081
-alpha
version core
⎩
⎪
⎨
⎪
⎧
⎪
⎪
⎪
⎪
⎪
optional
⎩
⎪
⎨
⎪
⎧
The importance of standards
Using SemVer helps a great deal to understand what has changed, since the changed number reflects what the actual change consists of.
The importance of standards
The importance of standards
$ git commit -am "Added feature ... (past tense)"
$ git commit -am "clarify further the brokenness of C++. why the fuck are we using C++?"
The importance of standards
$ git commit -am "Add feature to alert admin for new user registration"
$ git commit -am "Elaborate on the inherent deficiencies of the C++ programming language"
The importance of standards
$ git commit -am "Add feature to alert admin for new user registration"
$ git commit -am "Elaborate on the inherent deficiencies of the C++ programming language"
The importance of standards
The reason behind using present tense is that the commit message is answering the question "What will happen after the commit is applied?".
If we think of a commit as an independent patch, it does not matter if it applied in the past. What matters is that this patch is always supposed to make that particular change when it is applied.
The importance of standards
Commitizen … uses a standard way of committing rules and from that foundation, it can bump version, create changelog, and update files.
The importance of standards
$ git log --pretty=format:'%h %s'.
3332279 style: 💄 Lint.
60f0ec8 fix: 🐛 Fix sticky header issues.
9f5fdcd feat: 🎸 Add read time.
55bf3ad feat: 🎸 Add copy code button and language string to code blocks.
813df4a refactor: 💡 Some adjustments.
79549ab refactor: 💡 Adjust code blocks.
6876cec fix: 🐛 Add label attribute to heading link.
8bf68c6 refactor: 💡 Comment out copy / language feat for prism.
9f97ebf feat: 🎸 Make header sticky in desktop mode.
95ceac0 style: 💄 Tune lint rules for markdown.
d7c3a13 feat: 🎸 Add `print.css`.
// In your project root
$ sudo npm install -g commitizen git-cz && commitizen init git-cz
{
…
"scripts": {
…
"commit": "npx git-cz",
…
},
…
}
$ git log
commit 8f82e8189e614332b6c80d2ab8291aa59325b130 (HEAD -> main)
Author: Alexander Vassbotn Røyne-Helgesen <alexander+github.com@phun-ky.net>
Date: Fri Jan 5 15:11:19 2024 +0100
style: 💄 lint `src/styles/index.styl`
For funsies
✅ Closes: #123
The importance of standards
The importance of standards
… when the concept arrived it was one of the biggest features for me as a dev.
It made the code feel cleaner
The importance of standards
{
"singleQuote": true,
"jsxBracketSameLine": true,
"tabWidth": 2,
"printWidth": 80,
"proseWrap": "always"
}
{
"singleQuote": true,
"jsxBracketSameLine": true,
"tabWidth": 2,
"printWidth": 80,
"proseWrap": "always"
}
The reason why prettier uses 80 columns to format code is because this is the best heuristic we know. It's not perfect as you have seen but one interesting property is that it almost never looks terrible and most of the time it look reasonable.
The longer the line, the bigger the diff and the harder it is to track what has been chanced
The importance of standards
$ NO_ESLINT=1 npx putout src
src/utils/version.ts
140:42 error Use function to check type instead of 'typeof' types/convert-typeof-to-is-type
265:4 error Use function to check type instead of 'typeof' types/convert-typeof-to-is-type
155:17 error Swap 'instances.length - 1' with 'index' conditions/apply-comparison-order
37:2 error Use consistent blocks conditions/apply-consistent-blocks
45:2 error Use consistent blocks conditions/apply-consistent-blocks
242:2 error Use consistent blocks conditions/apply-consistent-blocks
60:9 error Avoid useless 'else' conditions/remove-useless-else
66:9 error Avoid useless 'else' conditions/remove-useless-else
src/utils/authentication/index.ts
17:19 error Avoid useless 'async' promises/remove-useless-async
src/utils/converters/organisation-to-normalized-dropdown-item-type.ts
16:56 error Avoid useless 'return' remove-useless-return
src/utils/stop-place-icon/index.ts
6:9 error Use optional chaining apply-optional-chaining/use
9:22 error Use optional chaining apply-optional-chaining/use
src/utils/validation/user-profile-schema.ts
32:8 error Use object destructuring apply-destructuring/object
34:8 error Use consistent blocks conditions/apply-consistent-blocks
✖ 168 errors in 18 files
fixable with the `--fix` option
The importance of standards
// Don't do this for content
export const checkForApples = (…): boolean => …;
// Don't do this for boolean returns
export const versionIsExpired = (…): boolean => …;
The importance of standards
// Do this when checking for content
export const hasApples = (…): boolean => …;
// Do this for boolean returns
export const isVersionExpired = (…): boolean => …;
The importance of standards
export const myFunction = (var) => {
if(var){
return [1,2,3,4,5];
} else {
return [];
}
}
The importance of standards
export const myFunction = (var) => {
if(!var) return [];
return [1,2,3,4,5];
}
The importance of standards
The importance of standards
const a = b === null ? false : b === 2 ? false : true;
The importance of standards
let a = false;
if (b === 2) {
a = true;
}
The importance of standards
The importance of standards
export const MyComponent = ({ isCool }) => {
return (
{isCool ? <MyCoolComponent/> : <MyNotSoCoolComponent/>}
)
}
The importance of standards
export const MyComponent = ({ isCool }) => {
if (isCool) return <MyCoolComponent />;
return <MyNotSoCoolComponent />;
};
The importance of standards
The importance of standards
import React from 'react';
import { Button } from '../../../../../../components/actions/Button';
{
"compilerOptions": {
…
"paths": {
"components/*": ["./src/components/*"],
…
}
},
…
}
{
…
alias: {
components: path.resolve(__dirname, 'src/components'),
…
},
…
}
import React from 'react';
import { Button } from 'components/actions/Button';
The importance of standards
{
…
rules: {
'import/order': [
'error',
{
groups: [
'external',
'builtin',
'internal',
'parent',
'sibling',
'index'
],
pathGroups: [
{ pattern: 'components', group: 'internal' },
{ pattern: 'utils', group: 'internal' },
…
],
pathGroupsExcludedImportTypes: ['internal'],
alphabetize: {
order: 'asc',
caseInsensitive: true
},
'newlines-between': 'always'
}
],
}
…
}
The importance of standards
The importance of standards
$ struct
📦 my-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.js
├── 📁 public
└── 📄 package.json
$ struct
📦 my-ts-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-react-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 contexts
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 stores
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 App.tsx
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-express-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 config
│ ├── 📁 lib
│ ├── 📁 middlewares
│ ├── 📁 router
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ └── 📄 index.ts
└── 📄 package.json
$ struct
📦 my-static-html-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ │ ├── 📁 css
│ │ ├── 📁 img
│ │ ├── 📁 js
│ │ ├── 📁 meta
│ │ └── 📁 posts
│ ├── 📁 components
│ ├── 📁 pages
│ ├── 📁 styles
│ ├── 📁 utils
│ └── 📄 main.js
└── 📄 package.json
$ struct
📦 my-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.js
├── 📁 public
└── 📄 package.json
$ struct
📦 my-ts-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-react-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 contexts
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 stores
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 App.tsx
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-express-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 config
│ ├── 📁 lib
│ ├── 📁 middlewares
│ ├── 📁 router
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ └── 📄 index.ts
└── 📄 package.json
$ struct
📦 my-static-html-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ │ ├── 📁 css
│ │ ├── 📁 img
│ │ ├── 📁 js
│ │ ├── 📁 meta
│ │ └── 📁 posts
│ ├── 📁 components
│ ├── 📁 pages
│ ├── 📁 styles
│ ├── 📁 utils
│ └── 📄 main.js
└── 📄 package.json
$ struct
📦 my-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.js
├── 📁 public
└── 📄 package.json
$ struct
📦 my-ts-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-react-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 contexts
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 stores
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 App.tsx
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-express-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 config
│ ├── 📁 lib
│ ├── 📁 middlewares
│ ├── 📁 router
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ └── 📄 index.ts
└── 📄 package.json
$ struct
📦 my-static-html-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ │ ├── 📁 css
│ │ ├── 📁 img
│ │ ├── 📁 js
│ │ ├── 📁 meta
│ │ └── 📁 posts
│ ├── 📁 components
│ ├── 📁 pages
│ ├── 📁 styles
│ ├── 📁 utils
│ └── 📄 main.js
└── 📄 package.json
$ struct
📦 my-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.js
├── 📁 public
└── 📄 package.json
$ struct
📦 my-ts-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-react-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 contexts
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 stores
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 App.tsx
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-express-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 config
│ ├── 📁 lib
│ ├── 📁 middlewares
│ ├── 📁 router
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ └── 📄 index.ts
└── 📄 package.json
$ struct
📦 my-static-html-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ │ ├── 📁 css
│ │ ├── 📁 img
│ │ ├── 📁 js
│ │ ├── 📁 meta
│ │ └── 📁 posts
│ ├── 📁 components
│ ├── 📁 pages
│ ├── 📁 styles
│ ├── 📁 utils
│ └── 📄 main.js
└── 📄 package.json
$ struct
📦 my-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.js
├── 📁 public
└── 📄 package.json
$ struct
📦 my-ts-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-react-frontend
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 components
│ ├── 📁 config
│ ├── 📁 contexts
│ ├── 📁 features
│ ├── 📁 lib
│ ├── 📁 pages
│ ├── 📁 services
│ ├── 📁 styles
│ ├── 📁 stores
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ ├── 📁 …
│ └── 📄 App.tsx
│ └── 📄 main.ts
├── 📁 public
└── 📄 package.json
$ struct
📦 my-express-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ ├── 📁 config
│ ├── 📁 lib
│ ├── 📁 middlewares
│ ├── 📁 router
│ ├── 📁 types
│ ├── 📁 test
│ ├── 📁 utils
│ └── 📄 index.ts
└── 📄 package.json
$ struct
📦 my-static-html-app
├── 📁 scripts
├── 📁 src
│ ├── 📁 assets
│ │ ├── 📁 css
│ │ ├── 📁 img
│ │ ├── 📁 js
│ │ ├── 📁 meta
│ │ └── 📁 posts
│ ├── 📁 components
│ ├── 📁 pages
│ ├── 📁 styles
│ ├── 📁 utils
│ └── 📄 main.js
└── 📄 package.json
The importance of standards
src/components/navigation
src/components/page-section
src/components/form
or src/components/input-elements
src/components/tables
src/components/feedback
The importance of standards
$ struct
📦 my-frontend
├── 📁 src
│ ├── …
│ ├── 📁 components
│ │ ├── 📁 communication
│ │ ├── 📁 content
│ │ ├── 📁 meta
│ │ ├── 📁 navigation
│ │ ├── 📁 page-sections
│ │ └── …
│ └── …
└── …
The importance of standards
module.exports = {
…,
rules: {
…,
'max-lines': ['error',{
max: 50,
skipBlankLines: false
}],
}
};
module.exports = {
…,
rules: {
…,
'max-lines': ['error',{
max: 50,
skipBlankLines: false
}],
}
};
Automate
Automate
Automate
Automate
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
groups:
minor-and-patch:
applies-to: version-updates
update-types:
- "minor"
- "patch"
major-updates:
applies-to: version-updates
update-types:
- "major"
schedule:
interval: "weekly"
open-pull-requests-limit: 2
allow:
- dependency-type: direct
- dependency-type: production
commit-message:
prefix: 'chore: 🤖 '
Automate
name: Publish
on:
pull_request:
types: [closed]
branches: [ "main" ]
paths:
- '.github/**'
- 'src/**'
- 'api/**'
- 'public/**'
- 'package.json'
- 'package-lock.json'
- 'rollup.config.js'
- 'tsconfig.json'
- '.npmrc'
- '.release-it.json'
- 'README.md'
- 'CONTRIBUTING.md'
- 'CODE_OF_CONDUCT.md'
- 'SECURITY.md'
- '.postcssrc.cjs'
- '.browserlistrc'
workflow_dispatch:
jobs:
publish:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Checkout all branches and tags
token: ${{ secrets.GH_TOKEN }}
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: '>=20.11.1'
- name: Install dependencies
run: | # Install and link dependencies
npm i
- name: "Release" # Interesting step
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor}}@users.noreply.github.com"
npm run release
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
notify:
name: Notify failed build
needs: publish
if: failure()
runs-on: ubuntu-latest
steps:
- uses: jayqi/failed-build-issue-action@v1.2
with:
github-token: ${{ secrets.GH_TOKEN }}
name: Checks
on:
pull_request:
branches: [ "main" ]
types: [opened, synchronize]
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: '>=20.11.1'
- name: Install dependencies
run: npm i
- name: Build
run: npm run build
- name: Test
run: npm run test-ci
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4.0.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: phun-ky/speccer
notify:
name: Notify failed check
needs: check
if: failure()
runs-on: ubuntu-latest
steps:
- uses: jayqi/failed-build-issue-action@v1.2
with:
github-token: ${{ secrets.GH_TOKEN }}
name: "Pull Request Labeler"
on:
- pull_request_target
jobs:
labeler:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- id: label-the-PR
uses: actions/labeler@v5
with:
sync-labels: true
'section: workflows':
- any:
- changed-files:
- any-glob-to-any-file:
- .github/workflows/**
'section: repo':
- any:
- changed-files:
- any-glob-to-any-file:
- '*'
'experience: developer':
- any:
- changed-files:
- any-glob-to-any-file:
- '.editorconfig'
- '.eslintignore'
- '.eslintrc.json'
- '.eslintrc.js'
- '.gitignore'
- '.release-it.json'
- '.renovate.json'
- '.npmrc'
- '.prettierrc'
- 'tslint.json'
'context: github':
- any:
- changed-files:
- any-glob-to-any-file:
- .github/**
'context: docker':
- any:
- changed-files:
- any-glob-to-any-file:
- Dockerfile
'context: npm':
- any:
- changed-files:
- any-glob-to-any-file:
- '.npmrc'
'context: rollup':
- any:
- changed-files:
- any-glob-to-any-file:
- 'rollup.config.js'
- 'rollup.config.mjs'
- 'rollup.*.config.js'
- 'rollup.*.config.mjs'
'mindless: docs':
- any:
- head-branch: ['^docs', 'docs']
- changed-files:
- any-glob-to-any-file:
- '**/*.md'
'mindless: dependencies':
- any:
- changed-files:
- any-glob-to-any-file:
- 'package-lock.json'
- 'yarn.lock'
# Add '✨ feature' label to any PR where the head branch name starts with `feat` or has a `feat` section in the name
'✨ feature':
- head-branch: ['^feat', 'feat']
'problems: bug':
- head-branch: ['^fix', 'fix']
'mindless: chore':
- head-branch: ['^chore', 'chore']
'improvements: enhancement':
- head-branch: ['^improvements', 'improvements']
# Add 'release' label to any PR that is opened against the `main` branch
release:
- base-branch: 'main'
$ gh label clone entur/products-models --repo entur/vite-plugin-assets-json
name: Auto Assign
on:
issues:
types: [opened]
pull_request:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: 'Auto-assign issue'
uses: pozil/auto-assign-issue@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
assignees: phun-ky
numOfAssignee: 1
Extrapolate
{
…
"plugins": {
"@release-it/conventional-changelog": {
"header": "# Changelog",
"preset": {
"name": "conventionalcommits",
"types": […]
},
"infile": "CHANGELOG.md"
}
}
}
Extrapolate
$ npm i -D typedoc
$ npm i -D typedoc-plugin-frontmatter typedoc-plugin-markdown typedoc-plugin-mdn-links typedoc-plugin-no-inherit typedoc-plugin-rename-defaults
{
…
"scripts": {
…
"docs:gen": "node ./node_modules/.bin/typedoc --entryPoints src --entryPointStrategy expand --gitRevision main --githubPages false --plugin typedoc-plugin-markdown --tsconfig tsconfig.json --hideInPageTOC --out api --readme none",
…
}
…
}
Additionally, there are other strategies to lessen the environmental impact in development, including:
Minimize
Minimize
Minimize
module.exports = leftpad;
function leftpad (str, len, ch) {
str = String(str);
var i = -1;
if (!ch && ch !== 0) ch = ' ';
len = len - str.length;
while (++i < len) {
str = ch + str;
}
return str;
}
Minimize
Minimize
Minimize
What's next?
By Alexander Vassbotn Røyne-Helgesen
Dive into the nitty-gritty of frontend development with me! In this talk, I'll share 24 years of coding insights, breaking down practical tips for an A+ developer experience. From semantic versioning hacks to commitizen magic, we'll spice up your coding life. Learn the dos and don'ts of naming functions, organizing components, and acing imports. But wait, there's more! Discover the sweet spot of automation using Commitizen, Release-it, and GitHub Actions. Plus, let's talk code minimization—why it matters and how it can make your life easier. Whether you're a coding pro or just getting started, this talk is packed with hands-on advice to level up your frontend game. Join me for a casual chat about cleaner code, smoother workflows, and sustainable coding habits. No fluff, just the good stuff! See you there!