Skip to main content

迁移到 16.0.0

¥Migrating to 16.0.0

此版本包含重大或重大更改。

¥This release contains significant or breaking changes.

我们已将源代码迁移到 ECMAScript 模块 (ESM) — 经过一年的努力,允许使用 ESM 插件、自定义语法和格式化程序,并朝着更新纯 ESM 依赖迈出一步。

¥We've migrated our source code to ECMAScript modules (ESM) — a year-long effort to allow ESM plugins, custom syntaxes and formatters, and a step towards updating our pure ESM dependencies.

为了让社区有时间迁移到 ESM,我们将发布一个混合包来支持(现已弃用)CommonJS Node.js API,直到我们的下一个主要版本。

¥To give the community time to migrate to ESM, we'll publish a hybrid package to support the (now deprecated) CommonJS Node.js API until our next major release.

重大变化

¥Significant changes

我们已经:

¥We've:

  • 添加了对 ESM 插件的支持

    ¥added support for ESM plugins

  • 添加了对 ESM 自定义语法的支持

    ¥added support for ESM custom syntaxes

  • 添加了对 ESM 自定义格式化程序的支持

    ¥added support for ESM custom formatters

  • 已弃用 CommonJS Node.js API

    ¥deprecated the CommonJS Node.js API

  • 重构为在内部使用 .mjs.cjs 扩展

    ¥refactored to use .mjs and .cjs extensions internally

添加了对 ESM 插件的支持

¥Added support for ESM plugins

你现在可以创建 ESM plugins

¥You can now create ESM plugins.

例如:

¥For example:

import stylelint from "stylelint";

const {
createPlugin,
utils: { report, ruleMessages, validateOptions }
} = stylelint;

const ruleName = "foo-org/foo-bar";

const messages = ruleMessages(ruleName, {
rejected: (selector) => `Unexpected "foo"`
});

const meta = {
url: "https://foo.org/foo-bar"
};

const ruleFunction = (primary, secondaryOptions) => {
return (root, result) => {
const validOptions = validateOptions(/* .. */);

if (!validOptions) return;

/* .. */

report({
/* .. */
});
};
};

ruleFunction.ruleName = ruleName;
ruleFunction.messages = messages;
ruleFunction.meta = meta;

export default createPlugin(ruleName, ruleFunction);

我们更新了 插件开发者指南,添加了更多 ESM 语法示例。

¥We've updated our plugin developer guide with more examples of ESM syntax.

添加了对 ESM 自定义语法的支持

¥Added support for ESM custom syntaxes

你现在可以创建 ESM 自定义语法

¥You can now create ESM custom syntaxes.

例如:

¥For example:

import postcss from "postcss";

function parse(css, opts) {
/* .. */
}

function stringify(node, builder) {
/* .. */
}

export default { parse, stringify };

有关更多示例,请参阅 我们的开发者指南的自定义语法部分

¥See the custom syntaxes section of our developer guide for more examples.

添加了对 ESM 自定义格式化程序的支持

¥Added support for ESM custom formatters

你现在可以创建 ESM 自定义格式化程序

¥You can now create ESM custom formatters.

例如:

¥For example:

export default function yourOwnFormatter(results) {
/* .. */
}

有关更多示例,请参阅 我们的开发者指南的自定义格式化程序部分

¥See the custom formatters section of our developer guide for more examples.

已弃用的 CommonJS API

¥Deprecated CommonJS API

我们已弃用 CommonJS Node.js API,并将在下一个主要版本中将其删除,以便我们可以更新纯 ESM 依赖。

¥We've deprecated the CommonJS Node.js API and will remove it in the next major release so that we can update our pure ESM dependencies.

如果你是插件作者或使用 stylelint.lint() 来检查文件,则弃用将对你产生影响。自定义语法和格式化程序不受影响,因为它们不使用 Node.js API。

¥The deprecation will impact you if you're a plugin author or use stylelint.lint() to lint files. Custom syntaxes and formatters are not affected as they don't consume the Node.js API.

要迁移到 ESM,你应该:

