create-react-app 建立项目有关 less 的若干问题

在上篇文章使用 Eject 方式在 create-react-app 中使用 Ant Design of React中, 使用 create-react-app 建立了 React 项目,并使用 Eject 方式暴露出了 webpack 的配置,并成功按需引入了 antd。本文主要内容:解决 create-react-app 建立项目后 less 不生效的问题;antd 按需引入 less 源文件,以及遇到的 bezierEasing.less 文件报错问题;antd 本地字体的配置方法;less 使用 css module 的配置。javascript

直接引入less样式不生效

建立 test.less,并在 App.js 中引入css

.test {
  color: red;
}
复制代码
// App.js
...
import './test.less'
...
 <div className="test">test</div>
 <Button type="primary">Button</Button>
...
复制代码

发现 test 的颜色并无生效,由于 create-react-app 没有内置 less-loaderjava

安装 lessless-loader ,并修改 webpack 配置

$ cnpm i less less-loader --save-dev
复制代码

修改 webpack 配置 修改 webpack.config.dev.jswebpack.config-prod.js 配置文件, 增长less文件配置:node

// webpack.config.dev.js
...
  {
    test: /\.less$/,
    use: [
      require.resolve('style-loader'),
      {
        loader: require.resolve('css-loader'),
        options: {
          importLoaders: 1,
        },
      },
      {
        loader: require.resolve('less-loader') // compiles Less to CSS
      }
    ],
  },
...
复制代码

重启项目后,less样式已经生效react

antd 的样式使用 less 源文件方式引入

babel-plugin-import 中对 style 有这样对说明:webpack

["import", { "libraryName": "antd" }] : import js modularlygit

["import", { "libraryName": "antd", "style": true }] : import js and css modularly (LESS/Sass source files)github

["import", { "libraryName": "antd", "style": "css" }] : import js and css modularly (css built files)web

修改package.json,将style的值改成truenpm

...
  "babel": {
    "presets": [
      "react-app"
     ]
     ],
    "plugins": [
      ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": true }]
    ]
  }
...
复制代码

重启以后,编译错误,提示 bezierEasing.less 文件的 .bezierEasingMixin() 方法报错:

按照报错提供的 issue 地址查看 : issues/44

缘由是由于 less v3 以后废弃了 Enable Inline JavaScript Option :lesscss.org/usage/#less…

主要有2种解决方式

  • 将 less 版本降到 3.0 如下
  • less loader 增长配置,开启 JavaScript :
// webpack.config.dev.js
...
  {
- loader: require.resolve('less-loader') // compiles Less to CSS
+ loader: require.resolve('less-loader'), // compiles Less to CSS
+ options: {
+ javascriptEnabled: true
+ }
    
  }
复制代码

从新 npm start,项目能够正常启动。

antd使用本地字体 iconfont

2018年9月5日更新,9月开学季, ant design 系列迎来了一系列的重大更新。umi 迎来了 2.0 版本, 随之而来的是 ant design pro 使用 umi 2.0 构建的 2.0 版本。 今天注意到 ant design 的 3.9.0 版本一个重大的更新是对 Icon 进行了重构, 使用 SVG 代替以前的 css font icon。因此若是使用 ant design 3.9.0 以上的版本, 就不会存在离线找不到字体文件的问题了。若是你使用的 ant design 在 3.9.0 版本如下,能够参考下文离线使用 iconfont 的方式。

Ant Design 默认的 iconfont 文件托管在 iconfont.cn 并默认使用平台提供的 alicdn 地址,公网可访问使用。

因为 alicdn 对部分域名有访问限制,或者须要内网环境使用,须要将字体下载到本地

最新的 iconfont 文件能够到 此连接 下载。

下载后将字体文件放入 public/iconfont/ 路径下

因为项目使用的是 create-react-app 建立项目,且antd的样式使用babel-plugin-import按需加载样式,因此只能采用 定制主题中的 less-loadermodifyVars 配置来覆盖原来的样式变量。

具体改动 修改 webpack.config.dev.jswebpack.config-prod.js 配置文件

// webpack.config.dev.js
...
  {
     loader: require.resolve('less-loader'), // compiles Less to CSS
     options: {
        javascriptEnabled: true,
        modifyVars: {
          "icon-url": "'/public/iconfont/iconfont'"
        }
     }
  }
复制代码

重启项目,成功引入了本地字体

须要注意的是webpack.config-prod.js文件中的icon-url路径须要将public替换为生产环境项目文件路径,打包以后public中的文件和文件夹直接复制到bulid路径下。使用相对路径会报错没法编译,这点不知道有没有更好的处理方式,但愿读者大神们提供更好的方式。

// webpack.config-prod.js
...
  {
     loader: require.resolve('less-loader'), // compiles Less to CSS
     options: {
        javascriptEnabled: true,
        modifyVars: {
          "icon-url": "'/your-project-name/iconfont/iconfont'"
        }
     }
  }
复制代码

css module 形式引入less

增长css-loader的配置

{
            test: /\.less$/,
            // exclude: [/node_modules/],
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                   importLoaders: 1,
+ modules: true
                },
              },
              {
                loader: require.resolve('less-loader'), // compiles Less to CSS
                options: {
                  javascriptEnabled: true,
                  modifyVars: {
                    "icon-url": "'/public/iconfont/iconfont'"
                  }
                }
              }
            ],
          },
复制代码

修改App.js,使用css module方式引入

- import './test.less'
+ import styles from './test.less'

    class App extends Component {
      render() {
        return (
          <div className="App">
- <div className="test">test</div>
+ <div className={styles.test}>test</div>
            <Button type="primary">Button</Button>
          </div>
        );
      }
    }
复制代码

重启项目,css module引入的test样式生效了,可是antd的按钮样式失效了

须要修改 webpack.config.dev.js,只对src中的less文件开启css module,这里写法有点麻烦,应该有更好的方式。

// webpack.config.dev.js
...
          {
            test: /\.less$/,
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1
                },
              },
              {
                loader: require.resolve('less-loader'), // compiles Less to CSS
                options: {
                  javascriptEnabled: true,
                  modifyVars: {
                    "icon-url": "'/public/iconfont/iconfont'"
                  }
                }
              }
            ],
          },
          {
            test: /\.less$/,
            include: [/src/],
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1,
                  modules: true
                },
              }
            ],
          },
...
复制代码

2018-08-02更新,评论区有兄弟留言说从新npm install后,css module引入的样式失效了,今天测试了一下确实有这个问题,试着改了上面的对less文件处理的loader顺序能够解决这个问题,可是原理不是很清楚,还请了解原理的兄弟帮忙指点,多谢

// webpack.config.dev.js
...
          {
            test: /\.less$/,
            include: [/src/],
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1,
                  modules: true
                },
              }
            ],
          },
          {
            test: /\.less$/,
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1
                },
              },
              {
                loader: require.resolve('less-loader'), // compiles Less to CSS
                options: {
                  javascriptEnabled: true,
                  modifyVars: {
                    "icon-url": "'/public/iconfont/iconfont'"
                  }
                }
              }
            ],
          },
...
复制代码

总结

本文在ejectcreate-react-app的项目基础上,按需引入了antd,遇到了有关less的若干问题:解决了less文件不生效的问题,内网环境使用本地iconfont的配置方式,css module的配置方式。本文还有一些配置方式不是最优的方式,但愿各位可以给出更好的方案。

最近在起步 React,准备记录如下本身的学习和踩坑过程。下一篇文章应该是dva的使用。

参考资料

相关文章
相关标签/搜索