版权声明:原创内容转载请注明出处: https://blog.csdn.net/wuzhe128520/article/details/89789190
这个配置是基于webpack3.X版本的;
1、第一个文件webpack.util.js,主要作用是自动读取入口文件并进行配置,自动生成html模板的配置文件
const glob = require('glob'),
path = require('path'),
htmlWebpackPlugin = require('html-webpack-plugin'),
//公共使用的第三方库,单独打包到一个文件里避免长效缓存失败
vendors = ['jquery', 'lodash'];
const webpackUtil = {
//文件路径
fileDir: {
//打包前的原始路径
origin: {
//入口文件的路径(正则表示)
entryJs: './src/js/pages/',
//页面模板路径(正则表示)
tmpls: './src/view/pages/'
} ,
//打包后的路径
build: {
//打包后的html存放目录
view: './view/',
}
},
//根据给定的值删除数组对应的值
deleteByValue: function(ary, value, isDeleteAll){
var i = 0,
length = ary.length;
for(; i < length; i++){
if(value === ary[i]){
ary.splice(i,1);
//是否删除所有跟value一样的值,默认只删除最近的一个
if(!isDeleteAll){
break;
}
}
}
return ary;
},
//获取所有的入口地址
getEntry: function(globPath) {
//找到正则globPath匹配的文件名(包括完整的路径)
let files = glob.sync(globPath),
entries = {},
entry,
dirname,
basename,
pathname,
extname;
entries['vendors'] = vendors;
for (let i = 0; i < files.length; i++) {
entry = files[i];
//文件的路径
dirname = path.dirname(entry);
//文件名的后缀
extname = path.extname(entry);
//方法返回一个 path 的最后一部分
basename = path.basename(entry, extname);
pathname = path.join(dirname, basename);
entries[basename] = entry;
}
return entries;
},
/**
* [配置webpack插件的选项]
* @param {[string]} tmplsDir [html模板路径]
* @param {[string]} ext [模板的后缀名]
* injectArray: 需要将js插入到head的页面数组
* @return {[type]} [description]
*/
configHtmlWebpackOptions: function(tmplsDir, ext, injectArray, entries, config) {
let pages = Object.keys(entries);
pages = webpackUtil.deleteByValue(pages,'vendors');
//去除vendors这个chunk,已在其他插件处理
pages.forEach(function(pagename) {
let htmlWebpackOption = {
filename: webpackUtil.fileDir.build.view + pagename + '.html',
template: webpackUtil.fileDir.origin.tmpls + pagename + '.' +ext,
inject: injectArray && (injectArray.indexOf(pagename) !== -1)&&'head'||'body',
minify: {
removeComments: true,
collapseWhitespace: false
}
};
if(pagename in config.entry) {
htmlWebpackOption.favicon = './src/images/favicon.ico',
htmlWebpackOption.chunks = ['vendors', 'runtime', pagename]
}
config.plugins.push(
new htmlWebpackPlugin(htmlWebpackOption)
);
});
}
};
module.exports = webpackUtil;
2、webpack.comm.js 公用配置;主要设置插件和各种loader
const path = require('path'),
webpackUtil = require('./webpack.util.js'),
cleanWebpackPlugin = require('clean-webpack-plugin'),
extractTextWebpackPlugin = require('extract-text-webpack-plugin'),
copyWebpackPlugin = require('copy-webpack-plugin'),
webpack = require('webpack'),
//文件路径配置
fileDir = webpackUtil.fileDir;
let config = {
resolve: {
extensions: [".js", ".less", ".css"] // 后缀名自动补全
},
plugins: [
new cleanWebpackPlugin(['dist']),
//提取行内css样式到单独的文件
new extractTextWebpackPlugin('css/[name].css'),
new copyWebpackPlugin([{
from: __dirname + '/src/js/lib/old-plugins/',
to: __dirname + '/dist/js/',
}]),
//全局加载jq(只能在webpack模板中使用)
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery',
}),
],
module: {
rules: [
{
test: require.resolve('jquery'),
use: [
{
loader: 'expose-loader',
options: '$'
},
{
loader: 'expose-loader',
options: 'jQuery'
}
]
},
{
test: /\.js$/,
include: path.resolve(__dirname, 'src/js'),
exclude: path.resolve(__dirname, 'src/js/lib'),
use: ['babel-loader']
},
//抽离css样式
{
test: /\.css$/,
use: extractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
minimize: true
}
},
{
loader: 'postcss-loader'
}
]
})
},
/*
* 将图片混合到css中
* url-loader:与file-loader类似;如果文件小于限制的字节大小,它可以返回一个dataURL(base64格式的图片描述字符串,减少http请求)
*
* */
{
test: /\.(png|jpg|gif|ico)$/,
use: [
{
loader: 'url-loader',
options: {
name: 'images/[name].[ext]',
//将8KB以下的图片转换为base64的dataURL输出形式
limit: 8192
}
}
],
},
//html页面路径自动转换不正确
{
test: /\.html$/,
use: [
'html-loader'
]
},
{
test: /\.ejs$/,
use: [
'ejs-loader'
]
},
//加载字体
{
test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'fonts/[name].[ext]'
}
}
]
},
//编译less
{
test: /\.less$/,
loader: extractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
minimize: true
}
},
{
loader: 'postcss-loader'
},
{
loader: 'less-loader'
}
]
})
}
]
}
};
var entries = webpackUtil.getEntry(fileDir.origin.entryJs + '**/*.js');
config['entry'] = entries;
webpackUtil.configHtmlWebpackOptions(fileDir.origin.tmpls + '**/*.html', 'html', [],entries, config);
module.exports = config;
3、webpack开发模式下;设置开发模式下得服务器相关配置,以及打包后的文件输出配置
const merge = require('webpack-merge'),
path = require('path'),
webpack = require('webpack'),
common = require('./webpack.comm.js');
module.exports = merge(common, {
devtool: 'inline-source-map',
devServer: {
/*
告诉服务器从哪里提供内容.只有在你想要提供静态文件时才需要。
推荐使用绝对路径。
*/
// contentBase: path.resolve(__dirname, 'dist'),
//此路径下的打包文件可在浏览器中访问;确定从哪里提供bundle,并且此选项优先;(是一个虚拟目录,实际上引用的是内存中的文件)
//publicPath: '/build/' //总是以斜杠开始和结尾
// 可以局域网访问
// host: '0.0.0.0',
contentBase: path.resolve(__dirname, 'dist'),
publicPath: "/dist/",
hot: true, //开启热点
inline: true, //开启页面自动刷新
compress: true,
port: '8088', //设置端口号
//监控在contentBase选项里的文件,一旦文件发生改变将会触发整个页面重新加载;
watchContentBase: false,
proxy: {
// 反向代理 /cfy 开头的都转发到后台
'/cfy': {
target: 'http://192.168.1.77:8080',
secure: false,
changeOrigin:true
},
'/hrManeger': {
target: 'http://192.168.1.55:8080',
secure: false,
changeOrigin:true
},
'/user': {
target: 'http://192.168.1.55:8080',
secure: false,
changeOrigin:true
},
'/user': {
target: 'http://192.168.1.77:3000',
secure: false,
changeOrigin:true
},
}
},
plugins: [
//当热更新启用的时候,插件会影响模块显示的相对路径;建议在开发模式下使用;
new webpack.NamedModulesPlugin(),
//热加载
new webpack.HotModuleReplacementPlugin()
],
output: {
//设置生成打包后的根目录
path: path.resolve(__dirname, 'dist'),
//生成后的bundle.js的访问目录
publicPath: '/dist/',l
filename: 'js/[name].bundle.js', //这里的路径是相对于build的
//未配置在entry中,但是在入口js文件中被引用的所有js文件被打包后的路径和文件名
chunkFilename: 'js/[id].bundle.js'
}
});
4、webpack.prod.js生产环境下的配置;
const merge = require('webpack-merge'),
path = require('path'),
webpack = require('webpack'),
uglifyJsPlugin = require('uglifyjs-webpack-plugin'),
common = require('./webpack.comm.js');
module.exports = merge(common, {
devtool: 'source-map',
plugins: [
//压缩js代码
new uglifyJsPlugin(),
//将很少修改的第三方库单独存合并在一个js文件里
new webpack.optimize.CommonsChunkPlugin({
name: 'vendors'
}),
//合并公共的文件(包含js和css)
new webpack.optimize.CommonsChunkPlugin({
name: 'runtime'
}),
//添加新的依赖后,保证hash不会乱修改使长缓存失效
new webpack.HashedModuleIdsPlugin(),
],
output: {
//设置生成打包后的根目录
path: path.resolve(__dirname, 'dist'),
//生成后的bundle.js的访问目录
publicPath: '/hrManeger/dist/',
filename: 'js/[name].bundle.js', //这里的路径是相对于build的
//未配置在entry中,但是在入口js文件中被引用的所有js文件被打包后的路径和文件名
chunkFilename: 'js/[id].bundle.js'
}
});