¥To migrate to ESM you should:

  • 将所有 require()/module.export 替换为 import/export

    ¥replace all require()/module.export with import/export

  • 如果你不使用 .mjs 扩展,请将 "type": "module" 添加到 package.json

    ¥add "type": "module" to package.json if you are not using the .mjs extension

  • 仅使用完整的相对文件路径进行导入,例如 import x from '.';import x from './index.js';

    ¥use only full relative file paths for imports, e.g., import x from '.';import x from './index.js';

我们还建议你:

¥We also recommend that you:

  • package.json 中的 "engines" 字段更新为 "node": ">=18.12.0"

    ¥update the "engines" field in package.json to "node": ">=18.12.0"

  • 从所有文件中删除 'use strict';

    ¥remove 'use strict'; from all files

  • package.json 中添加 "exports": "./index.js"

    ¥add "exports": "./index.js" in package.json

  • 使用 node: 协议进行 Node.js 内置导入

    ¥use the node: protocol for Node.js built-in imports

有关更多详细信息,请参阅 ESM 的 Node.js 文档

¥For more details, see the Node.js documentation for ESM.

插件

¥Plugins

例如,要将你的插件迁移为使用 importexport

¥For example, to migrate your plugin to use import and export:

-const stylelint = require("stylelint");
+import stylelint from "stylelint";

const {
createPlugin,
utils: { report, validateOptions },
} = stylelint;

const ruleFunction = (primary, secondaryOptions) => { /* .. */ };

ruleFunction.ruleName = ruleName;
ruleFunction.messages = messages;
ruleFunction.meta = meta;

-module.exports = createPlugin(ruleName, ruleFunction);
+export default createPlugin(ruleName, ruleFunction);

如果你使用我们的 testRule 模式测试你的插件,你可以:

¥If you test your plugin using our testRule schema, you can either:

jest-preset-stylelint

预设需要 --experimental-vm-modules Node.js 标志来支持 ESM。你可以使用 cross-env 包在你的 npm-run-script 中设置 NODE_OPTIONS 环境变量:

¥The preset needs the --experimental-vm-modules Node.js flag to support ESM. You can use the cross-env package to set the NODE_OPTIONS environment variable in your npm-run-script:

 {
"scripts": {
- "test": "jest",
+ "test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --no-warnings\" jest --runInBand",
}
}

cross-env 处于维护模式,因为它是 视为已完成。)

