用 postcss 协调 antd 导入

问题描述

我正在尝试使用 postcss-env-function 以便能够在 javascript 和 less/css 之间共享变量。我在构建过程中收到以下错误。如果我删除 index.less 的第一行,错误就会消失:

@import '~antd/dist/antd.less';

不过,那我就拿不到antd的style了。 (如果我删除 postcss-loader 也没有错误)。如何解决这个问题?

Minimal repository


错误

ERROR in ./src/styles/index.less (./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./node_modules/less-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./src/styles/index.less)
Module build Failed (from ./node_modules/postcss-loader/dist/cjs.js):
SyntaxError

(1:1) postcss-env-fn: <css input> UnkNown word

> 1 | opacity=45

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const copyPlugin = require('copy-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const path = require('path');
const fs = require('fs');

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

function buildConfig(args) {
  var rootConfig = {
    entry: './src/index.tsx',output: {
      path: path.resolve(__dirname,'dist'),filename: 'app.[fullhash].js'
    },resolve: {
      extensions: ['.ts','.tsx','.js','.json']
    },devtool: (args && args.production ? false : 'inline-cheap-source-map'),devServer: {
      contentBase: './dist',disableHostCheck: true,hot: true,historyApiFallback: true,proxy: {
        '/api': {
          target: `https://${process.env.API_HOST}:8081`,secure: false,}
      },https: {
        key: fs.readFileSync(process.env.SSL_KEY_FILE),cert: fs.readFileSync(process.env.SSL_CERT_FILE),}
    },module: {
      rules: [
        {
          test: /\.(ts|js)x?$/,exclude: /node_modules/,loader: 'babel-loader',},{
          test: /\.(c|le)ss$/,use: [
            { loader: 'style-loader' },{ loader: 'css-loader',options: { importLoaders: 1 } },{ loader: 'postcss-loader',options: {
              postcssOptions: {
                ident: 'postcss',plugins: { 'postcss-env-function': { importFrom: { environmentvariables: { '--test': '200px' } } } }
              } } },{ loader: 'less-loader',options: { lessOptions: { javascriptEnabled: true } } },]
        },{
          test: /\.(png|svg|jpg|gif|woff|woff2|eot|ttf|otf|jpeg)$/,use: [
            { loader: 'file-loader' },]
        }
      ],plugins: [
      new HtmlWebpackPlugin({
        inject: true,template: require('html-webpack-template'),devServer: (args && args.production) ? undefined : `https://${process.env.BUBI_API_HOST}:8080`,Meta: [
          {
            name: 'og:title',content: 'frontend-react'
          },{
            name: 'og:description',content: 'React app'
          },],mobile: true,lang: 'en-GB',title: 'frontend-react',scripts: [
        ],}),new copyPlugin([
        { from: 'static_assets/',to: '' },]),};

  if (args && args.production) {
    rootConfig = {
      ...rootConfig,optimization: {
        minimize: true,minimizer: [new TerserPlugin({
          extractComments: 'all',})],usedExports: true,};
  }

  return rootConfig;
}

module.exports = buildConfig;

版本: 少加载器:8.1.1 postcss:8.3.5 postcss-loader:6.1.1

index.less 的开头:

@import '~antd/dist/antd.less'; 

@shadow: 0px 0px 15px rgba(0,0.08);
@body-background-color: #f7fafc;

.text {
  font-family: "HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
  font-weight: 300;
}

body {
  background-color: @body-background-color;
  padding: 0; 
  overflow-x: hidden;
}

package.json

declare module '*.jpg';
declare module '*.jpeg';
declare module '*.png';

.babelrc

{
    "presets": [
        "@babel/preset-env","@babel/preset-typescript","@babel/preset-react"
    ],"plugins": [
        "@babel/plugin-proposal-class-properties"
    ]
}

解决方法

看起来您编译的 CSS 包含 filter: alpha(opacity=45);,而 postcss-env-function 不喜欢。

“未知词”异常由 postcss-values-parser 抛出(postcss-env-function 使用它来解析 CSS 声明值)。

理想情况下,您可以将 ignoreUnknownWords 选项传递给 postcss-values-parser 以忽略该 filter: alpha 声明,但 postcss-env-function 不允许您这样做。

因此,可能的解决方案是修改 postcss-env-function,以便您可以将 ignoreUnknownWords 选项传递给解析器。

另一种可能的解决方案是从您的 CSS 中删除所有 filter: alpha(opacity=#) 声明,因为只有 IE8 及以下版本支持它。例如,您可以创建一个简单的函数“插件”,遍历所有 filter: 声明并在其值以“alpha”开头时将其删除:

webpack.config.js:

{ loader: 'postcss-loader',options: {
  postcssOptions: {
    ident: 'postcss',plugins: [
      root => root.walkDecls('filter',decl => {
        if (decl.value.startsWith('alpha')) decl.remove();
      }),{ 'postcss-env-function': { importFrom: { environmentVariables: { '--test': '200px' } } } },],}
} },
,

这似乎是关于您的不透明度的语法错误。最常见的样式使用对象,因此您可以将不透明度声明为:

pip install python-engineio==3.14.2 python-socketio==4.6.0

我不完全确定如何减少工作量,因为我主要使用 sass、scss 和 css,但是,我相信您的问题在于将不透明度声明为 style = { opacity:"45%" } 而不是 {opacity=45}。发布您的样式代码以查看语法错误会很有帮助,但我会开始查看。