Support shared Prettier configuration (#5963)

* Support external configuration

* Document changes

* Update existing snapshots

* Update existing snapshots (2)

* Fix typo in docs

* Add example config repo
master
Lucas Azzola 2019-03-13 09:34:51 +11:00 committed by GitHub
parent ef48f71b7b
commit f32b289032
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 113 additions and 1 deletions

View File

@ -42,6 +42,35 @@ Examples:
-->
- Config: Support shared configurations ([#5963] by [@azz])
Sharing a Prettier configuration is simple: just publish a module that exports a configuration object, say `@company/prettier-config`, and reference it in your `package.json`:
```json
{
"name": "my-cool-library",
"version": "9000.0.1",
"prettier": "@company/prettier-config"
}
```
If you don't want to use `package.json`, you can use any of the supported extensions to export a string, e.g. `.prettierrc.json`:
```json
"@company/prettier-config"
```
An example configuration repository is available [here](https://github.com/azz/prettier-config).
> Note: This method does **not** offer a way to _extend_ the configuration to overwrite some properties from the shared configuration. If you need to do that, import the file in a `.prettierrc.js` file and export the modifications, e.g:
>
> ```js
> module.exports = {
> ...require("@company/prettier-config"),
> semi: false
> };
> ```
- JavaScript: Add an option to modify when Prettier quotes object properties ([#5934] by [@azz])
**`--quote-props <as-needed|preserve|consistent>`**

View File

@ -91,6 +91,35 @@ overrides:
`files` is required for each override, and may be a string or array of strings. `excludeFiles` may be optionally provided to exclude files for a given rule, and may also be a string or array of strings.
## Sharing configurations
Sharing a Prettier configuration is simple: just publish a module that exports a configuration object, say `@company/prettier-config`, and reference it in your `package.json`:
```json
{
"name": "my-cool-library",
"version": "9000.0.1",
"prettier": "@company/prettier-config"
}
```
If you don't want to use `package.json`, you can use any of the supported extensions to export a string, e.g. `.prettierrc.json`:
```json
"@company/prettier-config"
```
An example configuration repository is available [here](https://github.com/azz/prettier-config).
> Note: This method does **not** offer a way to _extend_ the configuration to overwrite some properties from the shared configuration. If you need to do that, import the file in a `.prettierrc.js` file and export the modifications, e.g:
>
> ```js
> module.exports = {
> ...require("@company/prettier-config"),
> semi: false
> };
> ```
## Setting the [parser](options.md#parser) option
By default, Prettier automatically infers which parser to use based on the input file extension. Combined with `overrides` you can teach Prettier how to parse files it does not recognize.

View File

@ -2,6 +2,7 @@
const thirdParty = require("../common/third-party");
const minimatch = require("minimatch");
const resolve = require("resolve");
const path = require("path");
const mem = require("mem");
@ -13,6 +14,13 @@ const getExplorerMemoized = mem(opts => {
cache: opts.cache,
transform: result => {
if (result && result.config) {
if (typeof result.config === "string") {
const modulePath = resolve.sync(result.config, {
basedir: path.dirname(result.filepath)
});
result.config = eval("require")(modulePath);
}
if (typeof result.config !== "object") {
throw new Error(
`Config is only allowed to be an object, ` +

View File

@ -28,7 +28,7 @@ exports[`throw error for unsupported extension (stdout) 1`] = `""`;
exports[`throw error for unsupported extension (write) 1`] = `Array []`;
exports[`throw error with invalid config format (stderr) 1`] = `
"[error] Invalid configuration file: Config is only allowed to be an object, but received string in \\"<cwd>/tests_integration/cli/config/invalid/file/.prettierrc\\"
"[error] Invalid configuration file: Cannot find module '--invalid--' from '<cwd>/tests_integration/cli/config/invalid/file'
"
`;

View File

@ -23,6 +23,9 @@ function f() {
\\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\"
)
}
console.log(
\\"should have no semi\\"
)
console.log(
\\"jest/__best-tests__/file.js should have semi\\"
);
@ -130,6 +133,7 @@ function f() {
\\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\"
)
}
console.log(\\"should have no semi\\")
console.log(\\"jest/__best-tests__/file.js should have semi\\");
console.log(\\"jest/Component.js should not have semi\\")
console.log(\\"jest/Component.test.js should have semi\\");
@ -192,6 +196,15 @@ function packageTs() {
exports[`resolves configuration from external files and overrides by extname (write) 1`] = `Array []`;
exports[`resolves external configuration from package.json (stderr) 1`] = `""`;
exports[`resolves external configuration from package.json (stdout) 1`] = `
"console.log(\\"should have no semi\\")
"
`;
exports[`resolves external configuration from package.json (write) 1`] = `Array []`;
exports[`resolves json configuration file with --find-config-path file (stderr) 1`] = `""`;
exports[`resolves json configuration file with --find-config-path file (stdout) 1`] = `

View File

@ -102,6 +102,9 @@ function f() {
\\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\"
)
}
console.log(
\\"should have no semi\\"
)
console.log(
\\"jest/__best-tests__/file.js should have semi\\"
);
@ -191,6 +194,9 @@ function f() {
\\"should have space width 2 despite ../.editorconfig specifying 8, because ./.hg is present\\"
)
}
console.log(
\\"should have no semi\\"
)
console.log(
\\"jest/__best-tests__/file.js should have semi\\"
);

View File

@ -25,6 +25,12 @@ describe("accepts configuration from --config", () => {
});
});
describe("resolves external configuration from package.json", () => {
runPrettier("cli/config/", ["external-config/index.js"]).test({
status: 0
});
});
describe("resolves configuration file with --find-config-path file", () => {
runPrettier("cli/config/", ["--find-config-path", "no-config/file.js"]).test({
status: 0
@ -262,3 +268,11 @@ test("API resolveConfig resolves relative path values based on config filepath",
pluginSearchDirs: [path.join(parentDir, "path-to-plugin-search-dir")]
});
});
test("API resolveConfig de-references to an external module", () => {
const currentDir = path.join(__dirname, "../cli/config/external-config");
expect(prettier.resolveConfig.sync(`${currentDir}/index.js`)).toEqual({
printWidth: 77,
semi: false
});
});

View File

@ -0,0 +1 @@
console.log("should have no semi");

View File

@ -0,0 +1,4 @@
{
"printWidth": 77,
"semi": false
}

View File

@ -0,0 +1,5 @@
{
"name": "@company/prettier-config",
"main": "index.json",
"version": "0.0.0"
}

View File

@ -0,0 +1,3 @@
{
"prettier": "@company/prettier-config"
}