基于webpack 2.3的標(biāo)準(zhǔn)語(yǔ)法,包含了less變量替換、React組件熱加載、第三庫(kù)單獨(dú)輸出、區(qū)分生產(chǎn)與開(kāi)發(fā)環(huán)境等常用配置。
'use strict'
module.exports = function( env ) {
// 生成環(huán)境下webpack使用-p參數(shù)開(kāi)啟代碼壓縮
// webpack[-dev-server]使用--env dev參數(shù)指定編譯環(huán)境
var isDev = env == 'dev';
var path = require( 'path' );
var webpack = require( 'webpack' );
var CleanWebpackPlugin = require( 'clean-webpack-plugin' );
var CopyWebpackPlugin = require( 'copy-webpack-plugin' );
var HtmlWebpackPlugin = require( 'html-webpack-plugin' );
var WebkitPrefixer = require( 'autoprefixer' );
var WebpackMd5Hash = require( 'webpack-md5-hash' );
var BundleAnalyzerPlugin = require( 'webpack-bundle-analyzer' ).BundleAnalyzerPlugin;
var sourcedir = path.resolve( __dirname, 'src' );// 源碼和資源文件的放置位置
var outputdir = path.resolve( __dirname, 'build' );// 編譯結(jié)果的放置位置
var webContextRoot = '/myreact/';// 應(yīng)用的實(shí)際訪問(wèn)路徑,默認(rèn)是'/'
// antd的圖標(biāo)字體文件的實(shí)際訪問(wèn)路徑,利用less-load的變量替換功能
var antd_fonticon = webContextRoot + 'assets/antd_fonticon/iconfont';
var hasValue = function( item ) { return item != null; };
return {
//context: path.resolve( __dirname ),
devtool: 'source-map',
devServer: {
host: '0.0.0.0',
port: 8082,
historyApiFallback: true
},
resolve: {
// 讓less-loader等插件能找到以~相對(duì)定位的資源
modules: [sourcedir, 'node_modules']
},
entry: {
main: [
// 編譯新版本js的新api(如Promise),主要是讓IE11能夠執(zhí)行編譯后的代碼
'babel-polyfill',
//使用react-hot-loader@3.0.0-beta.6,
// 搭配webpack-dev-server --hot命令實(shí)現(xiàn)react組件的hot reload
isDev ? 'react-hot-loader/patch' : null,
path.resolve( sourcedir, 'main.jsx' )].filter( hasValue ),
// 第三方庫(kù)匯總
輸出
vendor: ['bootstrap/dist/css/bootstrap.min.css', 'react',
'react-dom', 'react-router', 'redux', 'react-redux',
'react-router-redux', 'moment', 'lodash', 'immutable', 'whatwg-fetch',
// 只含antd的js部分
'antd',
// 各控件還需引入各自的樣式文件
'antd/lib/style/index.less']
},
output: {
path: outputdir,
filename: isDev ? 'js/[name].js' : 'js/[name]_[chunkhash:8].js',
// 使用require.ensure造成的延遲加載的代碼文件
chunkFilename: isDev ? 'js/chunk_[id]_[name].js'
: 'js/chunk_[name]_[chunkhash:8].js',
publicPath: webContextRoot
},
module: {
rules: [{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: [{
// 編譯新版本js語(yǔ)法為低版本js語(yǔ)法
loader: 'babel-loader',
options: {
presets: [
// 編譯es2015版本的js
['babel-preset-es2015', {
modules: false
}], 'babel-preset-stage-2',
// 編譯jsx
'babel-preset-react'],
plugins: [// 支持熱加載react組件
isDev ? 'react-hot-loader/babel' : null,
// 減少重復(fù)的編譯后的輔助方法
'babel-plugin-transform-runtime',
// 按需加載組件的代碼和樣式
['babel-plugin-import', {
libraryName: 'antd',
style: true
}]].filter( hasValue )
}
}]
}, {
test: /\.css$/,
use: ['style-loader',
{
loader: 'css-loader',
options: {
// 第三方組件未以module方式引入css,所以不能在全局開(kāi)啟css module
modules: false
}
},
{ loader: 'postcss-loader', options: { plugins: [WebkitPrefixer] } }]
}, {
test: /\.less$/,
use: ['style-loader',
{
loader: 'css-loader',
options: {
modules: false
}
},
{ loader: 'postcss-loader', options: { plugins: [WebkitPrefixer] } },
{
loader: 'less-loader',
options: {
modules: false,
modifyVars: {
// 替換antd用到的字體文件路徑
"icon-url": JSON.stringify( antd_fonticon )
}
}
}]
}, {
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
// 編碼為dataUrl的最大尺寸
limit: 10000,
// 輸出路徑,相對(duì)于publicPath
outputPath: 'assets/',
name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
}
}
}, {
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
outputPath: 'assets/',
name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
}
}
}, {
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream',
outputPath: 'assets/',
name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
}
}
}, {
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/vnd.ms-fontobject',
outputPath: 'assets/',
name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
}
}
}, {
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/svg+xml',
outputPath: 'assets/',
name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
}
}
}]
},
plugins: [
// momentjs包含大量本地化代碼,需篩選
new webpack.ContextReplacementPlugin( /moment[\/\\]locale$/, /en-ca|zh-cn/ ),
new webpack.optimize.OccurrenceOrderPlugin( true ),
// 復(fù)制無(wú)需編譯的文件至輸出目錄
new CopyWebpackPlugin( [{
from: path.resolve( sourcedir, 'assets' ),
to: 'assets'
}] ),
// 修復(fù)webpack的chunkhash不以chunk文件實(shí)際內(nèi)容為準(zhǔn)的問(wèn)題
new WebpackMd5Hash(),
// 單獨(dú)打包輸出第三方組件,和webpack生成的運(yùn)行時(shí)代碼
new webpack.optimize.CommonsChunkPlugin( {
name: ['vendor', 'manifest']
}),
// 自動(dòng)填充js、css引用進(jìn)首頁(yè)
new HtmlWebpackPlugin( {
title: 'wzp react',
template: path.resolve( sourcedir, 'index.html' ),
inject: 'body' // Inject all scripts into the body
}),
// 設(shè)置環(huán)境變量
new webpack.DefinePlugin( {
process: {
env: {
// process.env.NODE_ENV==="production"
// 應(yīng)用代碼里,可憑此判斷是否運(yùn)行在生產(chǎn)環(huán)境
NODE_ENV: isDev ? JSON.stringify( 'development' )
: JSON.stringify( 'production' )
}
}
}),
// print more readable module names on HMR updates
isDev ? new webpack.NamedModulesPlugin() : null,
// 先清理輸出目錄
isDev ? null : new CleanWebpackPlugin( [outputdir] ),
// 排除特定庫(kù)
isDev ? null : new webpack.IgnorePlugin( /.*/, /react-hot-loader$/ ),
// 輸出報(bào)告,查看第三方庫(kù)的大小
isDev ? null : new BundleAnalyzerPlugin(
{
analyzerMode: 'static',
reportFilename: 'report.html',
openAnalyzer: true,
generateStatsFile: false
})
].filter( hasValue )
}
};
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com