Merge pull request #679 from akellbl4/frontend-scripts

Frontend scripts and docs updates
This commit is contained in:
Umputun
2020-04-13 16:49:02 -05:00
committed by GitHub
13 changed files with 147 additions and 83 deletions
+3 -9
View File
@@ -17,18 +17,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- run: npm ci
- run: npm ci --loglevel warn
working-directory: ./frontend
- run: npx run-p check lint lint:style test
working-directory: ./frontend
- run: npm run size
working-directory: ./frontend
- run: npm run check:translation
- run: npx run-p check lint
working-directory: ./frontend
+2 -2
View File
@@ -40,7 +40,7 @@ ENV HUSKY_SKIP_INSTALL=true
RUN apk add --no-cache --update git
ADD frontend/package.json /srv/frontend/package.json
ADD frontend/package-lock.json /srv/frontend/package-lock.json
RUN cd /srv/frontend && CI=true npm ci
RUN cd /srv/frontend && CI=true npm ci --loglevel warn
FROM node:10.11-alpine as build-frontend
@@ -51,7 +51,7 @@ ARG NODE_ENV=production
COPY --from=build-frontend-deps /srv/frontend/node_modules /srv/frontend/node_modules
ADD frontend /srv/frontend
RUN cd /srv/frontend && \
if [ -z "$SKIP_FRONTEND_TEST" ] ; then npx run-p check lint lint:style test build ; \
if [ -z "$SKIP_FRONTEND_TEST" ] ; then npx run-p lint test check; \
else echo "skip frontend tests and lint" ; npm run build ; fi && \
rm -rf ./node_modules
+13 -4
View File
@@ -587,6 +587,10 @@ It stars backend service with embedded bolt store on port `8080` with basic auth
### Frontend development
#### Developer guide
Frontend guide can be found here: [./frontend/Readme.md](./frontend/Readme.md)
#### Build
You should have at least 2GB RAM or swap enabled for building
@@ -597,7 +601,7 @@ You should have at least 2GB RAM or swap enabled for building
* result files will be saved in `./frontend/public`.
**Note** Running `npm install` will set up precommit hooks into your git repository.
It used to reformat your frontend code using `prettier` and lint with `eslint` before every commit.
It used to reformat your frontend code using `prettier` and lint with `eslint` and `stylelint` before every commit.
#### Devserver
@@ -612,12 +616,17 @@ You can attach to locally running backend by providing `REMARK_URL` environment
npx cross-env REMARK_URL=http://127.0.0.1:8080 npm start
```
The best way for start local developer enviroment:
```sh
cp compose-dev-frontend.yml compose-private-frontend.yml
docker-compose -f compose-private-frontend.yml up --build
cd frontend
npm run dev
```
Developer build running by `webpack-dev-server` supports devtools for [React](https://github.com/facebook/react-devtools) and
[Redux](https://github.com/zalmoxisus/redux-devtools-extension).
#### Frontend guide
Frontend guide can be found here: [./frontend/Readme.md](./frontend/Readme.md)
## API
+2 -2
View File
@@ -28,7 +28,7 @@ pull the latest changes from the upstream master branch. It could be done like t
1. add new locale with [two-letter code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
of the language you want to make the translation into to list in
[frontend/tasks/supportedLocales.json](https://github.com/umputun/remark42/blob/master/frontend/tasks/supportedLocales.json)
1. run `npm run generate-langs` in `frontend` folder
1. run `npm run translation:generate` in `frontend` folder
1. translate all values in the newly created json file in
[frontend/app/locales/](https://github.com/umputun/remark42/blob/master/frontend/app/locales/)
1. commit all changes above in your fork
@@ -46,4 +46,4 @@ of the language you want to make the translation into to list in
and make sure that your translation looks as you expect it to look
1. make a screenshot from [http://127.0.0.1:8080](http://127.0.0.1:8080) with your translation in place
1. after all previous steps are done, create a [Pull Request](https://github.com/umputun/remark42/pulls) to umputun/remark42
repo with your changes, attaching a screenshot or two from your local test instance to it
repo with your changes, attaching a screenshot or two from your local test instance to it
+1
View File
@@ -6,3 +6,4 @@ public
!.lintstagedrc.js
!.stylelintrc.js
!.size-limit.js
!.huskyrc.js
+7
View File
@@ -0,0 +1,7 @@
module.exports = {
hooks: {
'pre-commit': 'lint-staged',
'post-commit': 'git update-index --again',
'pre-push': 'run-s check test',
},
};
+1 -1
View File
@@ -1,5 +1,5 @@
module.exports = {
'./**/*.{ts,tsx,js,jsx}': [`eslint --fix --max-warnings=0`, `git add`],
'./**/*.{ts,tsx,js,jsx}': ['eslint --fix --max-warnings=0', 'prettier --write', 'git add'],
'./**/*.{scss,pcss,css}': ['prettier --write', 'stylelint', 'git add'],
'./iframe.html': ['prettier --write', 'stylelint', 'git add'],
};
+1
View File
@@ -1 +1,2 @@
node_modules
public
-17
View File
@@ -1,17 +0,0 @@
{
"printWidth": 120,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "avoid",
"overrides": [
{
"files": ["*.ejs", "*.html"],
"options": {
"trailingComma": "none"
}
}
]
}
+17
View File
@@ -0,0 +1,17 @@
module.exports = {
printWidth: 120,
useTabs: false,
semi: true,
singleQuote: true,
trailingComma: 'es5',
bracketSpacing: true,
arrowParens: 'avoid',
overrides: [
{
files: ['*.ejs', '*.html'],
options: {
trailingComma: 'none',
},
},
],
};
+8 -8
View File
@@ -3,22 +3,22 @@
### Code Style
- project uses typescript to statically analyze code
- project uses `eslint` to check frontend code. You can manually run via `npm run lint`.
- project uses `eslint` and `stylelint` to check frontend code. You can manually run via `npm run lint`.
- git hooks (via husky) installed automatically on `npm install` and check and try to fix code style if possible, otherwise commit will be rejected
- if you want IDE integration, you need `eslint` plugin to be installed.
- if you want IDE integration, you need `eslint` and `stylelint` plugin to be installed.
### CSS Styles
- although styles have `scss` extension, it is actually pack of post-css plugins, so syntax differs, for example in `calc` function.
- component styles use BEM notation (at least it should): `block__element_modifier`. Also there are `mix` classes: `block_modifier`.
- component base style resides in the component's root directory with name of component converted to kebab-case. For example `ListComments` style is located in `./app/components/list-comments/list-comments/scss`
- component's element style resides in its own subdirectory, with name consisting of full elements selector, for example `ListComments` `item` element is placed in `__item` directory under name `./list-comments__item.scss`
- each style should be `require`d in `index.ts` of component's root directory
- now we are migrating to css-modules and this is recomended way to stylization. A file with styles should be named like `component.module.css`
- old component styles use BEM notation (at least it should): `block__element_modifier`. Also there are `mix` classes: `block_modifier`.
- new way to naming CSS selectors is camel-case like `blockElemenModifier` and use `classnames` to combine it
- component base style resides in the component's root directory with name of component converted to kebab-case. For example `ListComments` style is located in `./app/components/list-comments/list-component.tsx`
- any other files should be named also in kebab-case. For example `./app/utils/get-param.ts`
### Imports
- imports for typescript, javascript files should be without extension: `./index`, not `./index.ts`
- if file resides in same directory or in subdirectory import should be relative: `./types/something`
- if file resides in the same directory or in subdirectory import should be relative: `./types/something`
- otherwise it should start from `@app` namespace: `@app/common/store` which mapped to `/app/common/store.ts` in webpack, tsconfig and jest
### Testing
+53 -2
View File
@@ -5840,6 +5840,58 @@
"sha.js": "^2.4.8"
}
},
"cross-env": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz",
"integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==",
"dev": true,
"requires": {
"cross-spawn": "^7.0.1"
},
"dependencies": {
"cross-spawn": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
"integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
}
}
},
"cross-fetch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.4.tgz",
@@ -22599,8 +22651,7 @@
"whatwg-fetch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==",
"dev": true
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
},
"whatwg-mimetype": {
"version": "2.3.0",
+39 -38
View File
@@ -3,25 +3,48 @@
"version": "0.1.0",
"license": "MIT",
"scripts": {
"build": "webpack --mode production && es-check es5 './public/*.js'",
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development",
"check": "tsc -p tsconfig.typecheck.json --noEmit --skipLibCheck",
"check:translation": "npm run extract-messages && node ./tasks/checkTranslation.js",
"lint": "eslint --max-warnings=0 --ext=.ts,.tsx,.js,.jsx .",
"lint:style": "stylelint '**/*.scss' '**/*.pcss' '**/*.css' 'iframe.html'",
"dev": "cross-env REMARK_URL=http://127.0.0.1:8080 npm start",
"test": "jest",
"test:coverage": "jest --coverage",
"check": "cross-env NODE_ENV=production npm run build && run-p check:*",
"check:types": "tsc -p tsconfig.typecheck.json --noEmit --skipLibCheck",
"check:translation": "run-s translation:extract translation:check",
"check:size": "size-limit",
"check:es": "es-check es5 './public/*.js'",
"lint": "run-p lint:*",
"lint:eslint": "eslint --max-warnings=0 --ext=.ts,.tsx,.js,.jsx .",
"lint:stylelint": "stylelint '**/*.scss' '**/*.pcss' '**/*.css' 'iframe.html'",
"size": "cross-env NODE_ENV=production run-s build check:size",
"es-check": "cross-env NODE_ENV=production run-s build check:es",
"prettier": "prettier --write './**/*.{js,jsx,ts,tsx,scss}'",
"extract-messages": "formatjs extract --out-file=./extracted-messages/messages.json './app/**/*.{js,jsx,ts,tsx}'",
"generate-langs": "npm run extract-messages && node ./tasks/generateDictionary.js",
"size": "NODE_ENV=production npm run build && size-limit"
"translation:extract": "formatjs extract --out-file=./extracted-messages/messages.json './app/**/*.{js,jsx,ts,tsx}'",
"translation:generate": "node ./tasks/generateDictionary.js",
"translation:check": "node ./tasks/checkTranslation.js"
},
"husky": {
"hooks": {
"pre-commit": "./node_modules/.bin/lint-staged",
"post-commit": "git update-index --again",
"pre-push": "npm run check && npm test"
}
"engines": {
"node": ">=12.11",
"npm": ">=6.13.4"
},
"dependencies": {
"@github/markdown-toolbar-element": "^1.2.0",
"@github/text-expander-element": "^1.0.2",
"@webcomponents/custom-elements": "^1.4.1",
"bem-react-helper": "^1.1.2",
"classnames": "^2.2.6",
"core-js": "^3.6.5",
"es6-promise": "^4.2.8",
"focus-visible": "^5.1.0",
"intersection-observer": "^0.7.0",
"lodash-es": "^4.17.15",
"node-emoji": "^1.10.0",
"preact": "^10.4.0",
"react-intl": "^3.12.0",
"react-redux": "^7.1.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"whatwg-fetch": "^3.0.0"
},
"devDependencies": {
"@babel/core": "^7.6.4",
@@ -51,6 +74,7 @@
"babel-loader": "^8.0.6",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^5.1.1",
"cross-env": "^7.0.2",
"css-loader": "^3.2.0",
"document-register-element": "^1.14.3",
"dotenv": "^8.2.0",
@@ -100,29 +124,6 @@
"webpack": "^4.41.2",
"webpack-bundle-analyzer": "^3.6.1",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.9.0",
"whatwg-fetch": "^3.0.0"
},
"dependencies": {
"@github/markdown-toolbar-element": "^1.2.0",
"@github/text-expander-element": "^1.0.2",
"@webcomponents/custom-elements": "^1.4.1",
"bem-react-helper": "^1.1.2",
"classnames": "^2.2.6",
"core-js": "^3.6.5",
"es6-promise": "^4.2.8",
"focus-visible": "^5.1.0",
"intersection-observer": "^0.7.0",
"lodash-es": "^4.17.15",
"node-emoji": "^1.10.0",
"preact": "^10.4.0",
"react-intl": "^3.12.0",
"react-redux": "^7.1.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0"
},
"engines": {
"node": ">=12.11",
"npm": ">=6.13.4"
"webpack-dev-server": "^3.9.0"
}
}