关于create-react-app扩展webpack配置(less, vw)

517 阅读3分钟

create-react-app(cra)是react官方的脚手架工具,它集成了babel,webpack,wekpack-dev-server等。

我通过cra创建了一个react项目,我需要我的项目支持less,并且做vw适配。所以我需要扩展cra的webpack配置。我知道的可以通过两个方法:

    1. 通过npm run eject,暴露cra项目的webpack配置文件webpack.config.js,修改这个文件。直接修改它的配置感觉不是很好,于是我们使用第2种方法。
    1. 使用react-app-rewired,它是一个cra再配置的工具,可以使用它对cra的webpack配置进行扩展。下面是具体做法。

    首先需要安装依赖,我这里使用的是react-app-rewired2.x的版本,所以我需要安装 react-app-rewired和cra-customize。

    cnpm i react-app-rewired cra-customize -D

    然后需要在项目根目录下创建一个config-overrides.js文件来做扩展的配置,原理是把cra的默认配置和我们扩展的配置合并,然后暴露出去。

    const {override} = require('customize-cra');
        module.exports = {webpack: override()}
    

    接着我们需要修改 package.json 中的脚本命令

    "scripts": {
        "start": "react-app-rewired start",
        "build": "react-app-rewired build",
        "test": "react-app-rewired test",
        "eject": "react-scripts eject"
    },
    

    接下来我们可以扩展webpack配置了。

    怎么配置less

    首先还是先安装依赖 less less-loader。

    cnpm i less less-loader -D

    然后修改config-overrides.js const {override, addLessLoader} = require('customize-cra');

    module.exports = {
        webpack: override(
            addLessLoader({
                strictMath: true,
                noIeCompat: true
            })
        )
    }
    

    怎么配置vw适配

    首先还是安装依赖:

      postcss-aspect-ratio-mini:核心,为了实现宽高比。
      postcss-px-to-viewport: 核心,用来把px单位转换为vw、vh、vmin或者vmax这样的视窗单位。我们在写代码是时候可以直接用设计图的px来写就可以了。
      postcss-write-svg:核心,为了解决1px的问题,自动生成border-image或者background-image的图片。
      postcss-viewport-units:核心,要解决vw兼容性的问题(csshack)。postcss-viewport-units会给css自动添加content属性,例如(content:"viewport-units-buggyfill; width: 100vw"),而viewport-units-buggyfill能帮我们正确的解析vw。
      cssnano:核心,将你的 CSS 文件做 多方面的的优化,以确保最终生成的文件 对生产环境来说体积是最小的。
      cssnano-preset-advanced:cssnano的配置中使用了preset: "advanced"配置
      postcss-flexbugs-fixes 
      postcss-preset-env 
    
    cnpm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano cssnano-preset-advanced --D
    

    接下来修改config-overrides.js文件。

    const {override, addLessLoader, addPostcssPlugins} = require('customize-cra');
    
    module.exports = {
        webpack: override(
            addLessLoader({
                strictMath: true,
                noIeCompat: true
            }),
            addPostcssPlugins([
                require('postcss-flexbugs-fixes'),
                require('postcss-preset-env')({
                    autoprefixer: {
                        flexbox: 'no-2009',
                    },
                    stage: 3,
                }),
                require('postcss-aspect-ratio-mini')({}),
                require('postcss-px-to-viewport')({
                    viewportWidth: 750, // (Number) The width of the viewport.
                    viewportHeight: 1334, // (Number) The height of the viewport.
                    unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
                    viewportUnit: 'vw', // (String) Expected units.
                    selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px.
                    minPixelValue: 150, // (Number) Set the minimum pixel value to replace.
                    mediaQuery: false // (Boolean) Allow px to be converted in media queries.
                }),
                require('postcss-write-svg')({
                    utf8: false
                }),
                require('postcss-viewport-units')({}),
                require('cssnano')({
                    preset: "advanced",
                    autoprefixer: false,
                    "postcss-zindex": false
                })
            ])
        )
    }
    

    为了修复某些浏览器中关于viewport的兼容性问题,我们还需要引入viewport-units-buggyfill.js和viewport-units-buggyfill.hacks.js,并加入一段代码。操作在根目录的index.html中。

    <script src="//g.alicdn.com/fdilab/lib3rd/viewport-units-buggyfill/0.6.2/??viewport-units-buggyfill.hacks.min.js,viewport-units-buggyfill.min.js"></script>
    <script> 
        window.onload = function () {
            window.viewportUnitsBuggyfill.init({
                hacks: window.viewportUnitsBuggyfillHacks
            }); 
        } 
    </script>
    

    完结撒花