一、package.json
如上图,添加自定义命令build 与dev,
1.build 对应生产环境的webpack.produce.config.js,执行npm run build会根据这份配置编译打包
2.dev对应开发环境webpack.config.js,执行npm run dev则根据这份配置实时编译,但是生成的文件是存储在内存中
二、贴上demo的目录结构
三、webpack.config.js
var path = require("path");
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin');
//var CopyWebpackPlugin = require('copy-webpack-plugin');
var autoprefixer = require('autoprefixer');
module.exports = {
devServer: {
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
//contentBase: '/',
port: 8080
},
// entry : [ //如果使用这种配置配置webpack-dev-server,那么上面的devServer与plugins中的webpack.HotModuleReplacementPlugin()可以去掉
// "webpack/hot/dev-server",
// "webpack-dev-server/client?http://localhost:8080",
// path.resolve(__dirname, "app/main.js")
// ],
/*
单入口
entry : path.resolve(__dirname, "app/main.js"),
output : {
path : path.resolve(__dirname, "build"),
filename : "bundle.js"
},
*/
entry : {
bundle : path.resolve(__dirname, "app/main.js"),
xxx : path.resolve(__dirname, "app/xxx.js"),
vendors : ["react", "react-dom", "jquery", "react-router"]//抽取公用块
},
output : {
path : path.resolve(__dirname, "build"),
filename : "[name].[hash].js",//这里使用的是dev-server所以加个hash可以防止缓存
//publicPath : '',暂时不知道作用
},
resolve : {
extensions:["",".js",".json",".jsx",".es6","css","scss","png","jpg","jpeg"]
},
module : {
/*
配置参数
test 正则表达式匹配
loader 匹配的文件, "-loader"可以省略
include 需要处理的目录包括进来
exclude 排除不需要处理的目录
query 参数
*/
loaders : [
{
test : /\.js[x]?$/,
exclude: /node_modules/,
loader : "babel",
query: {
presets: ['es2015', 'stage-0', 'react']
}
},
{
test : /\.css$/,
//loader : "style!css"//编译后内连在html中
//loader : ExtractTextPlugin.extract("style", "css!postcss")
loader : ExtractTextPlugin.extract(["css", "postcss"])
//postcss编译css自行添加浏览器的前缀,如chrome -webkit-, firefox -moz-
},
{
test: /\.scss$/,
//loader: 'style!css!sass'//编译后内连在html中
//loader : ExtractTextPlugin.extract("style", "css!sass!postcss")
loader : ExtractTextPlugin.extract(["css", "sass", "postcss"])
//postcss编译css自行添加浏览器的前缀,如chrome -webkit-, firefox -moz-
},
{
test: /\.(png|jpg)$/,
loader: 'url', //url?limit=25000
query : {limit : 10000, name:'images/[name].[ext]'}
//识别url对应到的图片且后缀为png/jpg的,小于10000的时候自行转换为base64Str
//但是引用的时候必须是url(../images/big.png) 不能有双引号或单引号
},
{
test: /\.(eot|woff|woff2|ttf|svg)((\?|\#)[\?\#\w\d_-]+)?$/,
loader: "url",
query: {limit: 10000, name: 'fonts/[name].[ext]'}
//同上
}
]
},
postcss : [autoprefixer({browsers:["last 3 version", "Firefox >= 15", "IE >= 10", "Opera >= 12"]})],//对于需要的浏览器添加编译css时候自动添加前缀
plugins : [
new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity),//抽取公用块
new ExtractTextPlugin("[name].css"),
//分离css,输出名字与entry中定义的相同,如bundle.js对应到bundle.css
new HtmlWebpackPlugin({
title: "I am index.html",
template : path.resolve(__dirname, "build/__index.html"),
filename : "index.html",
chunks : ["vendors", "bundle"],
inject : "body"
}),//根据模版新建html,引入哪个js就能对应引入哪个css,如bundle.js也会引入bundle.css
new HtmlWebpackPlugin({
title: "I am xxx.html",
template : path.resolve(__dirname, "build/__index.html"),
filename : "xxx.html",
chunks : ["vendors", "xxx"],
inject : "body"
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
// new CopyWebpackPlugin([
// { from: path.resolve(__dirname, "build"), to: '../copy' }
// ]),
]
}
四、webpack.produce.config.js
var path = require("path");
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var autoprefixer = require('autoprefixer');
//这里就没必要说得很详细了,与webpack.produce.js很相似
module.exports = {
// devServer: {
// historyApiFallback: true,
// hot: true,
// inline: true,
// progress: true,
// contentBase: '/',
// port: 8080
// },
// entry : [ //如果使用这种配置配置webpack-dev-server,那么上面的devServer与plugins中的webpack.HotModuleReplacementPlugin()可以去掉
// "webpack/hot/dev-server",
// "webpack-dev-server/client?http://localhost:8080",
// path.resolve(__dirname, "app/main.js")
// ],
/*
单入口
entry : path.resolve(__dirname, "app/main.js"),
output : {
path : path.resolve(__dirname, "build"),
filename : "bundle.js"
},
*/
entry : {
bundle : path.resolve(__dirname, "app/main.js"),
xxx : path.resolve(__dirname, "app/xxx.js"),
vendors : ["react", "react-dom", "jquery", "react-router"]
},
output : {
path : path.resolve(__dirname, "build"),
filename : "[name].min.js",
//publicPath : '',
},
resolve : {
extensions:["",".js",".json",".jsx",".es6","css","scss","png","jpg","jpeg"]
},
module : {
/*
配置参数
test 正则表达式匹配
loader 匹配的文件, "-loader"可以省略
include 需要处理的目录包括进来
exclude 排除不需要处理的目录
query 参数
*/
loaders : [
{
test : /\.js[x]?$/,
exclude: /node_modules/,
loader : "babel",
query: {
presets: ['es2015', 'stage-0', 'react']
}
},
{
test : /\.css$/,
//loader : "style!css"
//loader : ExtractTextPlugin.extract("style", "css!postcss")
loader : ExtractTextPlugin.extract(["css?-autoprefixer", "postcss"])
//生产环境需要添加?-autoprefixer才能编译出css并自动添加浏览器样式前缀;
//其实是打包压缩的时候自行删除掉了过时的前缀,通过添加该命令来禁止删除过时的样式前缀
},
{
test: /\.scss$/,
//loader: 'style!css!sass'
//loader : ExtractTextPlugin.extract("style", "css!sass!postcss")
loader : ExtractTextPlugin.extract(["css?-autoprefixer", "sass?-autoprefixer", "postcss"])
},
{
test: /\.(png|jpg)$/,
loader: 'url', //url?limit=25000
query : {limit : 10000, name:'images/[name].[ext]'}
},
{
test: /\.(eot|woff|woff2|ttf|svg)((\?|\#)[\?\#\w\d_-]+)?$/,
loader: "url",
query: {limit: 10000, name: 'fonts/[name].[ext]'}
}
]
},
postcss : [autoprefixer({browsers:["last 3 version", "Firefox >= 15", "IE >= 10", "Opera >= 12"]})],//{browsers:['last 2 versions']}
plugins : [
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
}),//对应编译压缩的react
new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
}),//压缩
new ExtractTextPlugin("[name].min.css"),
new HtmlWebpackPlugin({
title: "I am index.html",
template : path.resolve(__dirname, "build/__index.html"),
filename : "index.html",
chunks : ["vendors", "bundle"],
inject : "body"
}),
new HtmlWebpackPlugin({
title: "I am xxx.html",
template : path.resolve(__dirname, "build/__index.html"),
filename : "xxx.html",
chunks : ["vendors", "xxx"],
inject : "body"
}),
//new webpack.HotModuleReplacementPlugin(),
//new webpack.NoErrorsPlugin(),
new CopyWebpackPlugin([
{ from: path.resolve(__dirname, "build"), to: '../copy' }
]),
//复制,不过这个有些问题,复制的过程在HtmlWebpackPlugin之前
//可以考虑这个transfer-webpack-plugin
]
}
五、参考文章
https://segmentfault.com/a/1190000004172052 webpack常用功能
http://www.codesec.net/view/453356.html webpack-dev-server
http://www.cnblogs.com/grimm/p/5772444.html webpack插件篇
https://zhuanlan.zhihu.com/leanreact webpack+react知乎专栏
https://github.com/postcss/postcss-loader/issues/37 编译css自行添加浏览器前缀
https://segmentfault.com/a/1190000005128101 兼容ie
http://www.aliued.com/?p=3240 兼容问题