React + Webpack简单配置(多入口)

目前有写demo的文件,各个文件中有package.json和相关的node_modules,个人需求:

统一管理,不要重复的安装依赖————实现多入口;

现有目录结构如下:
图片描述

package.json

{
  "name": "front_web_demo",
  "version": "1.0.0",
  "main": "index.js",
  "directories": {
    "test": "test"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --config webpack.dev.config.js",
    "build": "webpack --config webpack.production.config.js"
  },
  "repository": {
    "type": "git",
    "url": "git@git.graysoft.cn:zhangchao/front_web_demo.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.23.1",
    "babel-loader": "^6.3.2",
    "babel-preset-env": "^1.1.8",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-react": "^6.23.0",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.26.1",
    "file-loader": "^0.10.0",
    "html-webpack-plugin": "^2.28.0",
    "node-sass": "^4.5.0",
    "sass-loader": "^6.0.1",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "webpack": "^2.2.1",
    "webpack-del-plugin": "0.0.1",
    "webpack-dev-server": "^2.4.1",
    "webpack-notifier": "^1.5.0"
  },
  "dependencies": {
    "chart.js": "^2.5.0",
    "jquery": "^3.1.1",
    "jstree": "^3.3.3",
    "react": "^15.4.2",
    "react-chartjs-2": "^2.0.0",
    "react-dom": "^15.4.2",
    "react-intl": "^2.2.3",
    "underscore": "^1.8.3"
  },
  "description": ""
}

webpack.dev.config.js

var webpack = require("webpack");
var path = require("path");
var glob = require("glob");

var htmlWebpackPlugin = require("html-webpack-plugin");
var webpackCopyPlugin = require("copy-webpack-plugin");
var webpackDelPlugin = require("webpack-del-plugin");
var webpackNotifierPlugin = require("webpack-notifier");

var ROOT_PATH = path.resolve(__dirname);
var SRC_PATH = path.resolve(ROOT_PATH,"source");
var DIST_PATH = path.resolve(ROOT_PATH,"dist");
var TEM_PATH = path.resolve(ROOT_PATH,"templates");

var ProjectArray = glob.sync(SRC_PATH + "/*/index.js");
var ProjectEntries = {};

var config = {
    entry: {
        vendors:["react","react-dom","underscore","jquery"],
        intlVendor:["react-intl"],
        jstreeVendor:["jstree"],
        chartVendors:["react-chartjs-2","chart.js"]
    },
    output:{
        path:DIST_PATH,
        filename:"[name].js"
    },
    module:{
        rules:[
            {
                test:/\.(es6|js)$/,
                use:[
                    {
                        loader:"babel-loader"
                    }
                ],
                exclude:/node_modules/
            },
            {
                test:/\.(scss|css)$/,
                use:[
                    {
                        loader:"style-loader"
                    },
                    {
                        loader:"css-loader"
                    },
                    {
                        loader:"sass-loader"
                    }
                ],
                exclude:/node_modules/
            },
            {
                test:/\.(png|jpeg|jpg|gif)$/,
                use:[
                    {
                        loader:"url-loader",
                    }
                ],
                exclude:/node_modules/
            },
            {
                test:/\.(woff2?|otf|eot|svg|ttf)$/,
                use:[
                    {
                        loader:"url-loader"
                    }
                ]
            }
        ]
    },
    plugins:[
        new webpackNotifierPlugin({excludeWarnings: true}),
        new webpack.HotModuleReplacementPlugin()
    ],
    devtool:"cheap-eval-source-map",
    devServer:{
        host: "0.0.0.0",
        port: "6000",
        hot: true,
        inline: true,
        historyApiFallback: true
    }
};

ProjectArray.forEach(function(f){
    var regex = new RegExp(".*\/source\/(.*?)\/index\.js");
    var name = regex.exec(f)[1];
    ProjectEntries[name] = f;

    switch (name){
        case "React_i18n":
            {
                config.plugins.push(
                    new htmlWebpackPlugin({
                        title: name,
                        filename: name + '.html',
                        template: path.resolve(TEM_PATH,"./index.html"),
                        inject: "body",
                        chunks: ["vendors","intl", name]
                    })
                );
            }
            break;
        case "JSTree":
            {
                config.plugins.push(
                    new htmlWebpackPlugin({
                        title: name,
                        filename: name + '.html',
                        template: path.resolve(TEM_PATH,"./index.html"),
                        inject: "body",
                        chunks: ["vendors","jstreeVendor", name]
                    })
                );
            }
            break;
        case "weather":
            {
                config.plugins.push(
                    new htmlWebpackPlugin({
                        title: name,
                        filename: name + '.html',
                        template: path.resolve(TEM_PATH,"./index.html"),
                        inject: "body",
                        chunks: ["vendors","chartVendors", name]
                    })
                );
            }
            break;
        default:
            {
                config.plugins.push(
                    new htmlWebpackPlugin({
                        title: name,
                        filename: name + '.html',
                        template: path.resolve(TEM_PATH,"./index.html"),
                        inject: "body",
                        chunks: ["vendors", name]
                    })
                );
            }
            break;
    }
});

config.entry = Object.assign({}, config.entry, ProjectEntries);

module.exports = config;

webpack.production.config.js

var webpack = require("webpack");
var path = require("path");
var glob = require("glob");