¥(cross-env is in maintenance-mode as it's considered finished.)

如果你收到错误(例如,在 Node.js 18 上运行预设时出现分段错误),你可以尝试在 Jest 配置中使用 jest-light-runner

¥If you get an error (e.g. a segmentation fault while running the preset on Node.js 18), you can try using jest-light-runner in your Jest config:

 export default {
preset: "jest-preset-stylelint",
setupFiles: ["./jest.setup.js"],
+ runner: "jest-light-runner",
};

运行器具有有限的覆盖支持。

¥The runner has limited coverage support.

stylelint-test-rule-node

要尝试我们新的 stylelint-test-rule-node 包,你应该将其导入到你的测试文件中:

¥To try our new stylelint-test-rule-node package, you should import it into your test files:

+import { testRule } from "stylelint-test-rule-node";

testRule({
/* .. */
});

并更新你的 npm-run-script:

¥And update your npm-run-script:

 {
"scripts": {
- "test": "jest"
+ "test": "node --test"
}
}

该软件包使用 node:test,它在 Node.js 18 中是实验性的,但在 20 中是稳定的。覆盖率支持也是实验性的。

¥The package uses node:test which is experimental within Node.js 18, but stable in 20. Coverage support is also experimental.

如果你有其他 Jest 测试,则需要调整它们以使用 node:test,例如 expect() 变为 assert()

¥If you have other Jest tests, you'll need to adapt them to use node:test, e.g. expect() becomes assert().

stylelint.lint()

例如,要将使用 stylelint.lint() 的代码迁移到使用 import 和顶层 await

¥For example, to migrate your code that uses stylelint.lint() to use import and top-level await:

-const stylelint = require("stylelint");
+import stylelint from "stylelint";

-stylelint.lint(options).then((result) => { console.log(result); });
+const result = await stylelint.lint(options);
+console.log(result);

你将找到有关 用户指南中的 ESM Node.js API 的更多详细信息。

¥You'll find more details about the ESM Node.js API in the user guide.

使用 CommonJS Node.js API 将触发弃用警告。如果你尚未准备好迁移到 ESM,则可以使用 quietDeprecationWarnings 选项隐藏警告。

¥Using the CommonJS Node.js API will trigger a deprecation warning. If you're not quite ready to migrate to ESM yet, you can use the quietDeprecationWarnings option to hide the warning.

 const stylelint = require("stylelint");

const resultPromise = stylelint.lint({
/* .. */
+ quietDeprecationWarnings: true
});

重构为在内部使用 .mjs.cjs 扩展

¥Refactored to use .mjs and .cjs extensions internally

我们现在在内部使用 .mjs.cjs 扩展来支持混合包。此更改不会影响我们的公共 API,但如果你的插件 require 内部文件会影响你。

¥We now use .mjs and .cjs extensions internally to support a hybrid package. This change doesn't affect our public API but will affect you if your plugin requires internal files.

我们建议将文件复制到你的项目而不是导入它们,因为我们将在下一个主要版本中删除对它们的访问权限。

¥We recommended copying files to your project instead of importing them as we'll remove access to them in the next major release.

但是,你可以通过更新导入来不安全地在下一个主要版本之前继续对文件进行 importrequire

¥However, you can unsafely continue to import or require the files before the next major release by updating your imports:

 // ESM
-import('stylelint/lib/utils/typeGuards.js');
+import('stylelint/lib/utils/typeGuards.mjs');

// CommonJS
-require('stylelint/lib/utils/typeGuards.js');
+require('stylelint/lib/utils/typeGuards.cjs');

重大变化

¥Breaking changes

我们已经:

¥We've:

  • 删除了已弃用的风格规则

    ¥removed deprecated stylistic rules

  • 删除了对低于 18.12.0 的 Node.js 的支持

    ¥removed support for Node.js less than 18.12.0

  • 更改 Node.js API 返回已解析对象

    ¥changed Node.js API returned resolved object

  • 更改了 Node.js API stylelint.formatters 对象

    ¥changed Node.js API stylelint.formatters object

  • 更改了 Node.js API stylelint.rules 对象

    ¥changed Node.js API stylelint.rules object

  • 更改了 Node.js API stylelint.utils.checkAgainstRule() 功能

    ¥changed Node.js API stylelint.utils.checkAgainstRule() function

  • 更改 CLI 以将问题打印到 stderr

    ¥changed CLI to print problems to stderr

  • 更改了标志错误的 CLI 退出代码

    ¥changed CLI exit code for flag errors

  • 更改了默认语法行为以始终使用带有 fix 的安全解析器,无论扩展名如何

    ¥changed default syntax behaviour to always use safe-parser with fix regardless of extension

删除了已弃用的风格规则

¥Removed deprecated stylistic rules

我们删除了在 15.0.0 中弃用的样式规则。

¥We've removed the stylistic rules we deprecated in 15.0.0.

你应该从配置对象中删除规则。有关详细信息,请参阅 15.0.0 迁移指南

¥You should remove the rules from your configuration object. See the 15.0.0 migration guide for more details.

删除了对低于 18.12.0 的 Node.js 的支持

¥Removed support for Node.js less than 18.12.0

Node.js 14 和 16 已终止生命周期。我们已经删除了对它们的支持以更新我们的一些依赖。

¥Node.js 14 and 16 have reached end-of-life. We've removed support for them to update some of our dependencies.

你应该使用 18.12.0 或更高版本的 Node.js。

¥You should use the 18.12.0 or higher versions of Node.js.

更改了 Node.js API 返回解析的对象

¥Changed Node.js API returned resolved object

我们更改了 stylelint.lint() 返回的 Promise 的已解析对象,以便新的:

¥We've changed the resolved object of the Promise returned by stylelint.lint() so that a new:

  • report 属性包含格式问题

    ¥report property contains the formatted problems

  • code 属性包含自动修复代码

    ¥code property contains the autofixed code

我们已弃用 output 属性,转而使用新的 reportcode 属性,并且我们将在下一个主要版本中删除它。

¥We've deprecated the output property in favor of the new report and code ones, and we'll remove it in the next major version.

如果你使用 stylelint.lint() 来检查源字符串,并且 fix 选项为 true,则 report 属性将包含格式化问题,code 属性将包含固定代码。

¥If you use stylelint.lint() to lint a source string and the fix option is true, the report property will contain the formatted problems and the code property will contain the fixed code.

 const result = await stylelint.lint({
code: "a {}",
fix: true
});
-const fixedCode = result.output;
+const formattedProblems = result.report;
+const fixedCode = result.code;

如果你使用 stylelint.lint() 来检查文件,则 code 属性将始终为 undefined

¥The code property will always be undefined if you use stylelint.lint() to lint files.

更改了 Node.js API stylelint.formatters 对象

¥Changed Node.js API stylelint.formatters object

我们更改了 Node.js API 中的 stylelint.formatters 对象,以便每个格式化程序都是一个 Promise 函数。

¥We've changed the stylelint.formatters object in the Node.js API so that every formatter is a Promise function.

-const formatter = stylelint.formatters.json;
+const formatter = await stylelint.formatters.json;

更改了 Node.js API stylelint.rules 对象

¥Changed Node.js API stylelint.rules object

我们更改了 Node.js API 中的 stylelint.rules 对象,以便每个规则都是 Promise 函数。

¥We've changed the stylelint.rules object in the Node.js API so that every rule is a Promise function.

-const rule = stylelint.rules['block-no-empty'];
+const rule = await stylelint.rules['block-no-empty'];

更改了 Node.js API stylelint.utils.checkAgainstRule() 功能

¥Changed Node.js API stylelint.utils.checkAgainstRule() function

我们更改了 Node.js API 中的 stylelint.utils.checkAgainstRule() 函数,使其成为异步函数。

¥We've changed the stylelint.utils.checkAgainstRule() function in the Node.js API so that it's an async function.

-checkAgainstRule({ /* .. */ });
+await checkAgainstRule({ /* .. */ });

更改了 CLI 以将问题打印到 stderr

¥Changed CLI to print problems to stderr

我们更改了 CLI,将问题打印到 stderr 而不是 stdout。

¥We've changed the CLI to print problems to stderr instead of stdout.

如果你使用 --fix--stdin 选项,CLI 会将固定代码打印到 stdout,并将任何问题打印到 stderr。

¥If you use the --fix and --stdin options, the CLI will print the fixed code to stdout and any problems to stderr.

如果你使用 > 重定向标准输出,例如从自定义格式化程序,你可以改用 --output-file 标志:

¥If you use > to redirect standard output, e.g. from a custom formatter, you can use the --output-file flag instead:

-npx stylelint "*.css" --custom-formatter custom-formatter.js > output.txt
+npx stylelint "*.css" --custom-formatter custom-formatter.js --output-file output.txt

更改了标志错误的 CLI 退出代码

¥Changed CLI exit code for flag errors

我们已将 CLI 标志错误的退出代码从 2 更改为 64,以便为 lint 问题保留 2

¥We've changed the exit code for CLI flag errors from 2 to 64 so that 2 is reserved for lint problems.

如果你是使用 CLI 的编辑器集成的作者,你现在可以区分标志错误和 lint 问题。

¥If you're an author of an editor integration that uses the CLI, you can now distinguish between flag errors and lint problems.

更改了默认语法行为,以始终使用带有 fix 的安全解析器,无论扩展名如何

¥Changed default syntax behaviour to always use safe-parser with fix regardless of extension

我们已将默认语法行为更改为在自动修复 CSS 代码时始终使用 postcss-safe-parser,无论文件扩展名如何。以前,只有 .css.pcss.postcss 文件会使用 postcss-safe-parser 自动修复。

¥We've changed the default syntax behaviour to always use postcss-safe-parser when autofixing CSS code, regardless of the file's extension. Previously, only .css, .pcss, or .postcss files were autofixed with postcss-safe-parser.