资讯专栏INFORMATION COLUMN

从零开始搭建一个React项目

HollisChuang / 2412人阅读

摘要:优化代码拆分从入口文件开始,递归地构建了整个应用的模块依赖图表,然后通常会将所有的模块打包成一个。

如果你还不知道什么是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支持多种不同的模块系统,我们主要用到以下三个:

es6模块系统

node平台的CommonJS模块系统

sass/less的模块系统

一、使用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文件以
             *      
             *      的形式插入到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:

babel-core

babel-runtime

babel-plugin-transform-runtime

babel-plugin-external-helpers

babel-preset-env

babel-preset-react

babel-plugin-import

babel-plugin-syntax-dynamic-import

babel-plugin-transform-class-properties

babel-plugin-transform-decorators-legacy

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

eslint

babel-eslint

eslint-plugin-react

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,内容如下:





    
    



    

接着,编写一个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 (
      
{this.state.text}, I am {this.props.author}!
) } } export default MyFirstComponent;
// 文件路径:react-template/src/index.js
import MyFirstComponent from "./components/myFirstComponent/myFirstComponent"

ReactDOM.render(, 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://www.ucloud.cn/yun/98318.html

相关文章

  • 前端之从零开始系列

    摘要:只有动手,你才能真的理解作者的构思的巧妙只有动手,你才能真正掌握一门技术持续更新中项目地址求求求源码系列跟一起学如何写函数库中高级前端面试手写代码无敌秘籍如何用不到行代码写一款属于自己的类库原理讲解实现一个对象遵循规范实战手摸手,带你用撸 Do it yourself!!! 只有动手,你才能真的理解作者的构思的巧妙 只有动手,你才能真正掌握一门技术 持续更新中…… 项目地址 https...

    Youngdze 评论0 收藏0
  • 从零开始搭建React同构应用(二):浏览器端工程化

    摘要:从零开始搭建同构应用二项目工程化浏览器端在从零开始同构开发一中我们已经能实现基本的配置和编译了。接下来我们需要将编译工作工程化。配置作用自动生成自动在引入,。文件内容如下同构开发配置自动刷新这里我们用到的修饰器特性。 从零开始搭建React同构应用(二) 项目工程化(浏览器端) 在从零开始React同构开发(一)中我们已经能实现基本的React配置和编译了。接下来我们需要将编译工作工程...

    wwq0327 评论0 收藏0
  • 从零开始的 Android 新项目 - 收藏集 - 掘金

    摘要:从零开始的新项目高级篇掘金承接上篇,本篇继续讲解一些更加进阶的内容,包括列表绑定自定义属性双向绑定表达式链表达式动画注入测试等。 从零开始的 Android 新项目 8 - Data Binding 高级篇 - 掘金 承接上篇,本篇继续讲解一些更加进阶的内容,包括:列表绑定、自定义属性、双向绑定、表达式链、Lambda表达式、动画、Component注入(测试)等。 Demo源码库:D...

    LeviDing 评论0 收藏0
  • 学习从零开始搭建React脚手架

    摘要:写在前面准备学习一下和相关的东西,官方的脚手架看起来太繁琐,所以打算自己来搭建一个,参考了这个文档从零搭建全家桶框架教程步骤上都差不多第一步,依赖总览完成到我现在半成品的过程中,目前完成开发模式的相关操作,添加了按需加载的地步。 写在前面 准备学习一下react和webpack相关的东西,官方的脚手架看起来太繁琐,所以打算自己来搭建一个,参考了这个文档从零搭建React全家桶框架教程;...

    cod7ce 评论0 收藏0
  • 从零开始搭建React同构应用(三):配置SSR

    摘要:从零开始搭建同构应用三配置这篇文章来讲解来配置,我们先从最简单的方法开始,用的方式模拟实现。影响生产环境下执行效率。最后权衡下,还是决定使用现在多一套编译配置的方案。新建,写入以下内容以为例,注意不能少。 从零开始搭建React同构应用(三):配置SSR 这篇文章来讲解来配置server side render,我们先从最简单的方法开始,用cli的方式模拟实现SSR。 demo在这里 ...

    jzzlee 评论0 收藏0
  • 手把手教你从零搭建react局部热加载环境

    摘要:有没有办法实现就局部刷新呢当然是有第十步执行为了实现局部热加载,我们需要添加插件。 前言 用了3个多月的vue自认为已经是一名合格的vue框架api搬运工,对于vue的api使用到达了一定瓶颈,无奈水平有限,每每深入底层观赏源码时候都迷失了自己。 遂决定再找个框架学习学习看看能否突破思维局限,加上本人早已对React、RN技术垂涎已久,于是决定找找教程来学习。无奈第一步就卡在了环境搭...

    quietin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<