var htmlWebpackPlugin = require("html-webpack-plugin");
var webpackCopyPlugin = require("copy-webpack-plugin");
var webpackDelPlugin = require("webpack-del-plugin");
var webpackNotifierPlugin = require("webpack-notifier");

var ROOT_PATH = path.resolve(__dirname);
var SRC_PATH = path.resolve(ROOT_PATH,"source");
var DIST_PATH = path.resolve(ROOT_PATH,"dist");
var TEM_PATH = path.resolve(ROOT_PATH,"templates");

var ProjectArray = glob.sync(SRC_PATH + "/*/index.js");
var ProjectEntries = {};

var config = {
    entry: {
        vendors:["react","react-dom","underscore","jquery"],
        intlVendor:["react-intl"],
        jstreeVendor:["jstree"],
        chartVendors:["react-chartjs-2","chart.js"]
    },
    output:{
        path:DIST_PATH,
        filename:"[name].js"
    },
    module:{
        rules:[
            {
                test:/\.(es6|js)$/,
                use:[
                    {
                        loader:"babel-loader"
                    }
                ],
                exclude:/node_modules/
            },
            {
                test:/\.(scss|css)$/,
                use:[
                    {
                        loader:"style-loader"
                    },
                    {
                        loader:"css-loader"
                    },
                    {
                        loader:"sass-loader"
                    }
                ],
                exclude:/node_modules/
            },
            {
                test:/\.(png|jpeg|jpg|gif)$/,
                use:[
                    {
                        loader:"url-loader",
                    }
                ],
                exclude:/node_modules/
            },
            {
                test:/\.(woff2?|otf|eot|svg|ttf)$/,
                use:[
                    {
                        loader:"url-loader"
                    }
                ]
            }
        ]
    },
    plugins:[
        new webpackDelPlugin({match: DIST_PATH}),
        new webpackNotifierPlugin({excludeWarnings: true}),
        new webpack.optimize.UglifyJsPlugin({minimize: true}),
        new webpack.optimize.CommonsChunkPlugin({
            name : 'vendors',
            filename: 'vendors.js'
        })
    ]
};

ProjectArray.forEach(function(f){
    var regex = new RegExp(".*\/source\/(.*?)\/index\.js");
    var name = regex.exec(f)[1];
    ProjectEntries[name] = f;

    switch (name){
        case "React_i18n":
        {
            config.plugins.push(
                new htmlWebpackPlugin({
                    title: name,
                    filename: name + '.html',
                    template: path.resolve(TEM_PATH,"./index.html"),
                    inject: "body",
                    chunks: ["vendors","intl", name]
                })
            );
        }
            break;
        case "JSTree":
        {
            config.plugins.push(
                new htmlWebpackPlugin({
                    title: name,
                    filename: name + '.html',
                    template: path.resolve(TEM_PATH,"./index.html"),
                    inject: "body",
                    chunks: ["vendors","jstreeVendor", name]
                })
            );
        }
            break;
        case "weather":
        {
            config.plugins.push(
                new htmlWebpackPlugin({
                    title: name,
                    filename: name + '.html',
                    template: path.resolve(TEM_PATH,"./index.html"),
                    inject: "body",
                    chunks: ["vendors","chartVendors", name]
                })
            );
        }
            break;
        default:
        {
            config.plugins.push(
                new htmlWebpackPlugin({
                    title: name,
                    filename: name + '.html',
                    template: path.resolve(TEM_PATH,"./index.html"),
                    inject: "body",
                    chunks: ["vendors", name]
                })
            );
        }
            break;
    }


    var AssetArray = glob.sync(SRC_PATH + "/"+ name +"/*/");
    AssetArray.forEach(function(f){
        var assetRegex = new RegExp(".*\/source\/"+ name +"\/(.*?)\/");
        var asset = assetRegex.exec(f)[1];

        if(asset !== "components"){
            config.plugins.push(
                new webpackCopyPlugin([
                    {
                        from:path.resolve(SRC_PATH,name,asset),
                        to:path.resolve(DIST_PATH,name,asset)
                    },
                    {
                        from:path.resolve(SRC_PATH,name,asset),
                        to:path.resolve(DIST_PATH,name,asset)
                    },
                    {
                        from:path.resolve(SRC_PATH,name,asset),
                        to:path.resolve(DIST_PATH,name,asset)
                    },
                    {
                        from:path.resolve(SRC_PATH,name,asset),
                        to:path.resolve(DIST_PATH,name,asset)
                    },
                    {
                        from:path.resolve(SRC_PATH,name,asset),
                        to:path.resolve(DIST_PATH,name,asset)
                    }
                ])
            )
        }
    })

});

config.entry = Object.assign({}, config.entry, ProjectEntries);

module.exports = config;

.babelrc

{
  "presets": [
      "react",
    ["env", {
      "targets": {
        "browsers": ["last 2 versions", "safari >= 7"]
      }
    }]
  ]
}

附带官网Clock组件类的代码:

var React = require('react');
var ReactDOM = require('react-dom');
var Clock = React.createClass({

getInitialState: function() {
    return {date: new Date()};
},
render:function(){
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
},
componentDidMount:function(){
    this.timerID = setInterval(
        //此处必须bind(this),因为如果不绑定,setInterval里的this已经变化
        function(){this.tick()}.bind(this),
        1000
    );
},
componentWillUnmount:function(){
    clearInterval(this.timerID);
},

tick : function(){
    this.setState({
        date:new Date()
    })
}
});

ReactDOM.render(
    <Clock />,
    document.body
);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值