17

如果你还不知道什么是React,请点击这里
github源码

安装Node.js

如果你还不知道什么是ECMAScript,请点击这里

如果你还不知道什么是Node.js,请点击这里

下载Node.js并安装;接着打开windows命令行窗口分别输入node -vnpm -v
如下图所示,nodenpm均显示出版本号则表示安装成功!
图片描述

npm初始化项目

如果你还不知道什么是npm,请点击这里

在你想要放置该项目代码的任何地方新建一个文件夹,并命名为react-template,接着打开该文件夹路径下windows命令行窗口输入npm init,接着根据提示依次输入:

  • package name:项目名称(默认是文件夹名称)
  • version:版本号(默认是1.0.0)
  • description:项目描述
  • entry point:项目入口文件(默认是index.js)
  • test command:测试命令
  • git repositorygit远程仓库地址
  • keywords:项目关键词
  • author:作者
  • license:开源许可声明

图片描述

初始化完成后,项目根目录会自动生成package.json文件,这就是项目的npm配置文件了。

图片描述

使用webpack4搭建自动化开发环境

如果你还不知道什么是webpack,请点击这里,并且本人强烈建议把该页内容耐心读完。

webpack是一个静态资源模块打包器,并且webpack支持多种不同的模块系统,我们主要用到以下三个:

一、使用npm安装webpack

首先,给package.json文件写入两个属性:

图片描述

这两个属性都是用来维护项目的本地依赖包列表的,但是devDependencies比较特殊,它只是开发环境的依赖,当构建生产环境代码时,这些包的代码会被舍去。

接着,给devDependencies写入webpack的依赖:

键值对:key为包名,value为版本号

{
    ...
    
    "devDependencies": {
        "webpack": "^4.12.0",
        "webpack-cli": "^3.0.8"
        ...
    
    }
}

命令行npm installnpm i,这个命令会根据dependenciesdevDependencies的配置去检查是否所有的依赖包都在本地安装了,若没有则会安装对应的包到本地。

图片描述

如果你对npm命令行不了解,可以看这里

如果你对npm的“全局”和“本地”的概念不是很清楚,例如:上文提到的本地依赖包,可以看这里

安装成功后,项目根目录下会生成一个node_modules文件夹,它就是本地依赖包的仓库,你可以在它的里面找到包webpackwebpack-cli

图片描述

特别地,还需要全局安装webpack,否则命令行窗口认不到 webpack 的命令。

$ npm i -g webpack webpack-cli

二、编写webpack4配置文件

新建react-template/src文件夹,并在里面新建文件index.js

新建react-template/build文件夹,接着在build文件夹里再新建两个文件:

  • webpack.base.js:基础配置文件(开发和生产共用)
  • webpack.dev.js:自动化开发环境的配置文件
  • webpack.pro.js:构建生产环境代码配置文件

关于webpack配置的详细内容,请看这里

webpack基础配置

配置文件通常是一个CommonJS规范的模块,输出一个JavaScript Object

