react工程搭建系列之---基于create-react-app使用antd-mobile

一、引入antd-mobile

1.安装

npm install antd-mobile --save

2.使用

/* src/App.js */
import {Button} from 'antd-mobile';
import 'antd-mobile/lib/button/style/css'  需要手动引入样式
class App extends Component {
  render() {
    return (
      <div className="App">
        <Button type='primary'>primary</Button>
      </div>
    );
  }
}

二、安装及配置react-app-rewired

1.安装react-app-rewired

npm install react-app-rewired --save-dev

2.修改package.json

/* package.json */
"scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test",
+   "test": "react-app-rewired test",
}

3.在项目根目录创建 config-overrides.js文件

由于使用creact-react-app创建的项目所以修改默认配置没那么方便,需要通过此文件修改默认配置

module.exports = function override(config, env) {
    // do stuff with the webpack config...
    console.log(config);
    return config;
};

运行npm run start打印出来的config,可以看出这是webpack的开发环境配置

mode: 'development',
  devtool: 'cheap-module-source-map',
  entry: 
   [ '/Users/surui/Desktop/my-react-app/node_modules/react-dev-utils/webpackHotDevClient.js',
     '/Users/surui/Desktop/my-react-app/src/index.js' ],
  output: 
   { pathinfo: true,
     filename: 'static/js/bundle.js',
     chunkFilename: 'static/js/[name].chunk.js',
     publicPath: '/',
     devtoolModuleFilenameTemplate: [Function: devtoolModuleFilenameTemplate] },
  optimization: 
   { splitChunks: { chunks: 'all', name: false },
     runtimeChunk: true },
  resolve: 
   { modules: [ 'node_modules' ],
     extensions: [ '.mjs', '.web.js', '.js', '.json', '.web.jsx', '.jsx' ],
     alias: { 'react-native': 'react-native-web' },
     plugins: [ [Object], [Object] ] },
  resolveLoader: { plugins: [ [Object] ] },
  module: 
   { strictExportPresence: true,
     rules: [ [Object], [Object], [Object] ] },
  plugins: 
   [ HtmlWebpackPlugin {
       options: [Object],
       childCompilerHash: undefined,
       childCompilationOutputName: undefined,
       assetJson: undefined,
       hash: undefined,
       version: 4 },
     InterpolateHtmlPlugin { htmlWebpackPlugin: [Object], replacements: [Object] },
     ModuleNotFoundPlugin {
       appPath: '/Users/surui/Desktop/my-react-app',
       yarnLockFile: undefined,
       useYarnCommand: [Function: bound useYarnCommand],
       getRelativePath: [Function: bound getRelativePath],
       prettierError: [Function: bound prettierError] },
     DefinePlugin { definitions: [Object] },
     HotModuleReplacementPlugin {
       options: {},
       multiStep: undefined,
       fullBuildTimeout: 200,
       requestTimeout: 10000 },
     CaseSensitivePathsPlugin { options: {}, pathCache: {}, fsOperations: 0, primed: false },
     WatchMissingNodeModulesPlugin {
       nodeModulesPath: '/Users/surui/Desktop/my-react-app/node_modules' },
     IgnorePlugin {
       options: [Object],
       checkIgnore: [Function: bound checkIgnore] },
     ManifestPlugin { opts: [Object] } ],

4.使用babel-plugin-import用于按需加载组件代码和样式

第一步:安装

npm install babel-plugin-import --save-dev

第二步:修改config-overrides.js文件

const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
    // do stuff with the webpack config...
    config = injectBabelPlugin(['import', {
        libraryName: 'antd-mobile',
        style: 'css',
        // style: true, // use less for customized theme
    }], config);
    return config;
};

如果样式用css那么style:'css,如果用less那么style: true

第三步:然后只需从 antd-mobile 引入模块即可,无需单独引入样式

/* src/App.js */
import {Button} from 'antd-mobile';
class App extends Component {
  render() {
    return (
      <div className="App">
        <Button type='primary'>primary</Button>
      </div>
    );
  }
}

5.样式与定制主题

less

antd-mobile 的样式使用了 Less 作为开发语言

第一步:安装less less-loader

npm install --save-dev less less-loader

第二步:在 package.json 文件中添加一个 theme 字段,里面将包含所有我们想要修改的主题样式

"theme": {
    "brand-primary": "red",
    "color-text-base": "#333"
  },

第三步:修改config-overrides.js文件,覆盖webpack配置

const { injectBabelPlugin, getLoader } = require('react-app-rewired');
const autoprefixer = require('autoprefixer');
const theme = require('./package.json').theme;
const fileLoaderMatcher = function (rule) {
    return rule.loader && rule.loader.indexOf(`file-loader`) != -1;
}
module.exports = function override(config, env) {
    // do stuff with the webpack config...
    config = injectBabelPlugin(['import', {
        libraryName: 'antd-mobile',
        // style: 'css',
        style: true, // use less for customized theme
    }], config);
    console.log(config.module.rules[2].oneOf);
    config.module.rules[2].oneOf.unshift(
        {
            test: /\.less$/,
            use: [
                require.resolve('style-loader'),
                require.resolve('css-loader'),
                {
                    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('less-loader'),
                    options: {
                        // theme vars, also can use theme.js instead of this.
                        modifyVars: theme,
                    },
                },
            ]
        }
    );

    // file-loader exclude
    let l = getLoader(config.module.rules, fileLoaderMatcher);
    l.exclude.push(/\.less$/);

    return config;
};

scss

第一步:安装sass-loader

npm install --save-dev sass-loader

第二步:修改config-overrides.js文件,覆盖webpack配置

const { injectBabelPlugin, getLoader } = require('react-app-rewired');
const autoprefixer = require('autoprefixer');
const theme = require('./package.json').theme;
const fileLoaderMatcher = function (rule) {
    return rule.loader && rule.loader.indexOf(`file-loader`) != -1;
}
module.exports = function override(config, env) {
    // do stuff with the webpack config...
    config = injectBabelPlugin(['import', {
        libraryName: 'antd-mobile',
        // style: 'css',
        style: true, // use less for customized theme
    }], config);
    console.log(config.module.rules[2].oneOf);

    // sass
    config.module.rules[2].oneOf.unshift(
        {
            test: /\.scss$/,
            use: [
                require.resolve('style-loader'),
                require.resolve('css-loader'),
                require.resolve('sass-loader'),
                {
                    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',
                            })
                        ],
                    },
                }
            ]
        }
    );
    //less
    config.module.rules[2].oneOf.unshift(
        {
            test: /\.less$/,
            use: [
                require.resolve('style-loader'),
                require.resolve('css-loader'),
                {
                    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('less-loader'),
                    options: {
                        // theme vars, also can use theme.js instead of this.
                        modifyVars: theme,
                    },
                },
            ]
        }
    );

    // file-loader exclude
    let l = getLoader(config.module.rules, fileLoaderMatcher);
    l.exclude.push(/\.scss$/);
    l.exclude.push(/\.less$/);
    return config;
};

项目地址:https://github.com/SuRuiGit/m...