diff --git a/packages/cli/package.json b/packages/cli/package.json index f5f7dea..8a87eef 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -42,6 +42,7 @@ "postcss-preset-env": "^7.0.2", "postcss-reporter": "^7.0.4", "resolve": "^1.19.0", + "stylis": "^3.5.4", "terser-webpack-plugin": "^5.3.0", "thread-loader": "^3.0.4", "tslib": "^2.3.0", diff --git a/packages/cli/src/config/postcssStylis.ts b/packages/cli/src/config/postcssStylis.ts new file mode 100644 index 0000000..92cef99 --- /dev/null +++ b/packages/cli/src/config/postcssStylis.ts @@ -0,0 +1,43 @@ +/* eslint-disable import/no-import-module-exports */ +import type { PluginCreator } from 'postcss'; +import stylis from 'stylis'; + +interface Options {} + +const postcssStylis: PluginCreator = () => ({ + postcssPlugin: 'postcss-stylis', + Once(root, postcss) { + const oldNodes = [...root.nodes]; + root.removeAll(); + for (const node of oldNodes) { + if (node.type === 'rule' && node.nodes.length) { + const startOffset = node.first?.source?.start?.offset; + const endOffset = node.last?.source?.end?.offset; + if (startOffset !== null && endOffset !== null) { + const css = node.source?.input.css.slice(startOffset, endOffset); + if (css !== undefined) { + let newCss: string; + try { + newCss = stylis(node.selector, css); + } catch (error) { + postcss.result.warn(`${error}`, { + node, + }); + throw error; + } + const tmpRoot = postcss.parse(newCss); + tmpRoot.each(newNode => { + root.append(newNode); + }); + continue; + } + } + } + root.append(node); + } + }, +}); + +postcssStylis.postcss = true; + +module.exports = postcssStylis; diff --git a/packages/cli/src/config/webpack.config.ts b/packages/cli/src/config/webpack.config.ts index b980abc..328d7cc 100644 --- a/packages/cli/src/config/webpack.config.ts +++ b/packages/cli/src/config/webpack.config.ts @@ -193,6 +193,7 @@ export const getWebpackConfig = ({ configFile: require.resolve('./linaria.config'), sourceMap: true, cacheProvider: require.resolve('./linariaFileCache'), + preprocessor: 'none', babelOptions: { // always use internal babel.config.js file configFile: require.resolve('./babel.config'), @@ -273,6 +274,17 @@ export const getWebpackConfig = ({ }, }, }, + { + loader: require.resolve('postcss-loader'), + options: { + implementation: require.resolve('postcss'), + postcssOptions: { + config: false, + // eslint-disable-next-line global-require + plugins: [require('./postcssStylis')()], + }, + }, + }, { loader: require.resolve('postcss-loader'), options: {