entry
// __dirname表示当前目录,path.resolve()可以防止不同操作系统之间的文件路径问题,并且可以使相对路径按照预期工作
module.exports = {
    /**
     * 项目入口文件
    */
    entry: path.resolve(__dirname, '../src/index.js')
    // ...省略其它选项
}
output
module.exports = {
    //...
    
    /**
     * 指定打包后的 bundle 如何输出
     * 特别说明:
     * 1. bundle是指多个模块打包在一起,产生的新文件。bundle 一般由html文件通过 script 标签加载
    */
    output: {
        // 打包后的 bundle 的生成位置(E:/react-template/dist/)
        path: path.resolve(__dirname, "../dist/"),

        // 主 bundle(E:/react-template/dist/js/main.js)
        filename: "js/main.js",

        // chunk: 单独拆分出来的 bundle,name即为chunk的名称
        chunkFilename: "js/[name].js",

        // publicPath + chunkFilename 为打包后生成的html文件请求 chunkFile 的路径
        // publicPath + 图片的URL 为打包后生成的html文件请求图片的路径,其他静态资源文件同理
        publicPath: "/"
    }
    
    //...
}
resolve
module.exports = {
    //...
    
    /**
     * 如何解析模块路径
    */
    resolve: {
        // 指定要解析的文件扩展名
        extensions: [".web.js", ".jsx", ".js", ".json"],

        // 模块路径别名
        alias: {}
    },
    
    //...
}
module
module.exports = {
    //...
    
    /**
     * 指定如何处理(编译)各种类型的模块
     * 特别说明:
     * 1. webpack提供了丰富的针对不同类型模块的loader,你可以使用loader对模块进行预处理或者对模块的      *    源代码进行转换(编译)
     * 2. 常见的模块类型:js, jsx, css, scss, less, json, png, git, jpg
    */
    module: {
        /**
         * 各种类型模块的处理规则
         * 特别说明:
         * 1. use属性表示模块使用什么loader
         * 2. 模块可以使用多个loader,处理顺序为use属性的数组的第一个到最后一个
        */
        rules: [
            // 图片文件小于8192byte时,转换为base64字符串
            {
                test: /\.(gif|png|jpg|jpeg|woff|woff2|eot|ttf|svg)(\?t=\d+)?$/,
                exclude: /node_modules/,
                use: ["url-loader?limit=8192"]
            },
            
            /**
             * 将js和jsx模块的源代码编译成浏览器能正常执行的代码
             * 特别说明:
             * 1. eslint是一个代码检查工具,中文官网:https://cn.eslint.org/
             *      一般我们会在项目根目录下为eslint创建一个配置文件 .eslintrc.json ,关于eslint               *    的配置,祥见:附录/eslint-loader配置文件
             * 2. babel是一个JavaScript编译器,它能够将浏览器尚未实现的新一代的ES语法转换成浏览器              *    已实现的语法,比如我们现在广泛使用的es6和部分es7语法和新的内置对象,其实浏览器并没              *    有完全实现,但是有了babel,我们完全可以放心使用它们。
             * 3. 一般我们会在项目根目录下为babel创建一个配置文件 .babelrc ,关于babel的配置,详                 *    见:附录/babel-loader配置文件
            */
            {
                enforce: "pre",
                test: /\.(js|jsx)?$/,
                exclude: /node_modules/,
                use: [{
                    loader: 'eslint-loader',
                    options: {
                        emitError: true,
                        emitWarning: true,
                        failOnError: true
                    }
                }]
            },
            {
                test: /\.(js|jsx)?$/,
                exclude: /node_modules/,
                use: ["babel-loader"]
            },
            
            /**
             * 处理css模块 
             * loader说明:
             * 1. style-loader 将css文件以
             *      <link rel="stylesheet" href="path/to/file.css">
             *      的形式插入到html文件
             * 2. css-loader 处理css的 @import语句 与 url() ,同时压缩代码
             * 3. postcss-loader 对css做一些加工处理,具体的配置放在postcss.config.js,比如给              *    css自动添加浏览器厂商前缀。如果不知道css浏览器厂商前缀的,请自行百度。
            */
            {
                test: /\.(css)?$/,
                use: [
                    "style-loader/url",
                    {
                        loader: "css-loader",
                        options: {
                            minimize: {
                                safe: true,
                                discardComments: {
                                    removeAll: true
                                }
                            }
                        }
                    },
                    "postcss-loader"
                ]
            },
            
            /**
             * 处理less模块
             * 特别说明:
             * 1. Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,                 *      使 CSS 更易维护和扩展。
             * 2. Less中文网:http://lesscss.cn/
            */
            {
                test: /\.less$/,
                use: ["style-loader", "css-loader", "less-loader"]
            },
            
            /**
             * 处理scss模块
             * 特别说明:
             * 1. sass与less类似,也是一门css预处理语言。
            */
            {
                test: /\.scss$/,
                exclude: /node_modules/,
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader',
                    'sass-loader'
                ]
            }
        ]
    }
    
    //...
}
externals
module.exports = {
    //...
    
    /**
     * 外部扩展
     * 有时候你可能不想把某个第三方 library 打包进你的 package 里,而是希望 library 做为外部依赖;       * 比如通过 script 标签来加载此 library , externals 这个选项可以帮到你。
    */
    externals: {
        "react": {
            commonjs: 'React',
            commonjs2: 'React',
             amd: 'React',
               root: 'React'
        },
        "react-dom": {
            commonjs: 'ReactDOM',
            commonjs2: 'ReactDOM',
             amd: 'ReactDOM',
               root: 'ReactDOM'
        }
    }
    
    //...
}
optimization
module.exports = {
    //...
    
    /**
     * 优化
    */
    optimization: {
        /**
         * 代码拆分
         * 从入口文件开始,webpack 递归地构建了整个应用的模块依赖图表(dependency graph),然后通           * 常会将所有的模块打包成一个 bundle。但是有两种情况需要把一些模块拆分成单独的 bundle:
         * 1. 通过 import() 函数导入的模块,这些模块不会被打包进主 bundle 里,而是拆分为单独的              *     bundle,等待 import() 函数执行,再去异步加载。
         *       import() 函数介绍:https://juejin.im/entry/58ba3308a22b9d005ede7565
         * 2. 有的模块由于被多个不同的 bundle 依赖,所以这几个 bundle 里都会有该模块的代码;这时就         *       需要将这种模块也单独拆分出来,避免重复加载相同的模块。
        */
        splitChunks: {
            chunks: "all",
            minSize: 30000,
            minChunks: 2,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: "~",
            name: true,
            cacheGroups: {
                default: false,
                vendor: {
                    name: "vendor",
                    priority: 99
                }
            }
        }
    }
}

