Skip to content

Commit

Permalink
refactor CSS unit transforming
Browse files Browse the repository at this point in the history
  • Loading branch information
malash committed Nov 29, 2023
1 parent b361ca7 commit c5c77e5
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 40 deletions.
75 changes: 52 additions & 23 deletions packages/cli/src/config/postcssConfig.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,58 @@
/* eslint-disable global-require */

export type TransformUnit = 'keep' | 'to-px' | 'to-rpx';

const getTransformUnitsPlugin = (unit: TransformUnit) => {
switch (unit) {
case 'keep':
return [];
case 'to-px':
// use this plugin because some plugins, like postcss-calc, don't support `rpx` unit
return [
require('./postcssTransformUnit')({
divisor: 2,
multiple: 1,
sourceUnit: 'rpx',
targetUnit: 'px',
}),
];
case 'to-rpx':
return [
require('./postcssTransformUnit')({
divisor: 1,
multiple: 2,
sourceUnit: 'px',
targetUnit: 'rpx',
}),
];
default:
throw new Error(`Unknown unit ${unit}`);
}
};

// to improve PostCSS performance, we should always use `require(name)(options)` rather than `[name, options]`
// also we should set `postcssOptions.config` to `false` to avoid loading any `postcss.config.js`
// TODO: hope PostCSS could fix this issue https://github.com/csstools/postcss-preset-env/issues/232#issuecomment-992263741
export default {
plugins: [
require('postcss-each')(),
// TODO: `postcss-nesting` from `postcss-preset-env` output `:is` pseudo-class that
// Mini Programs don't support.
// We have to `postcss-nested` manually before them to prevent `:is` being created.
require('postcss-nested'),
require('postcss-preset-env')({
stage: 0,
preserve: false, // for reducing file size
insertAfter: {
// postcss-calc must run before autoprefixer
'environment-variables': require('postcss-calc')(),
},
}),
// use postcss-px2units because some plugins, like postcss-calc, don't support `rpx` unit
require('./postcssPx2units')({
multiple: 2,
targetUnits: 'rpx',
}),
require('cssnano')({ preset: 'default' }),
require('postcss-reporter')({ clearReportedMessages: true }),
],
export default ({ unit }: { unit: TransformUnit }) => {
const transformUnitPlugin = getTransformUnitsPlugin(unit);

return {
plugins: [
require('postcss-each')(),
// TODO: `postcss-nesting` from `postcss-preset-env` output `:is` pseudo-class that Mini Programs don't support.
// We have to use `postcss-nested` manually before them to prevent `:is` being created.
require('postcss-nested'),
require('postcss-preset-env')({
stage: 0,
preserve: false,
insertAfter: {
// postcss-calc must run before autoprefixer
'environment-variables': require('postcss-calc')(),
},
}),
...transformUnitPlugin,
require('cssnano')({ preset: 'default' }),
require('postcss-reporter')({ clearReportedMessages: true }),
],
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,41 @@ interface Options {
divisor: number;
multiple: number;
decimalPlaces: number;
targetUnits: string;
sourceUnit: string;
targetUnit: string;
comment: string;
}

const DEFAULT_OPTIONS: Options = {
divisor: 1,
multiple: 1,
decimalPlaces: 2,
targetUnits: 'rpx',
sourceUnit: 'px',
targetUnit: 'rpx',
comment: 'no',
};

const postcssPx2units: PluginCreator<Partial<Options>> = (options = {}) => {
const postcssTransformUnit: PluginCreator<Partial<Options>> = (options = {}) => {
const mergedOptions = { ...DEFAULT_OPTIONS, ...options };

const replacePx = (str: string) => {
if (!str) {
return '';
}

return str.replace(/\b(\d+(\.\d+)?)px\b/gi, (match, x) => {
const size = (x * mergedOptions.multiple) / mergedOptions.divisor;
return size % 1 === 0
? size + mergedOptions.targetUnits
: size.toFixed(mergedOptions.decimalPlaces) + mergedOptions.targetUnits;
});
return str.replace(
new RegExp(`\\b(\\d+(\\.\\d+)?)${mergedOptions.sourceUnit}\\b`, 'g'),
(_match, x) => {
const size = (x * mergedOptions.multiple) / mergedOptions.divisor;
return size % 1 === 0
? size + mergedOptions.targetUnit
: size.toFixed(mergedOptions.decimalPlaces) + mergedOptions.targetUnit;
},
);
};

return {
postcssPlugin: 'postcss-px2units',
postcssPlugin: 'postcss-transform-unit',
Declaration(declaration) {
const nextNode = declaration.next();
if (nextNode?.type === 'comment' && nextNode.text === mergedOptions.comment) {
Expand All @@ -48,6 +53,6 @@ const postcssPx2units: PluginCreator<Partial<Options>> = (options = {}) => {
};
};

postcssPx2units.postcss = true;
postcssTransformUnit.postcss = true;

module.exports = postcssPx2units;
module.exports = postcssTransformUnit;
8 changes: 5 additions & 3 deletions packages/cli/src/config/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import resolve from 'resolve';
import { version as gojiCliVersion } from '@goji/cli/package.json';
import { version as babelCoreVersion } from '@babel/core/package.json';
import { version as babelLoaderVersion } from 'babel-loader/package.json';
import postcssConfig from './postcssConfig';
import postcssConfig, { TransformUnit } from './postcssConfig';
import { getThreadLoader } from './loaders';

const getSourceMap = (nodeEnv: string, target: GojiTarget): webpack.Configuration['devtool'] => {
Expand Down Expand Up @@ -46,6 +46,7 @@ export const getWebpackConfig = ({
watch,
progress,
nohoist,
cssUnit,
parallel,
}: {
basedir: string;
Expand All @@ -57,6 +58,7 @@ export const getWebpackConfig = ({
watch: boolean;
progress: boolean;
nohoist?: GojiWebpackPluginOptions['nohoist'];
cssUnit: TransformUnit;
parallel?: {
minimize?: number;
loader?: number;
Expand Down Expand Up @@ -230,7 +232,7 @@ export const getWebpackConfig = ({
implementation: require.resolve('postcss'),
postcssOptions: {
config: false,
...postcssConfig,
...postcssConfig({ unit: cssUnit }),
},
},
},
Expand Down Expand Up @@ -267,7 +269,7 @@ export const getWebpackConfig = ({
implementation: require.resolve('postcss'),
postcssOptions: {
config: false,
...postcssConfig,
...postcssConfig({ unit: cssUnit }),
},
},
},
Expand Down
5 changes: 5 additions & 0 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { GojiWebpackPluginOptions } from '@goji/webpack-plugin';
import { getWebpackConfig } from './config/webpack.config';
import { parseArgv, CliConfig } from './argv';
import './utils/fixSerializationWarning';
import { TransformUnit } from './config/postcssConfig';

interface GojiConfig {
watch?: boolean;
Expand All @@ -13,6 +14,9 @@ interface GojiConfig {
configureBabel?: (config: any) => any;
progress?: boolean;
nohoist?: GojiWebpackPluginOptions['nohoist'];
css?: {
unit?: TransformUnit;
};
parallel?:
| {
minimize?: number;
Expand Down Expand Up @@ -67,6 +71,7 @@ const main = async () => {
watch,
progress: gojiConfig.progress ?? cliConfig.progress ?? true,
nohoist: gojiConfig?.nohoist,
cssUnit: gojiConfig?.css?.unit ?? 'to-rpx',
parallel:
typeof gojiConfig.parallel === 'number'
? { loader: gojiConfig.parallel, minimize: gojiConfig.parallel }
Expand Down
6 changes: 5 additions & 1 deletion packages/demo-todomvc-linaria/goji.config.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
module.exports = {};
module.exports = {
css: {
unit: 'to-px',
},
};
6 changes: 5 additions & 1 deletion packages/demo-todomvc/goji.config.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
module.exports = {};
module.exports = {
css: {
unit: 'to-px',
},
};

0 comments on commit c5c77e5

Please sign in to comment.