diff --git a/.circleci/config.yml b/.circleci/config.yml
index 6a3153a526..b37e488d24 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -54,6 +54,8 @@ jobs:
- wagtail
- run: npm run lint:js
- run: npm run lint:css
+ # TODO Remove || true and enforce a successful exit code.
+ - run: npm run lint:format || true
- run: npm run test:unit:coverage -- --runInBand
- run: bash <(curl -s https://codecov.io/bash) -F frontend
diff --git a/.editorconfig b/.editorconfig
index 7c804220c2..1b06b5e1fe 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -4,17 +4,18 @@ root = true
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
-
-[*.{css,js,json,py,yml,rst,md}]
indent_style = space
+[Makefile]
+indent_style = tab
+
[*.{js,py}]
charset = utf-8
-[*.{css,py,scss,rst,md}]
+[*.{py,html,rst,md}]
indent_size = 4
-[*.{js,json,yml,rst}]
+[*.{js,ts,tsx,json,yml,yaml,css,scss}]
indent_size = 2
[*.md]
diff --git a/.eslintignore b/.eslintignore
index 5bd3074d0a..68f29c5323 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -15,4 +15,3 @@ wagtail/users/static
wagtail/contrib/*/static
wagtail/admin/templates/wagtailadmin/edit_handlers/inline_panel.js
wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js
-wagtail/users/templates/wagtailusers/groups/includes/page_permissions_formset.js
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 0000000000..6a2b8357f8
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,8 @@
+# git-blame ignored revisions
+# To configure, run
+# git config blame.ignoreRevsFile .git-blame-ignore-revs
+# Requires Git > 2.23
+# See https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revs-fileltfilegt
+
+# Initial Prettier reformatting
+# TODO
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index bdd79d9a1f..6b6c94a297 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,3 +1,5 @@
+default_language_version:
+ node: system
repos:
- repo: https://github.com/timothycrosley/isort
# isort config is in setup.cfg
@@ -11,3 +13,8 @@ repos:
hooks:
- id: flake8
language_version: python3
+ - repo: https://github.com/pre-commit/mirrors-prettier
+ rev: v2.5.1
+ hooks:
+ - id: prettier
+ types_or: [css, scss, javascript, ts, tsx, json, yaml]
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000000..4e5cb78eea
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,15 @@
+# Irrelevant files ignored for performance reasons.
+node_modules
+*.min.js
+**/lib/
+public/
+coverage/
+**/vendor/
+static
+_build
+# File types which Prettier supports but we don’t want auto-formatting.
+*.md
+# Files which contain incompatible syntax.
+*.html
+wagtail/admin/templates/wagtailadmin/edit_handlers/inline_panel.js
+wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js
diff --git a/Makefile b/Makefile
index 55c7a42c2c..0f92b6559a 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,7 @@ lint:
jinjalint --parse-only wagtail | grep -v 'welcome_page.html:6:70' | tee /dev/tty | wc -l | grep -q '0'
npm run lint:css --silent
npm run lint:js --silent
+ npm run lint:format --silent
doc8 docs
test:
diff --git a/docs/contributing/css_guidelines.rst b/docs/contributing/css_guidelines.rst
index b31a5c4e58..124a3d1443 100644
--- a/docs/contributing/css_guidelines.rst
+++ b/docs/contributing/css_guidelines.rst
@@ -6,7 +6,8 @@ Our CSS is written in `Sass `_, using the SCSS syntax.
Linting and formatting SCSS
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Wagtail uses the `stylelint `_ linter.
+Wagtail uses `stylelint `_ for linting,
+and `Prettier `_ for formatting.
You'll need Node.js and npm on your development machine.
Ensure project dependencies are installed by running ``npm install --no-save``
@@ -26,7 +27,13 @@ below, plus a little more.
Formatting code
---------------
-If you want to autofix errors, you can run that command directly with:
+For Prettier auto-formatting, run:
+
+.. code-block:: console
+
+ $ npm run format
+
+If you want to autofix linting errors:
.. code-block:: console
diff --git a/docs/contributing/javascript_guidelines.rst b/docs/contributing/javascript_guidelines.rst
index b83457d79c..ae30f1a524 100644
--- a/docs/contributing/javascript_guidelines.rst
+++ b/docs/contributing/javascript_guidelines.rst
@@ -3,8 +3,7 @@ JavaScript coding guidelines
Write JavaScript according to the `Airbnb Styleguide `_, with some exceptions:
-- Use soft-tabs with a two space indent. Spaces are the only way to
- guarantee code renders the same in any person's environment.
+- Use `Prettier `_ for all formatting considerations.
- We accept ``snake_case`` in object properties, such as
``ajaxResponse.page_title``, however camelCase or UPPER_CASE should be used
everywhere else.
@@ -13,9 +12,9 @@ Write JavaScript according to the `Airbnb Styleguide `_ linter to help check your code meets the
-styleguide. You'll need node.js and npm on your development machine.
-Ensure project dependencies are installed by running ``npm install --no-save``
+Wagtail uses `ESLint `_ and `Prettier `_.
+You'll need Node and npm on your development machine.
+Ensure project dependencies are installed by running ``npm install --no-save``.
Linting code
------------
@@ -34,6 +33,14 @@ excluded from the linter.
Formatting code
---------------
+For Prettier auto-formatting, run:
+
+.. code-block:: console
+
+ $ npm run format
+
+If you want to autofix linting errors:
+
.. code-block:: console
$ npm run lint:js -- --fix
diff --git a/package-lock.json b/package-lock.json
index cd6383f5e9..a6eaf0d3ad 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -59,6 +59,7 @@
"mini-css-extract-plugin": "^2.4.5",
"postcss": "^8.4.5",
"postcss-loader": "^6.2.1",
+ "prettier": "^2.5.1",
"react-axe": "^3.5.4",
"react-test-renderer": "^16.14.0",
"redux-mock-store": "^1.3.0",
@@ -6690,6 +6691,18 @@
"url": "https://opencollective.com/core-js"
}
},
+ "node_modules/@storybook/csf-tools/node_modules/prettier": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz",
+ "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/@storybook/manager-webpack4": {
"version": "6.4.17",
"resolved": "https://registry.npmjs.org/@storybook/manager-webpack4/-/manager-webpack4-6.4.17.tgz",
@@ -23358,9 +23371,9 @@
}
},
"node_modules/prettier": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz",
- "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==",
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
+ "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
@@ -34202,6 +34215,12 @@
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz",
"integrity": "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==",
"dev": true
+ },
+ "prettier": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz",
+ "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==",
+ "dev": true
}
}
},
@@ -47168,9 +47187,9 @@
"dev": true
},
"prettier": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz",
- "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==",
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
+ "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
"dev": true
},
"pretty-error": {
diff --git a/package.json b/package.json
index d7cbd6653e..21efde8d37 100644
--- a/package.json
+++ b/package.json
@@ -75,6 +75,7 @@
"mini-css-extract-plugin": "^2.4.5",
"postcss": "^8.4.5",
"postcss-loader": "^6.2.1",
+ "prettier": "^2.5.1",
"react-axe": "^3.5.4",
"react-test-renderer": "^16.14.0",
"redux-mock-store": "^1.3.0",
@@ -116,9 +117,11 @@
"start": "webpack --config ./client/webpack.config.js --mode development --progress --watch",
"build": "webpack --config ./client/webpack.config.js --mode production",
"fix:js": "eslint --ext .js,.ts,.tsx --fix ./",
+ "format": "prettier --write '**/?(.)*.{css,scss,js,ts,tsx,json,yaml,yml}'",
"lint:js": "eslint --ext .js,.ts,.tsx --report-unused-disable-directives --max-warnings 16 ./client",
"lint:css": "stylelint **/*.scss",
- "lint": "npm run lint:js && npm run lint:css",
+ "lint:format": "prettier --check '**/?(.)*.{css,scss,js,ts,tsx,json,yaml,yml}'",
+ "lint": "npm run lint:js && npm run lint:css && npm run lint:format",
"test": "npm run test:unit",
"test:unit": "jest",
"test:unit:watch": "jest --watch",
diff --git a/prettier.config.js b/prettier.config.js
new file mode 100644
index 0000000000..1b349d1990
--- /dev/null
+++ b/prettier.config.js
@@ -0,0 +1,18 @@
+/**
+ * See https://prettier.io/docs/en/options.html.
+ */
+module.exports = {
+ arrowParens: 'always',
+ bracketSameLine: false,
+ bracketSpacing: true,
+ embeddedLanguageFormatting: 'auto',
+ endOfLine: 'lf',
+ htmlWhitespaceSensitivity: 'css',
+ jsxSingleQuote: false,
+ printWidth: 80,
+ proseWrap: 'preserve',
+ quoteProps: 'consistent',
+ semi: true,
+ singleQuote: true,
+ trailingComma: 'all',
+};