以上就是webpack的基础配置了。我们还需要把配置中用到的loader及相关的模块下载到本地。

其中,由于:

babel-loader依赖以下列出的package:

eslint-loader依赖以下列出的package:

less-loader依赖 less

postcss-loader依赖 postcss

把上面列出的package写入package.jsondependenciesdevDependencies

{
    "dependencies": {
        "babel-runtime": "^6.26.0"
    },
    "devDependencies": {
        "autoprefixer": "^9.1.5",
        "babel-core": "^6.26.3",
        "babel-eslint": "^9.0.0",
        "babel-loader": "^7.1.5",
        "babel-plugin-external-helpers": "^6.22.0",
        "babel-plugin-import": "^1.9.1",
        "babel-plugin-syntax-dynamic-import": "^6.18.0",
        "babel-plugin-transform-class-properties": "^6.24.1",
        "babel-plugin-transform-decorators-legacy": "^1.3.5",
        "babel-plugin-transform-runtime": "^6.23.0",
        "babel-preset-env": "^1.7.0",
        "babel-preset-react": "^6.24.1",
        "css-loader": "^1.0.0",
        "eslint": "^5.6.0",
        "eslint-loader": "^2.1.1",
        "eslint-plugin-react": "^7.11.1",
        "file-loader": "^2.0.0",
        "less": "^3.8.1",
        "less-loader": "^4.1.0",
        "node-sass": "^4.9.0",
        "path": "^0.12.7",
        "postcss": "^6.0.22",
        "postcss-loader": "^3.0.0",
        "react-hot-loader": "^4.3.8",
        "sass-loader": "^7.0.3",
        "style-loader": "^0.23.0",
        "url-loader": "^1.1.1",
        "webpack": "^4.12.0",
        "webpack-cli": "^3.1.0",
        "webpack-merge": "^4.1.4"
    }
}

接着

$ npm install

webpack自动化开发环境配置

上一步的基础配置都完成之后,实际上webpack已经可以正常工作了,你可以写一些测试模块,然后在src/index.js引入,用命令行运行webpack

$ webpack --config ./build/webpack.base.js --mode=development

图片描述

但是这个过程是纯手动的,我们可以使用一些webpack plugin来让某些动作自动化,以此来提高工作效率。

下面是webpack开发模式的配置文件:

var base = require("./webpack.base.js"),
    // merge() 合并配置选项
    merge = require('webpack-merge'),
    HtmlWebpackPlugin = require("html-webpack-plugin"),
    copyWebpackPlugin = require("copy-webpack-plugin");

module.exports = merge(base, {
    // 开发模式
    mode: "development",
    
    devtool: "#cheap-module-eval-source-map",
    
    // webpack plugin -> https://webpack.docschina.org/plugins/
    plugins: [
        // 复制无需参与构建的文件到输出位置
        new copyWebpackPlugin([
            {
                from: "src/js_modules/react/dev/react.js",
                to: "js/"
            },
            {
                from: "src/js_modules/react-dom/dev/react-dom.js",
                to: "js/"
            },
            {
                from: "img/**/*.*",
                to: ""
            }
        ]),
        
        // 自动在输出位置创建html文件,并在html文件自动注入加载bundle的script标签或link标签
        new HtmlWebpackPlugin({
            filename: "index.html",
            template: "index.html",
            chunks: ["main", "vendor"],
            inject: true,
            chunksSortMode: "auto"
        })
    ]
});

