From fb3b80db242978d88eb6c0eac382498b3aa04459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=B1=D0=BC=D0=BE=D1=87=D0=B5=D0=B2=D1=81=D0=BA?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D1=81=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=20=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=D0=BE?= =?UTF-8?q?=D0=B2=D0=B8=D1=87?= Date: Sat, 9 Nov 2024 22:26:18 +0700 Subject: [PATCH 1/6] feat(postcss): add custom postcss plugin - postcss-global-data --- .changeset/quick-starfishes-taste.md | 5 ++ .../src/configs/postcss.config.ts | 6 -- .../src/configs/webpack.client.ts | 12 ++- .../src/configs/webpack.server.ts | 8 +- .../plugins/__tests__/insert-plugin.test.ts | 19 +++++ .../arui-scripts/src/plugins/insert-plugin.ts | 19 +++++ .../postcss-global-data.ts | 52 ++++++++++++ .../__tests__/add-global-variable.tests.ts | 44 ++++++++++ .../__tests__/get-media-query-name.tests.ts | 17 ++++ .../utils/__tests__/parse-variables.tests.ts | 29 +++++++ .../postcss-global-data/utils/utils.ts | 83 +++++++++++++++++++ 11 files changed, 285 insertions(+), 9 deletions(-) create mode 100644 .changeset/quick-starfishes-taste.md create mode 100644 packages/arui-scripts/src/plugins/__tests__/insert-plugin.test.ts create mode 100644 packages/arui-scripts/src/plugins/insert-plugin.ts create mode 100644 packages/arui-scripts/src/plugins/postcss-global-data/postcss-global-data.ts create mode 100644 packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/add-global-variable.tests.ts create mode 100644 packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/get-media-query-name.tests.ts create mode 100644 packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/parse-variables.tests.ts create mode 100644 packages/arui-scripts/src/plugins/postcss-global-data/utils/utils.ts diff --git a/.changeset/quick-starfishes-taste.md b/.changeset/quick-starfishes-taste.md new file mode 100644 index 00000000..8e255b90 --- /dev/null +++ b/.changeset/quick-starfishes-taste.md @@ -0,0 +1,5 @@ +--- +'arui-scripts': minor +--- + +Добавлен кастомный плагин postcss-global-data, для оптимизации времени обработки глобальных переменных diff --git a/packages/arui-scripts/src/configs/postcss.config.ts b/packages/arui-scripts/src/configs/postcss.config.ts index 982d0db1..034c929b 100644 --- a/packages/arui-scripts/src/configs/postcss.config.ts +++ b/packages/arui-scripts/src/configs/postcss.config.ts @@ -1,5 +1,3 @@ -import path from 'path'; - import config from './app-configs'; import supportingBrowsers from './supporting-browsers'; /** @@ -28,7 +26,6 @@ export const postcssPlugins = [ 'postcss-mixins', 'postcss-for', 'postcss-each', - '@csstools/postcss-global-data', 'postcss-custom-media', 'postcss-color-mod-function', !config.keepCssVars && 'postcss-custom-properties', @@ -46,9 +43,6 @@ export const postcssPluginsOptions = { 'postcss-import': { path: ['./src'], }, - '@csstools/postcss-global-data': { - files: [path.join(__dirname, 'mq.css'), config.componentsTheme].filter(Boolean) as string[], - }, 'postcss-url': { url: 'rebase', }, diff --git a/packages/arui-scripts/src/configs/webpack.client.ts b/packages/arui-scripts/src/configs/webpack.client.ts index 56e5d9d3..d01aa713 100644 --- a/packages/arui-scripts/src/configs/webpack.client.ts +++ b/packages/arui-scripts/src/configs/webpack.client.ts @@ -20,6 +20,8 @@ import { WebpackDeduplicationPlugin } from 'webpack-deduplication-plugin'; import { WebpackManifestPlugin } from 'webpack-manifest-plugin'; import { AruiRuntimePlugin, getInsertCssRuntimeMethod } from '../plugins/arui-runtime'; +import { insertPlugin } from '../plugins/insert-plugin'; +import { postCssGlobalData } from '../plugins/postcss-global-data/postcss-global-data'; import { htmlTemplate } from '../templates/html.template'; import { getImageMin } from './config-extras/minimizers'; @@ -285,7 +287,10 @@ export const createSingleClientWebpackConfig = ( loader: require.resolve('postcss-loader'), options: { postcssOptions: { - plugins: postcssConf, + // добавляем postCssGlobalData плагин перед postcss-custom-media + plugins: insertPlugin(postcssConf, 'postcss-custom-media', postCssGlobalData({ + files: [path.join(__dirname, 'mq.css'), configs.componentsTheme].filter(Boolean) as string[] + })) }, }, }, @@ -313,7 +318,10 @@ export const createSingleClientWebpackConfig = ( loader: require.resolve('postcss-loader'), options: { postcssOptions: { - plugins: postcssConf, + // добавляем postCssGlobalData плагин перед postcss-custom-media + plugins: insertPlugin(postcssConf, 'postcss-custom-media', postCssGlobalData({ + files: [path.join(__dirname, 'mq.css'), configs.componentsTheme].filter(Boolean) as string[] + })) }, }, }, diff --git a/packages/arui-scripts/src/configs/webpack.server.ts b/packages/arui-scripts/src/configs/webpack.server.ts index 3fd34299..b5a0c20d 100644 --- a/packages/arui-scripts/src/configs/webpack.server.ts +++ b/packages/arui-scripts/src/configs/webpack.server.ts @@ -10,6 +10,9 @@ import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import webpack, { Configuration } from 'webpack'; import nodeExternals from 'webpack-node-externals'; +import { insertPlugin } from '../plugins/insert-plugin'; +import { postCssGlobalData } from '../plugins/postcss-global-data/postcss-global-data'; + import getEntry from './util/get-entry'; import { getWebpackCacheDependencies } from './util/get-webpack-cache-dependencies'; import configs from './app-configs'; @@ -155,7 +158,10 @@ export const createServerConfig = (mode: 'dev' | 'prod'): Configuration => ({ loader: require.resolve('postcss-loader'), options: { postcssOptions: { - plugins: postcssConf, + // добавляем postCssGlobalData плагин перед postcss-custom-media + plugins: insertPlugin(postcssConf, 'postcss-custom-media', postCssGlobalData({ + files: [path.join(__dirname, 'mq.css'), configs.componentsTheme].filter(Boolean) as string[] + })) }, }, }, diff --git a/packages/arui-scripts/src/plugins/__tests__/insert-plugin.test.ts b/packages/arui-scripts/src/plugins/__tests__/insert-plugin.test.ts new file mode 100644 index 00000000..9ad157c8 --- /dev/null +++ b/packages/arui-scripts/src/plugins/__tests__/insert-plugin.test.ts @@ -0,0 +1,19 @@ +import { insertPlugin } from '../insert-plugin'; + +describe('insertPlugin', () => { + it('Должен корректно добавить плагин перед искомым плагином', () => { + const plugins = ['plugin1', 'plugin2', 'plugin3', 'plugin4']; + + const newPlugins = insertPlugin(plugins, 'plugin4', 'plugin777'); + + expect(newPlugins).toEqual(['plugin1', 'plugin2', 'plugin3', 'plugin777', 'plugin4']); + }); + + it('Должен корректно добавить плагин перед искомым плагином, если искомый плагин в массиве', () => { + const plugins = ['plugin1', 'plugin2', ['plugin3', {}], 'plugin4']; + + const newPlugins = insertPlugin(plugins, 'plugin3', 'plugin777'); + + expect(newPlugins).toEqual(['plugin1', 'plugin2', 'plugin777', ['plugin3', {}], 'plugin4']); + }); +}); diff --git a/packages/arui-scripts/src/plugins/insert-plugin.ts b/packages/arui-scripts/src/plugins/insert-plugin.ts new file mode 100644 index 00000000..b899a7a7 --- /dev/null +++ b/packages/arui-scripts/src/plugins/insert-plugin.ts @@ -0,0 +1,19 @@ +export const insertPlugin = (plugins: string[] | unknown[], beforePluginName: string, plugin: string | unknown): string[] | unknown[] => { + let beforePluginIndex = -1; + + plugins.forEach((pluginName, index) => { + if(Array.isArray(pluginName) && pluginName[0] === beforePluginName){ + beforePluginIndex = index; + } + + if(!Array.isArray(pluginName) && pluginName === beforePluginName){ + beforePluginIndex = index; + } + }); + + if(beforePluginIndex === -1) { + return plugins; + } + + return [...plugins.slice(0, beforePluginIndex), plugin, ...plugins.slice(beforePluginIndex)] +} \ No newline at end of file diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/postcss-global-data.ts b/packages/arui-scripts/src/plugins/postcss-global-data/postcss-global-data.ts new file mode 100644 index 00000000..d02b51a6 --- /dev/null +++ b/packages/arui-scripts/src/plugins/postcss-global-data/postcss-global-data.ts @@ -0,0 +1,52 @@ +import type { AtRule, Plugin, PluginCreator, Rule } from 'postcss'; + +import { insertParsedCss, parseImport, parseMediaQuery, parseVariables } from './utils/utils'; + +type PluginOptions = { + files?: string[]; +}; + +const postCssGlobalData: PluginCreator = (opts?: PluginOptions) => { + const options = { + files: [], + ...opts, + }; + + const parsedVariables: Record = {}; + const parsedCustomMedia: Record = {}; + + let rulesSelectors = new Set(); + + return { + postcssPlugin: '@alfalab/postcss-global-data', + prepare(): Plugin { + return { + postcssPlugin: '@alfalab/postcss-global-data', + Once(root, postcssHelpers): void { + if (!Object.keys(parsedVariables).length) { + options.files.forEach((filePath) => { + const importedCss = parseImport(root, postcssHelpers, filePath); + + parseVariables(importedCss, parsedVariables); + parseMediaQuery(importedCss, parsedCustomMedia); + }); + } + + const rootRule = insertParsedCss(root, parsedVariables, parsedCustomMedia); + + root.append(rootRule); + }, + OnceExit(): void { + rulesSelectors.forEach((rule) => { + rule.remove(); + }); + rulesSelectors = new Set(); + }, + }; + }, + }; +}; + +postCssGlobalData.postcss = true; + +export { postCssGlobalData }; \ No newline at end of file diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/add-global-variable.tests.ts b/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/add-global-variable.tests.ts new file mode 100644 index 00000000..472e04fc --- /dev/null +++ b/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/add-global-variable.tests.ts @@ -0,0 +1,44 @@ +import { Rule } from 'postcss'; + +import { addGlobalVariable } from '../utils'; + +describe('addGlobalVariable', () => { + it('Должен добавлять переменные, найденные в cssValue, в rootSelector', () => { + const mockRootSelector = new Rule({ selector: ':root' }); + const parsedVariables = { + '--color-primary': '#ff0000', + }; + + addGlobalVariable('var(--color-primary)', mockRootSelector, parsedVariables); + + expect(mockRootSelector.nodes).toMatchObject([ + { prop: '--color-primary', value: '#ff0000' } + ]); + }); + + it('Должен рекурсивно добавлять вложенные переменные', () => { + const mockRootSelector = new Rule({ selector: ':root' }); + const parsedVariables = { + '--color-primary': 'var(--color-secondary)', + '--color-secondary': '#00ff00', + }; + + addGlobalVariable('var(--color-primary)', mockRootSelector, parsedVariables); + + expect(mockRootSelector.nodes).toMatchObject([ + { prop: '--color-primary', value: 'var(--color-secondary)' }, + { prop: '--color-secondary', value: '#00ff00' }, + ]); + }); + + it('Не должен добавлять переменные, если их нет в parsedVariables', () => { + const mockRootSelector = new Rule({ selector: ':root' }); + const parsedVariables = { + 'color-primary': '#ff0000', + }; + + addGlobalVariable('var(--color-secondary)', mockRootSelector, parsedVariables); + + expect(mockRootSelector.nodes).toEqual([]); + }); +}); diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/get-media-query-name.tests.ts b/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/get-media-query-name.tests.ts new file mode 100644 index 00000000..36bd8d7b --- /dev/null +++ b/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/get-media-query-name.tests.ts @@ -0,0 +1,17 @@ +import type { AtRule } from 'postcss'; + +import { getMediaQueryName, } from '../utils'; + +describe('getMediaQueryName', () => { + it('Должен возвращать имя медиа-запроса', () => { + const rule: AtRule = { params: 'screen and (min-width: 768px)' } as AtRule; + + expect(getMediaQueryName(rule)).toBe('screen'); + }); + + it('Должен возвращать пустую строку, если params пустой', () => { + const rule: AtRule = { params: '' } as AtRule; + + expect(getMediaQueryName(rule)).toBe(''); + }); +}); \ No newline at end of file diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/parse-variables.tests.ts b/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/parse-variables.tests.ts new file mode 100644 index 00000000..b52a2f3d --- /dev/null +++ b/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/parse-variables.tests.ts @@ -0,0 +1,29 @@ +import type { Declaration,Root } from 'postcss'; + +import { parseVariables } from '../utils'; + +describe('parseVariables', () => { + it('Должен корректно заполнять объект переменными на основе импортируемого файла', () => { + const parsedVariables: Record = {}; + + const mockImportedFile = { + walkDecls: (callback: (decl: Declaration, index: number) => false | void) => { + const mockDeclarations: Declaration[] = [ + { prop: '--color-primary', value: '#3498db' } as Declaration, + { prop: '--font-size', value: 'var(--gap-24)' } as Declaration, + ]; + + mockDeclarations.forEach(callback); + + return false; + } + }; + + parseVariables(mockImportedFile as Root, parsedVariables); + + expect(parsedVariables).toEqual({ + '--color-primary': '#3498db', + '--font-size': 'var(--gap-24)', + }); + }); +}); diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/utils/utils.ts b/packages/arui-scripts/src/plugins/postcss-global-data/utils/utils.ts new file mode 100644 index 00000000..a1895167 --- /dev/null +++ b/packages/arui-scripts/src/plugins/postcss-global-data/utils/utils.ts @@ -0,0 +1,83 @@ +import fs from 'fs'; +import path from 'path'; + +import { AtRule, Declaration, Helpers, Root, Rule } from 'postcss'; + +export const getMediaQueryName = (rule: AtRule) => rule.params.split(' ')[0]; + +export function parseImport(root: Root, postcssHelpers: Helpers, filePath: string) { + let resolvedPath = ''; + + try { + resolvedPath = path.resolve(filePath); + } catch (err) { + throw new Error(`Failed to read ${filePath} with error ${(err instanceof Error) ? err.message : err}`); + } + + postcssHelpers.result.messages.push({ + type: 'dependency', + plugin: 'postcss-global-data', + file: resolvedPath, + parent: root.source?.input?.file, + }); + + const fileContents = fs.readFileSync(resolvedPath, 'utf8'); + + return postcssHelpers.postcss.parse(fileContents, { from: resolvedPath }); +} + +export const parseVariables = (importedFile: Root, parsedVariables: Record) => { + importedFile.walkDecls((decl) => { + // eslint-disable-next-line no-param-reassign + parsedVariables[decl.prop] = decl.value; + }); +}; + +export const parseMediaQuery = (importedFile: Root, parsedCustomMedia: Record) => { + importedFile.walkAtRules('custom-media', (mediaRule) => { + const mediaName = getMediaQueryName(mediaRule); + + // eslint-disable-next-line no-param-reassign + parsedCustomMedia[mediaName] = mediaRule; + }); +}; + +export function addGlobalVariable(cssValue: string, rootSelector: Rule, parsedVariables: Record) { + const variableMatches = cssValue.match(/var\(--([^)]+)\)/g); + + if (variableMatches) { + variableMatches.forEach((match) => { + // var(--gap-24) => --gap-24 + const variableName = match.slice(4, -1); + + if (parsedVariables[variableName]) { + rootSelector.append(new Declaration({ prop: variableName, value: parsedVariables[variableName] })); + + // Рекурсивно проходимся по значениям css, там тоже могут использоваться переменные + addGlobalVariable(parsedVariables[variableName], rootSelector, parsedVariables); + } + }); + } +} + +export const insertParsedCss = (root: Root, parsedVariables: Record, parsedCustomMedia: Record): Rule => { + const rootRule = new Rule({ selector: ':root' }); + + root.walkDecls((decl) => { + addGlobalVariable(decl.value, rootRule, parsedVariables); + }); + + root.walkAtRules('media', (rule) => { + const mediaFullName = getMediaQueryName(rule); + + if (mediaFullName.startsWith('(--')) { + const mediaName = mediaFullName.slice(1, -1); + + if (parsedCustomMedia[mediaName]) { + root.append(parsedCustomMedia[mediaName]); + } + } + }); + + return rootRule; +}; From d3234eebe4841f591a1c5e039880cf48c55c254e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=B1=D0=BC=D0=BE=D1=87=D0=B5=D0=B2=D1=81=D0=BA?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D1=81=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=20=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=D0=BE?= =?UTF-8?q?=D0=B2=D0=B8=D1=87?= Date: Fri, 29 Nov 2024 13:43:38 +0700 Subject: [PATCH 2/6] feat(*): remove postcss-global-data and add custom postcss-global-variables --- packages/arui-scripts/package.json | 1 - .../src/configs/postcss.config.ts | 33 +++++++++++++++---- packages/arui-scripts/src/configs/postcss.ts | 4 ++- .../src/configs/webpack.client.ts | 12 ++----- .../src/configs/webpack.server.ts | 8 +---- .../plugins/__tests__/insert-plugin.test.ts | 19 ----------- .../arui-scripts/src/plugins/insert-plugin.ts | 19 ----------- .../postcss-global-variables.ts} | 11 ++++--- .../__tests__/add-global-variable.tests.ts | 0 .../__tests__/get-media-query-name.tests.ts | 0 .../utils/__tests__/parse-variables.tests.ts | 0 .../utils/utils.ts | 2 +- yarn.lock | 10 ------ 13 files changed, 39 insertions(+), 80 deletions(-) delete mode 100644 packages/arui-scripts/src/plugins/__tests__/insert-plugin.test.ts delete mode 100644 packages/arui-scripts/src/plugins/insert-plugin.ts rename packages/arui-scripts/src/plugins/{postcss-global-data/postcss-global-data.ts => postcss-global-variables/postcss-global-variables.ts} (79%) rename packages/arui-scripts/src/plugins/{postcss-global-data => postcss-global-variables}/utils/__tests__/add-global-variable.tests.ts (100%) rename packages/arui-scripts/src/plugins/{postcss-global-data => postcss-global-variables}/utils/__tests__/get-media-query-name.tests.ts (100%) rename packages/arui-scripts/src/plugins/{postcss-global-data => postcss-global-variables}/utils/__tests__/parse-variables.tests.ts (100%) rename packages/arui-scripts/src/plugins/{postcss-global-data => postcss-global-variables}/utils/utils.ts (98%) diff --git a/packages/arui-scripts/package.json b/packages/arui-scripts/package.json index 539ec098..d10c4e7a 100644 --- a/packages/arui-scripts/package.json +++ b/packages/arui-scripts/package.json @@ -36,7 +36,6 @@ "@babel/preset-react": "^7.23.3", "@babel/preset-typescript": "^7.23.3", "@babel/runtime": "^7.23.8", - "@csstools/postcss-global-data": "^2.0.1", "@pmmmwh/react-refresh-webpack-plugin": "0.5.11", "@swc/core": "^1.7.35", "@swc/jest": "^0.2.36", diff --git a/packages/arui-scripts/src/configs/postcss.config.ts b/packages/arui-scripts/src/configs/postcss.config.ts index 034c929b..2fc22d0a 100644 --- a/packages/arui-scripts/src/configs/postcss.config.ts +++ b/packages/arui-scripts/src/configs/postcss.config.ts @@ -1,21 +1,36 @@ +import path from 'path'; + +import type { Plugin, PluginCreator, Processor } from 'postcss'; + +import { postCssGlobalVariables } from '../plugins/postcss-global-variables/postcss-global-variables'; + import config from './app-configs'; import supportingBrowsers from './supporting-browsers'; + +type PostCssPluginName = string | PluginCreator; +type PostcssPlugin = string | [string, unknown] | (() => Plugin | Processor); + /** * Функция для создания конфигурационного файла postcss - * @param {String[]} plugins список плагинов + * @param {PostCssPluginName[]} plugins список плагинов * @param {Object} options коллекция конфигураций плагинов, где ключ - название плагина, а значение - аргумент для инициализации * @returns {*} */ export function createPostcssConfig( - plugins: string[], + plugins: PostCssPluginName[], options: Record, -): string[] | unknown[] { +): PostcssPlugin[] { return plugins.map((pluginName) => { - if (pluginName in options) { - return [pluginName, options[pluginName]]; + console.log('pluginName: ', pluginName); + if (typeof pluginName === 'string') { + return pluginName in options + ? [pluginName, options[pluginName]] + : pluginName; } - return pluginName; + console.log('pluginName.name', pluginName.name); + + return () => pluginName(options[pluginName.name]); }); } @@ -26,6 +41,7 @@ export const postcssPlugins = [ 'postcss-mixins', 'postcss-for', 'postcss-each', + postCssGlobalVariables, 'postcss-custom-media', 'postcss-color-mod-function', !config.keepCssVars && 'postcss-custom-properties', @@ -37,12 +53,15 @@ export const postcssPlugins = [ 'autoprefixer', 'postcss-inherit', 'postcss-discard-comments', -].filter(Boolean) as string[]; +].filter(Boolean) as PostCssPluginName[]; export const postcssPluginsOptions = { 'postcss-import': { path: ['./src'], }, + 'postCssGlobalVariables': { + files: [path.join(__dirname, 'mq.css'), config.componentsTheme].filter(Boolean) as string[], + }, 'postcss-url': { url: 'rebase', }, diff --git a/packages/arui-scripts/src/configs/postcss.ts b/packages/arui-scripts/src/configs/postcss.ts index 122c706b..1b7dfdd5 100644 --- a/packages/arui-scripts/src/configs/postcss.ts +++ b/packages/arui-scripts/src/configs/postcss.ts @@ -4,6 +4,8 @@ import { createPostcssConfig, postcssPlugins, postcssPluginsOptions } from './po const postcssConfig = applyOverrides( 'postcss', createPostcssConfig(postcssPlugins, postcssPluginsOptions), -); + // тк дается возможность переопределять options для плагинов импортируемых напрямую + // инициализировать их нужно после оверайдов +).map((plugin) => typeof plugin === 'function' ? plugin() : plugin); export default postcssConfig; diff --git a/packages/arui-scripts/src/configs/webpack.client.ts b/packages/arui-scripts/src/configs/webpack.client.ts index d01aa713..56e5d9d3 100644 --- a/packages/arui-scripts/src/configs/webpack.client.ts +++ b/packages/arui-scripts/src/configs/webpack.client.ts @@ -20,8 +20,6 @@ import { WebpackDeduplicationPlugin } from 'webpack-deduplication-plugin'; import { WebpackManifestPlugin } from 'webpack-manifest-plugin'; import { AruiRuntimePlugin, getInsertCssRuntimeMethod } from '../plugins/arui-runtime'; -import { insertPlugin } from '../plugins/insert-plugin'; -import { postCssGlobalData } from '../plugins/postcss-global-data/postcss-global-data'; import { htmlTemplate } from '../templates/html.template'; import { getImageMin } from './config-extras/minimizers'; @@ -287,10 +285,7 @@ export const createSingleClientWebpackConfig = ( loader: require.resolve('postcss-loader'), options: { postcssOptions: { - // добавляем postCssGlobalData плагин перед postcss-custom-media - plugins: insertPlugin(postcssConf, 'postcss-custom-media', postCssGlobalData({ - files: [path.join(__dirname, 'mq.css'), configs.componentsTheme].filter(Boolean) as string[] - })) + plugins: postcssConf, }, }, }, @@ -318,10 +313,7 @@ export const createSingleClientWebpackConfig = ( loader: require.resolve('postcss-loader'), options: { postcssOptions: { - // добавляем postCssGlobalData плагин перед postcss-custom-media - plugins: insertPlugin(postcssConf, 'postcss-custom-media', postCssGlobalData({ - files: [path.join(__dirname, 'mq.css'), configs.componentsTheme].filter(Boolean) as string[] - })) + plugins: postcssConf, }, }, }, diff --git a/packages/arui-scripts/src/configs/webpack.server.ts b/packages/arui-scripts/src/configs/webpack.server.ts index b5a0c20d..3fd34299 100644 --- a/packages/arui-scripts/src/configs/webpack.server.ts +++ b/packages/arui-scripts/src/configs/webpack.server.ts @@ -10,9 +10,6 @@ import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import webpack, { Configuration } from 'webpack'; import nodeExternals from 'webpack-node-externals'; -import { insertPlugin } from '../plugins/insert-plugin'; -import { postCssGlobalData } from '../plugins/postcss-global-data/postcss-global-data'; - import getEntry from './util/get-entry'; import { getWebpackCacheDependencies } from './util/get-webpack-cache-dependencies'; import configs from './app-configs'; @@ -158,10 +155,7 @@ export const createServerConfig = (mode: 'dev' | 'prod'): Configuration => ({ loader: require.resolve('postcss-loader'), options: { postcssOptions: { - // добавляем postCssGlobalData плагин перед postcss-custom-media - plugins: insertPlugin(postcssConf, 'postcss-custom-media', postCssGlobalData({ - files: [path.join(__dirname, 'mq.css'), configs.componentsTheme].filter(Boolean) as string[] - })) + plugins: postcssConf, }, }, }, diff --git a/packages/arui-scripts/src/plugins/__tests__/insert-plugin.test.ts b/packages/arui-scripts/src/plugins/__tests__/insert-plugin.test.ts deleted file mode 100644 index 9ad157c8..00000000 --- a/packages/arui-scripts/src/plugins/__tests__/insert-plugin.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { insertPlugin } from '../insert-plugin'; - -describe('insertPlugin', () => { - it('Должен корректно добавить плагин перед искомым плагином', () => { - const plugins = ['plugin1', 'plugin2', 'plugin3', 'plugin4']; - - const newPlugins = insertPlugin(plugins, 'plugin4', 'plugin777'); - - expect(newPlugins).toEqual(['plugin1', 'plugin2', 'plugin3', 'plugin777', 'plugin4']); - }); - - it('Должен корректно добавить плагин перед искомым плагином, если искомый плагин в массиве', () => { - const plugins = ['plugin1', 'plugin2', ['plugin3', {}], 'plugin4']; - - const newPlugins = insertPlugin(plugins, 'plugin3', 'plugin777'); - - expect(newPlugins).toEqual(['plugin1', 'plugin2', 'plugin777', ['plugin3', {}], 'plugin4']); - }); -}); diff --git a/packages/arui-scripts/src/plugins/insert-plugin.ts b/packages/arui-scripts/src/plugins/insert-plugin.ts deleted file mode 100644 index b899a7a7..00000000 --- a/packages/arui-scripts/src/plugins/insert-plugin.ts +++ /dev/null @@ -1,19 +0,0 @@ -export const insertPlugin = (plugins: string[] | unknown[], beforePluginName: string, plugin: string | unknown): string[] | unknown[] => { - let beforePluginIndex = -1; - - plugins.forEach((pluginName, index) => { - if(Array.isArray(pluginName) && pluginName[0] === beforePluginName){ - beforePluginIndex = index; - } - - if(!Array.isArray(pluginName) && pluginName === beforePluginName){ - beforePluginIndex = index; - } - }); - - if(beforePluginIndex === -1) { - return plugins; - } - - return [...plugins.slice(0, beforePluginIndex), plugin, ...plugins.slice(beforePluginIndex)] -} \ No newline at end of file diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/postcss-global-data.ts b/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts similarity index 79% rename from packages/arui-scripts/src/plugins/postcss-global-data/postcss-global-data.ts rename to packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts index d02b51a6..01ef62b9 100644 --- a/packages/arui-scripts/src/plugins/postcss-global-data/postcss-global-data.ts +++ b/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts @@ -6,7 +6,7 @@ type PluginOptions = { files?: string[]; }; -const postCssGlobalData: PluginCreator = (opts?: PluginOptions) => { +const postCssGlobalVariables: PluginCreator = (opts?: PluginOptions) => { const options = { files: [], ...opts, @@ -18,13 +18,14 @@ const postCssGlobalData: PluginCreator = (opts?: PluginOptions) = let rulesSelectors = new Set(); return { - postcssPlugin: '@alfalab/postcss-global-data', + postcssPlugin: '@alfalab/postcss-global-variables', prepare(): Plugin { return { - postcssPlugin: '@alfalab/postcss-global-data', + postcssPlugin: '@alfalab/postcss-global-variables', Once(root, postcssHelpers): void { if (!Object.keys(parsedVariables).length) { options.files.forEach((filePath) => { + console.log('parse file: ', filePath); const importedCss = parseImport(root, postcssHelpers, filePath); parseVariables(importedCss, parsedVariables); @@ -47,6 +48,6 @@ const postCssGlobalData: PluginCreator = (opts?: PluginOptions) = }; }; -postCssGlobalData.postcss = true; +postCssGlobalVariables.postcss = true; -export { postCssGlobalData }; \ No newline at end of file +export { postCssGlobalVariables }; \ No newline at end of file diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/add-global-variable.tests.ts b/packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/add-global-variable.tests.ts similarity index 100% rename from packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/add-global-variable.tests.ts rename to packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/add-global-variable.tests.ts diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/get-media-query-name.tests.ts b/packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/get-media-query-name.tests.ts similarity index 100% rename from packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/get-media-query-name.tests.ts rename to packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/get-media-query-name.tests.ts diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/parse-variables.tests.ts b/packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/parse-variables.tests.ts similarity index 100% rename from packages/arui-scripts/src/plugins/postcss-global-data/utils/__tests__/parse-variables.tests.ts rename to packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/parse-variables.tests.ts diff --git a/packages/arui-scripts/src/plugins/postcss-global-data/utils/utils.ts b/packages/arui-scripts/src/plugins/postcss-global-variables/utils/utils.ts similarity index 98% rename from packages/arui-scripts/src/plugins/postcss-global-data/utils/utils.ts rename to packages/arui-scripts/src/plugins/postcss-global-variables/utils/utils.ts index a1895167..281e56d1 100644 --- a/packages/arui-scripts/src/plugins/postcss-global-data/utils/utils.ts +++ b/packages/arui-scripts/src/plugins/postcss-global-variables/utils/utils.ts @@ -16,7 +16,7 @@ export function parseImport(root: Root, postcssHelpers: Helpers, filePath: strin postcssHelpers.result.messages.push({ type: 'dependency', - plugin: 'postcss-global-data', + plugin: 'postcss-global-environments', file: resolvedPath, parent: root.source?.input?.file, }); diff --git a/yarn.lock b/yarn.lock index c313e086..bf71c618 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2741,15 +2741,6 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-global-data@npm:^2.0.1": - version: 2.0.1 - resolution: "@csstools/postcss-global-data@npm:2.0.1" - peerDependencies: - postcss: ^8.4 - checksum: 21e7057b7f527481c7374810c3b49a2d47414b39f4408c5d182bb6aab62d190da5b6173aa1accacb091994d1158cee2a651fbf2977957bbcf1fc654669886c1a - languageName: node - linkType: hard - "@csstools/postcss-gradients-interpolation-method@npm:^3.0.6": version: 3.0.6 resolution: "@csstools/postcss-gradients-interpolation-method@npm:3.0.6" @@ -6485,7 +6476,6 @@ __metadata: "@babel/preset-react": ^7.23.3 "@babel/preset-typescript": ^7.23.3 "@babel/runtime": ^7.23.8 - "@csstools/postcss-global-data": ^2.0.1 "@pmmmwh/react-refresh-webpack-plugin": 0.5.11 "@swc/core": ^1.7.35 "@swc/jest": ^0.2.36 From b9bdd8a4ce675fe3275e2490c3198827dc4650e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=B1=D0=BC=D0=BE=D1=87=D0=B5=D0=B2=D1=81=D0=BA?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D1=81=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=20=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=D0=BE?= =?UTF-8?q?=D0=B2=D0=B8=D1=87?= Date: Mon, 2 Dec 2024 13:53:22 +0700 Subject: [PATCH 3/6] feat(*): remove console.log --- packages/arui-scripts/src/configs/postcss.config.ts | 3 --- .../postcss-global-variables/postcss-global-variables.ts | 1 - 2 files changed, 4 deletions(-) diff --git a/packages/arui-scripts/src/configs/postcss.config.ts b/packages/arui-scripts/src/configs/postcss.config.ts index 2fc22d0a..ccc4fd7e 100644 --- a/packages/arui-scripts/src/configs/postcss.config.ts +++ b/packages/arui-scripts/src/configs/postcss.config.ts @@ -21,15 +21,12 @@ export function createPostcssConfig( options: Record, ): PostcssPlugin[] { return plugins.map((pluginName) => { - console.log('pluginName: ', pluginName); if (typeof pluginName === 'string') { return pluginName in options ? [pluginName, options[pluginName]] : pluginName; } - console.log('pluginName.name', pluginName.name); - return () => pluginName(options[pluginName.name]); }); } diff --git a/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts b/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts index 01ef62b9..bd3af460 100644 --- a/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts +++ b/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts @@ -25,7 +25,6 @@ const postCssGlobalVariables: PluginCreator = (opts?: PluginOptio Once(root, postcssHelpers): void { if (!Object.keys(parsedVariables).length) { options.files.forEach((filePath) => { - console.log('parse file: ', filePath); const importedCss = parseImport(root, postcssHelpers, filePath); parseVariables(importedCss, parsedVariables); From 10fc6dd1446bf79c5381da3de4b903d639a4f83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=B1=D0=BC=D0=BE=D1=87=D0=B5=D0=B2=D1=81=D0=BA?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D1=81=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=20=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=D0=BE?= =?UTF-8?q?=D0=B2=D0=B8=D1=87?= Date: Thu, 5 Dec 2024 00:47:42 +0700 Subject: [PATCH 4/6] feat(*): fix parse css variable and override css plugin creators --- .../src/configs/postcss.config.ts | 10 +++++--- packages/arui-scripts/src/configs/postcss.ts | 4 ++- .../__tests__/add-global-variable.tests.ts | 25 +++++++++++++++++++ .../postcss-global-variables/utils/utils.ts | 4 +-- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/packages/arui-scripts/src/configs/postcss.config.ts b/packages/arui-scripts/src/configs/postcss.config.ts index ccc4fd7e..6fece934 100644 --- a/packages/arui-scripts/src/configs/postcss.config.ts +++ b/packages/arui-scripts/src/configs/postcss.config.ts @@ -1,6 +1,6 @@ import path from 'path'; -import type { Plugin, PluginCreator, Processor } from 'postcss'; +import type { PluginCreator } from 'postcss'; import { postCssGlobalVariables } from '../plugins/postcss-global-variables/postcss-global-variables'; @@ -8,7 +8,7 @@ import config from './app-configs'; import supportingBrowsers from './supporting-browsers'; type PostCssPluginName = string | PluginCreator; -type PostcssPlugin = string | [string, unknown] | (() => Plugin | Processor); +type PostcssPlugin = string | [string, unknown] | {name: string; plugin: PluginCreator; options?: unknown}; /** * Функция для создания конфигурационного файла postcss @@ -27,7 +27,11 @@ export function createPostcssConfig( : pluginName; } - return () => pluginName(options[pluginName.name]); + return { + name: pluginName.name, + plugin: pluginName, + options: options[pluginName.name] + } }); } diff --git a/packages/arui-scripts/src/configs/postcss.ts b/packages/arui-scripts/src/configs/postcss.ts index 1b7dfdd5..82559ea3 100644 --- a/packages/arui-scripts/src/configs/postcss.ts +++ b/packages/arui-scripts/src/configs/postcss.ts @@ -6,6 +6,8 @@ const postcssConfig = applyOverrides( createPostcssConfig(postcssPlugins, postcssPluginsOptions), // тк дается возможность переопределять options для плагинов импортируемых напрямую // инициализировать их нужно после оверайдов -).map((plugin) => typeof plugin === 'function' ? plugin() : plugin); +).map((plugin) => typeof plugin === 'string' || Array.isArray(plugin) + ? plugin + : plugin.plugin(plugin.options)); export default postcssConfig; diff --git a/packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/add-global-variable.tests.ts b/packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/add-global-variable.tests.ts index 472e04fc..402f8bea 100644 --- a/packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/add-global-variable.tests.ts +++ b/packages/arui-scripts/src/plugins/postcss-global-variables/utils/__tests__/add-global-variable.tests.ts @@ -18,17 +18,42 @@ describe('addGlobalVariable', () => { it('Должен рекурсивно добавлять вложенные переменные', () => { const mockRootSelector = new Rule({ selector: ':root' }); + const mockRootSelectorWithSpace = new Rule({ selector: ':root' }); + const mockRootSelectorWithNewLine = new Rule({ selector: ':root' }); + const parsedVariables = { '--color-primary': 'var(--color-secondary)', '--color-secondary': '#00ff00', }; + const parsedVariablesWithSpace = { + '--color-primary': 'var( --color-secondary )', + '--color-secondary': '#00ff00', + }; + + const parsedVariablesWithNewLine = { + '--color-primary': 'var(\n --color-secondary\n )', + '--color-secondary': '#00ff00', + }; + addGlobalVariable('var(--color-primary)', mockRootSelector, parsedVariables); + addGlobalVariable('var(--color-primary)', mockRootSelectorWithSpace, parsedVariablesWithSpace); + addGlobalVariable('var(--color-primary)', mockRootSelectorWithNewLine, parsedVariablesWithNewLine); expect(mockRootSelector.nodes).toMatchObject([ { prop: '--color-primary', value: 'var(--color-secondary)' }, { prop: '--color-secondary', value: '#00ff00' }, ]); + + expect(mockRootSelectorWithSpace.nodes).toMatchObject([ + { prop: '--color-primary', value: 'var( --color-secondary )' }, + { prop: '--color-secondary', value: '#00ff00' }, + ]); + + expect(mockRootSelectorWithNewLine.nodes).toMatchObject([ + { prop: '--color-primary', value: 'var(\n --color-secondary\n )' }, + { prop: '--color-secondary', value: '#00ff00' }, + ]); }); it('Не должен добавлять переменные, если их нет в parsedVariables', () => { diff --git a/packages/arui-scripts/src/plugins/postcss-global-variables/utils/utils.ts b/packages/arui-scripts/src/plugins/postcss-global-variables/utils/utils.ts index 281e56d1..75e60a9e 100644 --- a/packages/arui-scripts/src/plugins/postcss-global-variables/utils/utils.ts +++ b/packages/arui-scripts/src/plugins/postcss-global-variables/utils/utils.ts @@ -43,12 +43,12 @@ export const parseMediaQuery = (importedFile: Root, parsedCustomMedia: Record) { - const variableMatches = cssValue.match(/var\(--([^)]+)\)/g); + const variableMatches = cssValue.match(/var\(\s*--([^)]+)\s*\)/g); if (variableMatches) { variableMatches.forEach((match) => { // var(--gap-24) => --gap-24 - const variableName = match.slice(4, -1); + const variableName = match.slice(4, -1).trim(); if (parsedVariables[variableName]) { rootSelector.append(new Declaration({ prop: variableName, value: parsedVariables[variableName] })); From 834daed76b7072415c684067849ca76e8e33f936 Mon Sep 17 00:00:00 2001 From: Vladislav <56737476+VladislavNsk@users.noreply.github.com> Date: Thu, 5 Dec 2024 00:55:09 +0700 Subject: [PATCH 5/6] Update quick-starfishes-taste.md --- .changeset/quick-starfishes-taste.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.changeset/quick-starfishes-taste.md b/.changeset/quick-starfishes-taste.md index 8e255b90..5d792695 100644 --- a/.changeset/quick-starfishes-taste.md +++ b/.changeset/quick-starfishes-taste.md @@ -2,4 +2,25 @@ 'arui-scripts': minor --- -Добавлен кастомный плагин postcss-global-data, для оптимизации времени обработки глобальных переменных +Добавлен кастомный плагин postcss-global-variables, для оптимизации времени обработки глобальных переменных. +@csstools/postcss-global-data *удален* + +Проекты, которые использовали в оверрайдах кастомные настройки для плагина @csstools/postcss-global-data, должны перейти на использование postcss-global-variables следующим образом +``` +postcss: (config) => { + const overrideConfig = config.map((plugin) => { + if (plugin.name === 'postCssGlobalVariables') { + return { + ...plugin, + options: plugin.options.concat([ + // ваши файлы + ]) + } + } + return plugin; + }); + + return overrideConfig; +} +``` +Плагин работает только с глобальными переменными, если вам надо вставить что-то другое, отличное от глобальных переменных, вам нужно будет добавить @csstools/postcss-global-data в свой проект самостоятельно From 53896eb9a89b348a8bbe0f0db9efaf4af9b7d2d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=B1=D0=BC=D0=BE=D1=87=D0=B5=D0=B2=D1=81=D0=BA?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D1=81=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=20=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=D0=BE?= =?UTF-8?q?=D0=B2=D0=B8=D1=87?= Date: Thu, 5 Dec 2024 15:33:47 +0700 Subject: [PATCH 6/6] feat(*): add rootRule in rulesSelectors --- .../plugins/postcss-global-variables/postcss-global-variables.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts b/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts index bd3af460..0462d94e 100644 --- a/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts +++ b/packages/arui-scripts/src/plugins/postcss-global-variables/postcss-global-variables.ts @@ -35,6 +35,7 @@ const postCssGlobalVariables: PluginCreator = (opts?: PluginOptio const rootRule = insertParsedCss(root, parsedVariables, parsedCustomMedia); root.append(rootRule); + rulesSelectors.add(rootRule) }, OnceExit(): void { rulesSelectors.forEach((rule) => {