react-webpack 2 - 完整配置案例
源码
webpack 开发跨域问题解决
react16 + react-router4 + webpack开发环境搭建
1.先定义一些配置常量 /webpack/config.js
const path = require('path');
exports.sassLoaderConfig = '?outputStyle=expanded';
exports.vendor = [
'react',
'react-dom',
'react-redux',
'react-router',
'react-router-redux',
'redux',
'redux-thunk'
];
exports.autoConfig = {
browsers: [
'ie >= 9',
'ie_mob >= 10',
'ff >= 30',
'chrome >= 34',
'safari >= 7',
'opera >= 23',
'ios >= 7',
'android >= 4.4',
'bb >= 10'
],
cascade: true,
remove: true
};
exports.uglifyJsConfig = {
beautify: false,
compress: {
warnings: false,
drop_debugger: true,
drop_console: true
},
mangle: {
except: ['$super', '$', 'exports', 'require']
},
space_colon: false,
comments: false
};
const ROOT_PATH = path.resolve(__dirname, '../');
exports.defPath = {
ROOT_PATH: ROOT_PATH,
APP_PATH: path.resolve(ROOT_PATH, 'app'),
DEV_PATH: path.resolve(ROOT_PATH, 'dev'),
BUILD_PATH: path.resolve(ROOT_PATH, 'build'),
TPL_PATH: path.resolve(ROOT_PATH, 'app/tpl.html'),
ENTRY_PATH: path.resolve(ROOT_PATH, 'app/js/index.js'),
ESLINT_PATH: path.resolve(ROOT_PATH, './.eslintrc'),
REQUEST_PATH: path.resolve(ROOT_PATH, 'app/js/utils/request')
}
2.定义不同环境变量下的 应用请求配置
const ip = require('ip').address();
module.exports = {
test: 'http://xxx.xxx',
development: 'http://' + ip + ':3003',
production: 'http://xxx.xxx'
};
定义公共的配置 /webpack/base.js
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const config = require('./config');
const API = require('./API');
const defPath = config.defPath;
const APP_PATH = defPath.APP_PATH;
module.exports = function () {
return {
context: defPath.ROOT_PATH,
resolve: {
modules: [
APP_PATH,
'node_modules'
],
extensions: [
'.js', '.json', '.jsx', '.css'
]
},
cache: true,
module: {
rules: [
{
enforce: 'pre',
test : /\.(js|jsx)$/,
include : APP_PATH,
loader : 'eslint-loader',
options: {
configFile: defPath.ESLINT_PATH
}
},
{
test: /\.(js|jsx)$/,
include: APP_PATH,
loader: 'babel-loader'
},
{
test: require.resolve(defPath.REQUEST_PATH),
loader: 'imports-loader?baseUrl=>'+ JSON.stringify( API[ process.env.NODE_ENV || 'development' ] )
}
]
},
plugins: [
new webpack.LoaderOptionsPlugin({
options: {
context: '/',
minimize: true,
postcss: [autoprefixer(config.autoConfig)]
}
}),
new HtmlWebpackPlugin({
template: defPath.TPL_PATH,
title: 'Hello World app',
filename: 'index.html',
inject: 'body',
minify: {
removeComments: true
},
cache: false
})
]
}
}
开发环境的 webpack 配置 /webpack.dev.config.js
const webpackMerge = require('webpack-merge');
const webpack = require('webpack');
const ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
const ip = require('ip').address();
const baseConfig = require('./webpack/base');
const config = require('./webpack/config');
const defPath = config.defPath;
const APP_PATH = defPath.APP_PATH;
module.exports = webpackMerge(baseConfig(), {
devtool: 'cheap-module-source-map',
entry: {
app: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://' + ip + ':8090',
'webpack/hot/only-dev-server',
'./app/js/index.js'
],
vendor: config.vendor
},
output: {
path: defPath.DEV_PATH,
filename: 'js/bundle.js',
publicPath: '/',
chunkFilename: '[name].chunk.js'
},
module: {
rules: [
{
test: /\.(scss|sass|css)$/,
include: APP_PATH,
use: [
'style-loader', 'css-loader', 'postcss-loader', 'sass-loader' + config.sassLoaderConfig
]
}, {
test: /\.(eot|woff|woff2|ttf|svg|png|jpe?g|gif|mp4|webm)(\?\S*)?$/,
include: APP_PATH,
loader: 'url-loader?limit=8192&name=imgs/[name].[ext]'
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
}),
new webpack.optimize.CommonsChunkPlugin({
names: [
'vendor', 'manifest'
],
filename: 'js/[name].js',
minChunks: Infinity
}),
new ChunkManifestPlugin({
filename: 'chunk-manifest.json',
manifestVariable: 'webpackManifest'
})
],
devServer: {
contentBase: defPath.DEV_PATH,
publicPath: '/',
historyApiFallback: true,
clientLogLevel: 'none',
host: ip,
port: 8090,
open: true,
hot: true,
inline: true,
compress: true,
stats: {
colors: true,
errors: true,
warnings: true,
modules: false,
chunks: false
}
}
})
生产环境 webpack 配置 /webpack.prod.config.js
const webpackMerge = require('webpack-merge');
const webpack = require('webpack');
const ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
const baseConfig = require('./webpack/base');
const config = require('./webpack/config');
const defPath = config.defPath;
const APP_PATH = defPath.APP_PATH;
module.exports = webpackMerge(baseConfig(), {
entry: {
app: defPath.ENTRY_PATH,
vendor: config.vendor
},
output: {
path: defPath.BUILD_PATH,
filename: 'js/bundle.js?[chunkhash]',
publicPath: 'http://xxx.xxx',
chunkFilename: 'chunk.js?[chunkhash]'
},
module: {
rules: [
{
test: /\.(scss|sass|css)$/,
include: APP_PATH,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader!postcss-loader!sass-loader' + config.sassLoaderConfig
})
}, {
test: /\.(eot|woff|woff2|ttf|svg|png|jpe?g|gif|mp4|webm)(\?\S*)?$/,
include: APP_PATH,
loader: 'url-loader?limit=8192&name=imgs/[name].[ext]?[hash]'
}
]
},
plugins: [
new WebpackMd5Hash(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new webpack.optimize.UglifyJsPlugin(config.uglifyJsConfig),
new webpack.optimize.CommonsChunkPlugin({
names: [
'vendor', 'manifest'
],
filename: 'js/[name].js?[chunkhash]',
minChunks: Infinity
}),
new ChunkManifestPlugin({
filename: 'chunk-manifest.json',
manifestVariable: 'webpackManifest'
}),
new ExtractTextPlugin({
filename: 'css/styles.css?[contenthash]',
disable: false,
allChunks: true
})
]
})
对应的 babel 配置 /.babelrc
{
"presets": [
["es2015", {
"modules": false
}],
"stage-2",
"react"
],
"plugins": [
"react-hot-loader/babel",
"transform-object-assign",
"transform-decorators-legacy"
],
"env": {
"development": {
"plugins": [
"react-hot-loader/babel"
]
}
}
}
重要插件版本列表
{
"webpack": "^2.2.1",
"webpack-dev-server": "^2.4.1",
"webpack-md5-hash": "0.0.5",
"webpack-merge": "^4.0.0",
"chunk-manifest-webpack-plugin": "^1.0.0",
"extract-text-webpack-plugin": "^2.1.0",
"html-webpack-plugin": "^2.28.0",
"react-hot-loader": "^3.0.0-beta.6",
}