光是能复制或自动创建文件还不够,我们希望在开发过程中,当我们修改代码之后,webpack能够监听变更的文件自动增量编译,也希望浏览器能实时响应我们的代码(文件)变更,并自动变化或重载。要实现这个需求,我们需要使用express,并结合webpack-dev-middlewarewebpack-hot-middleware来搭建一个开发服务器。顺便提一句我个人比较推荐使用gulp来作为项目工程化的流程管理工具,所以启动开发服务器我是作为一个 gulp任务 来编写的,首先在根目录创建一个gulpfile.js,写入下面的代码:

var gulp = require("gulp"),
    gutil = require("gulp-util"),
    express = require("express"),
    webpack = require("webpack"),
    webpackDevMiddleware = require("webpack-dev-middleware"),
    webpackHotMiddleware = require("webpack-hot-middleware"),
    history = require("connect-history-api-fallback"),
    opn = require("opn");

// 开发服务器
gulp.task("dev", function() {
    var webpackDevConfig = require("./build/webpack.dev.js");

    webpackDevConfig.entry = [
        "webpack-hot-middleware/client?noInfo=true"
    ].concat([webpackDevConfig.entry]);

    webpackDevConfig.plugins = webpackDevConfig.plugins.concat([
        new webpack.HotModuleReplacementPlugin()
    ]);

    var devCompiler = webpack(webpackDevConfig);
    var devMiddleware = webpackDevMiddleware(devCompiler, {
        publicPath: webpackDevConfig.output.publicPath,
        stats: {
            chunks: false,
            colors: true,
            timings: true,
            source: true,
            cachedAssets: false
        },
        watchOptions: {
            ignored: /node_modules/,
            aggregateTimeout: 300,
            poll: true
        }
    });
    var hotMiddleware = webpackHotMiddleware(devCompiler, {
        log: false
    });

    var server = express();
    server.use(history());
    server.use(devMiddleware);
    server.use(hotMiddleware);
    server.listen(3008, function(err) {
        if (err) throw new gutil.PluginError("webpack-dev-server", err);
        opn("http://localhost:3008")
    });
});

把以上相关的package写入package.jsonnpm install

{
    "dependencies": {
        "babel-runtime": "^6.26.0",
        "react": "^16.4.1"
    },
    "devDependencies": {
        "autoprefixer": "^9.1.5",
        "babel-core": "^6.26.3",
        "babel-eslint": "^9.0.0",
        "babel-loader": "^7.1.5",
        "babel-plugin-external-helpers": "^6.22.0",
        "babel-plugin-import": "^1.9.1",
        "babel-plugin-syntax-dynamic-import": "^6.18.0",
        "babel-plugin-transform-class-properties": "^6.24.1",
        "babel-plugin-transform-decorators-legacy": "^1.3.5",
        "babel-plugin-transform-runtime": "^6.23.0",
        "babel-preset-env": "^1.7.0",
        "babel-preset-react": "^6.24.1",
        "connect-history-api-fallback": "^1.5.0",
        "copy-webpack-plugin": "^4.5.2",
        "css-loader": "^1.0.0",
        "eslint": "^5.6.0",
        "eslint-loader": "^2.1.1",
        "eslint-plugin-react": "^7.11.1",
        "express": "^4.16.3",
        "file-loader": "^2.0.0",
        "gulp": "^3.9.1",
        "gulp-sequence": "^1.0.0",
        "gulp-util": "^3.0.8",
        "html-webpack-plugin": "^3.2.0",
        "http-proxy-middleware": "^0.18.0",
        "less": "^3.8.1",
        "less-loader": "^4.1.0",
        "node-sass": "^4.9.0",
        "opn": "^5.3.0",
        "path": "^0.12.7",
        "postcss": "^6.0.22",
        "postcss-loader": "^3.0.0",
        "react-hot-loader": "^4.3.4",
        "sass-loader": "^7.0.3",
        "style-loader": "^0.23.0",
        "url-loader": "^1.1.1",
        "webpack": "^4.12.0",
        "webpack-cli": "^3.1.0",
        "webpack-dev-middleware": "^3.1.3",
        "webpack-hot-middleware": "^2.22.3",
        "webpack-merge": "^4.1.4"
    }
}

然后在根目录创建index.html,内容如下:

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
</head>

<body>
    <div id="app"></div>
    <script src="./js/react.js"></script>
    <script src="./js/react-dom.js"></script>
</body>

</html>

接着,编写一个react组件

// 文件路径:react-template/src/components/myFirstComponent/myFirstComponent.jsx

import { hot } from "react-hot-loader";

// @hot 可以是react组件热重载
@hot(module)
class MyFirstComponent extends React.Component {
  state = {
    text: "Hello React"
  };

