从零开始搭建一个React项目

2018-10-12 admin

如果你还不知道什么是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
        })
    ]
};

原文链接:https://segmentfault.com/a/1190000016661311

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-42497.html

文章标题:从零开始搭建一个React项目

相关文章
[翻译]基于Webpack4使用懒加载分离打包React代码
原文地址:https://engineering.innovid.com/code-splitting-using-lazy-loading-with-react-redux-typescript-and-webpack-4-3ec601...
2018-03-11
使用JavaScript制作一个简单的计数器的方法
设计思想 该方法的关键是Cookie技术和动态图像特性的综合运用。使用Cookie,可以在用户端的硬盘上记录用户的数据,下次访问此站点时,即可读取用户端硬盘的Cookie,直接得知来访者的身份和访问次数等有关信息。JavaScript中通过...
2017-03-27
VSCode配置react开发环境的步骤
vscode 默认配置对于 react 的 JSX 语法不友好,体现在使用自动格式化或者粘贴后默认缩进错误,尽管可以通过改变 language mode 缓解错误,但更改 language mode 后的格式化依然不够理想。 通过搭配使用 ...
2017-12-28
JavaScript数组对象实现增加一个返回随机元素的方法
本文实例讲述了JavaScript数组对象实现增加一个返回随机元素的方法。分享给大家供大家参考。具体如下: 核心特性: 概率随机、顺序随机、随机冒泡 本方法 来自个人手写 JavaScript 的实践,只涉及 JavaScript 1.5(...
2017-03-27
优化RequireJS项目的相关技巧总结
本文将演示如何合并与压缩一个基于RequireJS的项目。本文中将用到苦干个工具,这其中就包括Node.js。 因此,如果你手头上还没有Node.js可以点击此处下载一个。 动机 关于RequireJS已经有很多文章介绍过了。这个工具可以将...
2017-03-27
JavaScript使用pop方法移除数组最后一个元素用法实例
本文实例讲述了JavaScript使用pop方法移除数组最后一个元素的用法。分享给大家供大家参考。具体如下: 下面的代码演示了JS数组的pop方法,可以用来移除数组的最后一个元素,实际上就是把数组当成堆栈使用 &lt;!DOCTYPE ht...
2017-03-22
深入理解JavaScript的React框架的原理
如果你在两个月前问我对React的看法,我很可能这样说: 我的模板在哪里?javascript中的HTML在做些什么疯狂的事情?JSX开起来非常奇怪!快向它开火,消灭它吧! 那是因为我没有理解它. 我发誓,React 无疑是在正确的轨道...
2017-03-26
为你的 VS Code 搭建远程开发环境
开篇先说一下自己遇到的烦恼,介绍下写这篇文章的背景。我有一台低配的 MacBook 和 一台性能强悍的台式机。之前自己都是在 Mac 上跑前端项目的,那台台式机基本上处于闲置状态,偶尔用来看看文档。后来随着自己需要做服务端开发,有时候需要同...
2018-02-26
使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
一,利用Node搭建静态服务器 这个是这个项目的底层支撑部分。用来支持静态资源文件像html, css, gif, jpg, png, javascript, json, plain text等等静态资源的访问。这里面是有一个mime类型的...
2017-03-29
JavaScript获取一个范围内日期的方法
本文实例讲述了JavaScript获取一个范围内日期的方法。分享给大家供大家参考。具体分析如下: 指定开始和结束时间,范围该范围内的所有日期放入数组 Date.prototype.addDays = function(days) { v...
2017-03-22
回到顶部