使用create-react-app新增css modules、sasss和antd

林大元發表於2018-07-29

前言

create-react-app是facebook的官方腳手架,對於個人開發者和中小型公司快速建立專案非常推薦。react的CSS解決方案有很多,這裡我技術選型時用css modulessass,然後配合antd使用通用元件庫。但是create-react-app原生並不支援css modulessass,所以需要額外配置。

配置

增加css modules和sass

使用eject暴露配置

create-react-app預設是沒有暴露webpack配置的,所以需要eject一下。注意如果專案在git倉庫環境下,先提交程式碼到git倉庫,否則會報錯

npm run eject
複製程式碼

npm新增css modules和sass

npm install react-css-modules 
npm install sass-loader node-sass
複製程式碼

這裡安裝sass可能會遇到牆的問題報錯,所以要麼使用cnpm或者使用本地代理設定,因為我有ss所以使用本地代理

// 開啟代理
npm config set proxy http://127.0.0.1:1080
// 安裝完sass後關閉代理
npm config delete proxy
複製程式碼

webpack配置

重點來了,我們需要給webpack配置上css-modulessass-loader。但是使用css-modules會使node_modules庫裡的css樣式找不到,比如後面要使用到的antd,這個時候我們需要inclube來排除影響node_modules,使得css-modules不會影響到node_modules

修改專案中config目錄下的webpack.config.dev.jswebpack.config.prod.js,說明下這兩個檔案,前一個是開發環境npm start使用,後一個是npm run build打包後使用

  • 修改webpack.config.dev.js:

大約在160行左右,找到test: /\.css$/,中文註釋的地方就是修改和增加的地方

          {
            test: [/\.css$/, /\.scss$/],// 這裡增加SCSS的支援
            exclude: [/node_modules/],// 這裡去排除node_modules,防止css modules影響到node_modules
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1,
                  modules: true, // 這裡增加對css modules的支援
                  localIdentName: '[name]__[local]__[hash:base64:5]' //這裡增加對css modules的支援
                },
              },
              {
                loader: require.resolve('sass-loader'), // 這裡增加sass的支援
              },
              {
                loader: require.resolve('postcss-loader'),
                options: {
                  // Necessary for external CSS imports to work
                  // https://github.com/facebookincubator/create-react-app/issues/2677
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-flexbugs-fixes'),
                    autoprefixer({
                      browsers: [
                        '>1%',
                        'last 4 versions',
                        'Firefox ESR',
                        'not ie < 9', // React doesn't support IE8 anyway
                      ],
                      flexbox: 'no-2009',
                    }),
                  ],
                },
              },
            ],
          },
          // 因為上面排除了css_modules所以這裡一定要再新增個排除src來識別css_modules
          // 其實就是複製之前沒修改前的所有,再增加一個exclude: [/src/]
          {
            test: /\.css$/, 
            exclude: [/src/], // 這裡新增排除src,
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1,
                },
              },
              {
                loader: require.resolve('postcss-loader'),
                options: {
                  // Necessary for external CSS imports to work
                  // https://github.com/facebookincubator/create-react-app/issues/2677
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-flexbugs-fixes'),
                    autoprefixer({
                      browsers: [
                        '>1%',
                        'last 4 versions',
                        'Firefox ESR',
                        'not ie < 9', // React doesn't support IE8 anyway
                      ],
                      flexbox: 'no-2009',
                    }),
                  ],
                },
              },
            ],
          }
複製程式碼
  • 修改webpack.config.prod.js:

和上面修改webpack.config.dev.js類似

        {
            test: [/\.css$/, /\.scss$/], // 這裡增加SCSS的支援
            exclude: [/node_modules/], // 這裡去排除node_modules
            loader: ExtractTextPlugin.extract(
              Object.assign(
                {
                  fallback: {
                    loader: require.resolve('style-loader'),
                    options: {
                      hmr: false,
                    },
                  },
                  use: [
                    {
                      loader: require.resolve('css-loader'),
                      options: {
                        importLoaders: 1,
                        minimize: true,
                        sourceMap: true,
                        modules: true, // 這裡新增css modules支援
                      },
                    },
                    {
                      loader: require.resolve('postcss-loader'),
                      options: {
                        // Necessary for external CSS imports to work
                        // https://github.com/facebookincubator/create-react-app/issues/2677
                        ident: 'postcss',
                        plugins: () => [
                          require('postcss-flexbugs-fixes'),
                          autoprefixer({
                            browsers: [
                              '>1%',
                              'last 4 versions',
                              'Firefox ESR',
                              'not ie < 9', // React doesn't support IE8 anyway
                            ],
                            flexbox: 'no-2009',
                          }),
                        ],
                      },
                    },
                    {
                      loader: require.resolve('sass-loader'), // 這裡新增sass支援
                    }
                  ],
                },

                extractTextPluginOptions
              )
            ),
            // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
          },
          {
            test: /\.css$/,
            exclude: [/src/], // 排除src
            loader: ExtractTextPlugin.extract(
              Object.assign(
                {
                  fallback: {
                    loader: require.resolve('style-loader'),
                    options: {
                      hmr: false,
                    },
                  },
                  use: [
                    {
                      loader: require.resolve('css-loader'),
                      options: {
                        importLoaders: 1,
                        minimize: true,
                        sourceMap: true,
                      },
                    },
                    {
                      loader: require.resolve('postcss-loader'),
                      options: {
                        // Necessary for external CSS imports to work
                        // https://github.com/facebookincubator/create-react-app/issues/2677
                        ident: 'postcss',
                        plugins: () => [
                          require('postcss-flexbugs-fixes'),
                          autoprefixer({
                            browsers: [
                              '>1%',
                              'last 4 versions',
                              'Firefox ESR',
                              'not ie < 9', // React doesn't support IE8 anyway
                            ],
                            flexbox: 'no-2009',
                          }),
                        ],
                      },
                    }
                  ],
                },

                extractTextPluginOptions
              )
            ),
            // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
          }
複製程式碼

安裝antd和配置

主要是安裝配置antdbabel-plugin-import,這樣可以使得antd按需載入樣式

npm新增antd和babel-plugin-import

npm install antd
npm install babel-plugin-import
複製程式碼

配置babel

在專案根目錄下增加.babelrc檔案,然後配置如下

{
  "presets": [
    "react-app"
  ],
  "plugins": [
    "transform-runtime",
    [
      "import",
      {
        "libraryName": "antd",
        "style": "css"
      }
    ]
  ]
}
複製程式碼

大功告成

相關文章