  /** 组件生命周期钩子函数:在组件挂载完成后立即被调用 */
  componentDidMount() {
    console.log("组件挂载完成!");
  }

  render() {
    return (
      <div>{this.state.text}, I am {this.props.author}!</div>
    )
  }
}

export default MyFirstComponent;
// 文件路径:react-template/src/index.js
import MyFirstComponent from "./components/myFirstComponent/myFirstComponent"

ReactDOM.render(<MyFirstComponent author="Shaye"></MyFirstComponent>, document.getElementById("app"));

最后,打开CMD

$ gulp dev

废话少说,直接上图:

图片描述

浏览器会自动打开:

图片描述

你还可以试着修改组件的内容,你会发现每当你按下保存键,浏览器会跟着实时变化

好了,前面折腾了这么久,现在你可以去开发你的react应用了。只不过嘛,现在你能自由地开发调试了,但是还不能构建产品包,所以接下来我们还需要再配置一下 如何构建生产环境的代码。

webpack构建生产环境代码配置

webpack.pro.js配置文件

var base = require('./webpack.base.js'),
    merge = require('webpack-merge'),
    HtmlWebpackPlugin = require('html-webpack-plugin'),
    BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin,
    WebpackMd5Hash = require('webpack-md5-hash');

module.exports = merge(base, {
    mode: 'production',
    plugins: [
        new WebpackMd5Hash(),
        new BundleAnalyzerPlugin(),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            chunks: ['main', 'vendor'],
            inject: true,
            chunksSortMode: 'auto',
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
            }
        })
    ]
});

编写gulp构建生产环境代码任务:

var gulp = require("gulp"),
    gulpSequence = require("gulp-sequence"),
    gutil = require("gulp-util"),
    del = require("del"),
    uglify = require("gulp-uglify"),
    imagemin = require("gulp-imagemin"),
    express = require("express"),
    webpack = require("webpack"),
    webpackDevMiddleware = require("webpack-dev-middleware"),
    webpackHotMiddleware = require("webpack-hot-middleware"),
    history = require("connect-history-api-fallback"),
    opn = require("opn");

//...省略其他任务

//清除
gulp.task("clean", function(cb) {
    del.sync("dist");
    cb();
});

//图片压缩
gulp.task("copyImg", function() {
    return gulp
        .src("img/**/*.*")
        .pipe(imagemin())
        .pipe(gulp.dest("dist/img/"));
});

//复制无需编译的js文件
gulp.task("copyJs", function() {
    return gulp
        .src([
        "src/js_modules/react/pro/react.js",
        "src/js_modules/react-dom/pro/react-dom.js"
    ])
        .pipe(uglify())
        .pipe(gulp.dest("dist/js/"));
});

//webpack production
gulp.task("webpackPro", function(cb) {
    var webpackProConfig = require("./build/webpack.pro.js");
    webpack(webpackProConfig, function(err, stats) {
        if (err) throw new gutil.PluginError("webpack:production", err);
        gutil.log(
            "[webpack:production]",
            stats.toString({
                chunks: false,
                colors: true,
                timings: true,
                source: true,
                cachedAssets: false
            })
        );
        cb();
    });
});

gulp.task("buildSuccess", function(cb) {
    gutil.log("[webpack:production]", "build success!");
    cb();
});

gulp.task(
    "build",
    gulpSequence("clean", "copyImg", "copyJs", "webpackPro", "buildSuccess")
);

最后,老规矩把相关的package写入package.jsonnpm install

"dependencies": {
    "babel-runtime": "^6.26.0",
    "react": "^16.4.1"
},
"devDependencies": {
    "autoprefixer": "^9.1.5",
    "babel-core": "^6.26.3",
    "babel-eslint": "^9.0.0",
    "babel-loader": "^7.1.5",
    "babel-plugin-external-helpers": "^6.22.0",
    "babel-plugin-import": "^1.9.1",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-decorators-legacy": "^1.3.5",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "connect-history-api-fallback": "^1.5.0",
    "copy-webpack-plugin": "^4.5.2",
    "css-loader": "^1.0.0",
    "eslint": "^5.6.0",
    "eslint-loader": "^2.1.1",
    "eslint-plugin-react": "^7.11.1",
    "express": "^4.16.3",
    "file-loader": "^2.0.0",
    "gulp": "^3.9.1",
    "gulp-sequence": "^1.0.0",
    "gulp-util": "^3.0.8",
    "html-webpack-plugin": "^3.2.0",
    "http-proxy-middleware": "^0.18.0",
    "less": "^3.8.1",
    "less-loader": "^4.1.0",
    "node-sass": "^4.9.0",
    "opn": "^5.3.0",
    "path": "^0.12.7",
    "postcss": "^6.0.22",
    "postcss-loader": "^3.0.0",
    "react-hot-loader": "^4.3.4",
    "sass-loader": "^7.0.3",
    "style-loader": "^0.23.0",
    "url-loader": "^1.1.1",
    "webpack": "^4.12.0",
    "webpack-cli": "^3.1.0",
    "webpack-dev-middleware": "^3.1.3",
    "webpack-hot-middleware": "^2.22.3",
    "webpack-merge": "^4.1.4"
}

最后的最后,命令行输入gulp build试试效果吧!

附录

babel-loader配置文件

{
    "presets": [
        [
            "env",
            {
                "modules": false,
                "targets": {
                    "browsers": ["last 5 versions", "IE 9"]
                }
            }
        ],
        "react"
    ],
    "plugins": [
        [
            "transform-runtime",
            {
                "polyfill": false,
                "regenerator": true
            }
        ],
        "external-helpers",
        "syntax-dynamic-import",
        "transform-class-properties",
        "transform-decorators-legacy",
        [
            "import",
            {
                "libraryName": "antd",
                "libraryDirectory": "es",
                "style": "css"
            }
        ],
        "react-hot-loader/babel"
    ],
    "env": {
        "test": {
            "presets": [
                [
                    "env",
                    {
                        "modules": false,
                        "targets": {
                            "browsers": [
                                "last 5 versions",
                                "IE 9"
                            ]
                        }
                    }
                ],
                "react"
            ],
            "plugins": [
                [
                    "transform-runtime",
                    {
                        "polyfill": false,
                        "regenerator": true
                    }
                ],
                "external-helpers",
                "syntax-dynamic-import",
                "transform-es2015-modules-commonjs",
                "transform-class-properties",
                "transform-decorators-legacy",
                [
                    "import",
                    {
                        "libraryName": "antd",
                        "libraryDirectory": "es",
                        "style": "css"
                    }
                ]
            ]
        }
    }
}

eslint-loader配置文件

{
    "root": true,
    "env": {
        "es6": true,
        "browser": true,
        "node": true
    },
    "parser": "babel-eslint",
    "parserOptions": {
        "sourceType": "module",
        "ecmaFeatures": {
            "jsx": true,
            "experimentalObjectRestSpread": true
        }
    },
    "globals": {
        "ReactDOM": false,
        "React": false,
        "jest": false,
        "test": false,
        "expect": false,
        "describe": false,
        "it": false
    },
    "plugins": ["react"],
    "extends": ["eslint:recommended", "plugin:react/recommended"],
    "settings": {
        "react": {
            "version": "16.4.1"
        }
    },
    "rules": {
        "no-extra-semi": 0,
        "no-console": 0,
        "react/prop-types": 0,
        "no-extra-boolean-cast": 0,
        "no-else-return": [1, { "allowElseIf": false }],
        "no-loop-func": 1,
        "arrow-spacing": 1,
        "eqeqeq": 2,
        "no-restricted-properties": [
            2,
            {
                "object": "disallowedObjectName",
                "property": "disallowedPropertyName"
            },
            {
                "object": "disallowedObjectName",
                "property": "anotherDisallowedPropertyName",
                "message": "Please use allowedObjectName.allowedPropertyName."
            }
        ],
        "no-return-assign": [2, "always"],
        "no-sequences": 2,
        "no-throw-literal": 2,
        "no-unmodified-loop-condition": 2,
        "no-useless-return": 2,
        "prefer-promise-reject-errors": [2, {"allowEmptyReject": true}],
        "require-await": 2,
        "jsx-quotes": [2, "prefer-double"],
        "prefer-const": 2
    }
}

postcss-loader配置文件

module.exports = {
    plugins:[
        require('autoprefixer')({
            browsers:[
                "last 3 versions","iOS 7","not ie <= 9",
                "Android >= 4.0",
                "last 3 and_chr versions",
                "last 3 and_ff versions",
                "last 3 op_mob versions",
                "last 3 op_mob versions",
                "last 3 op_mini versions"
            ],
            //是否美化属性值
            cascade:true,
            //是否去掉不必要的前缀
            remove:true
        })
    ]
};

shayeLee
398 声望12 粉丝