webpack配置

620 阅读2分钟

分为三个部分.

webpack.config.js

公共配置:

//测试环境配置
const dev = require('./webpack.dev');
//生产环境配置
const prod = require('./webpack.prod');

const webpack = require('webpack');
const merge = require('webpack-merge');
const path = require('path');
//引入html模板插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
//打包到 配置项中 文件夹
const ExtractTextPlugin = require("extract-text-webpack-plugin");



/* 自动获取项目名 */
const productionName = path.basename(__dirname);
//拼接成打包输出路径
const filepath = path.resolve(__dirname, '../../../build/', productionName);

module.exports = env => {
  let publicPath = '/'; //动态路径.
  //通过不同的全局配置,将两种模式,混合到此公共文件
  let run = {};
  if (env.NODE_ENV == 'production') {
    console.log('启动-->生产模式\n');
    publicPath = '/build/' + productionName + '/';
    run = prod;
  } else  if(env.NODE_ENV == 'development'){
    console.log('启动-->本地开发模式\n');
    run = dev;
  }
  return merge({
    //输入文件路径, 可指定为多个.
    entry: {
      mian: ['babel-polyfill', './main.js'],
    },
    /**
     输出文件路径, 当输入 为多个时,指定固定名字.会创建同名文件,新的文件会覆盖旧的.
     最后只有剩下一个文件.html模板引入时只能找到一个;
     */
    output: {
      path: filepath,
      chunkFilename: 'js/[name].js', //当使用动态加载的模块,使模块另外打包;
      filename: 'js/[name].js',
      publicPath: publicPath //动态路径.把产品里的 URL SRC 中的连接设置成以'/'为根目录绝对地址.
    },
    //加载器  模块  配置 对象
    module: {
      // 文件加载 规则,检查以test属性值为后缀名的文件时,对应使用的加载器;
      rules: [{
          test: /\.css$/, //用正则验证文件后缀名,
          loader: ExtractTextPlugin.extract({
            use: [{
              loader: 'css-loader',
              options: {
                fallback: 'style-loader'
              }
            }]
          })
        },
        {
          test: /\.vue$/,
          loader: 'vue-loader',
          options: {
            loaders: {
              css: ExtractTextPlugin.extract({
                use: 'css-loader',
                fallback: 'vue-style-loader'
              })
            }
          }
        },
        {
          test: /\.(jpg|png|gif)$/,
          use: [{
            loader: 'url-loader',
            options: {
              limit: 8192,
              mimetype: 'image/png',
              name: 'images/[name].[ext]',
              fallback: 'file-loader'
            }
          }],
        },
        {
          test: /\.js$/,
          exclude: /(node_modules|bower_components)/, //排除某些文件夹,
          use: {
            loader: 'babel-loader'
          }
        },
        //加载字体.
        {
          test: /\.(woff|woff2|eot|ttf|otf)$/,
          use: [{
            loader: 'file-loader',
            options: {
              name: 'css/font/[name].[ext]'
            }
          }],
        },
        {
          test: require.resolve('../../lib/zepto.min.js'),
          loader: 'exports-loader?window.Zepto!script-loader'
        }
      ]
    },
    resolve: {
      extensions: [' ', '.js', '.json', '.vue'],
      alias: {
        'vue$': 'vue/dist/vue.js'
      }
    },
    plugins: [
      //html模板实例化+配置
      new HtmlWebpackPlugin({
        filename: 'index.html',
        template: './index.html',
        inject: true
      }),
      //打包css
      new ExtractTextPlugin("css/style.css"),
      //引入zepto
      new webpack.ProvidePlugin({
        $: path.resolve('../../lib', 'zepto.min.js')
      })
    ]
  }, run)
}

生产打包配置

webpack.prod.js

const webpack = require('webpack');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

module.exports = {
  entry: {
		// 如果有依赖的第三方库,都在这里统一打包到vendor.js中
		vendor: ['vue', 'vue-router', 'axios']
	},
  plugins: [
		// 压缩CSS
		new OptimizeCSSPlugin({
			cssProcessorOptions: {
				safe: true
			}
		}),
		// 压缩JS
		new webpack.optimize.UglifyJsPlugin({
			compress: {
				warnings: false,
				drop_debugger: true,
				// drop_console: true
			}
		}),
		new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
		//防止重复,提取到一个新生成的 chunk
    // 抽取公共模块
		new webpack.optimize.CommonsChunkPlugin({
			// 这公共代码的chunk名为'vendor'
			names:"vendor",
		 // 生成后的文件名
			filename: "js/[name].js",
			// 设定要有3个chunk(即3个页面)加载的js模块才会被纳入公共代码
			minChunks: 2
		})
  ]
};

// js文件还可以用 .gz 格式压缩,但是要服务端支持.可压缩到打包后的30%.

测试环境:

webpack.dev.js

const webpack = require('webpack');
const os = require('os');

//获取本机IP,当IP 设置为本机IP 后, 局域网内其它人可以通过 IP+端口,访问本机开发环境.
let host = '';
let obj = os.networkInterfaces();
for (n in obj) {
  obj[n].map(v => {
    /^[0-9]{2}\.[0-9]{3}\.[0-9]{3}\.[0-9]{3}$/.test(v.address) && (host = v.address)
  })
}

module.exports = {
  devtool: 'cheap-module-eval-source-map',
  devServer: {
    inline: true, //自动刷新页面
    open: true, //自动打开浏览器
    quiet: false, //控制台中不输出打包的信息
    port: 9091,//监听端口
    //设置成自己的IP可以在局域网中广播 地址为 本机 IP  xxx.xxx.xxx.xxx:port 机器名无效
    host: host,
    //如果要开 启 webpack-dev-sever 上的热更新,必须加上这个选项.但是一般都不能自动刷新浏览器
    hot: true,
    //当出现编译器错误或警告时,在浏览器中显示全屏叠加
    overlay: {
      warnings: true,
      errors: true
    },
    //请求地址代理地址
    proxy: {
      //开发数据代理到,局域网内任何服务包括自己,可以换成项目后端开发的IP
      '/Service/*': {//正则式匹配,将请求代理到target服务器.
        target: 'http://172.0.0.1:7001'
      }
    }
  },
  plugins: [
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ]
};

package.json

极简配置.只有两个命令.上面的配置中依赖包缺少,请安装.

{
  "name": "xxxxxx",
  "version": "1.0.1",
  "main": "main.js",
  "scripts": {
    "dev": "webpack-dev-server -d  --env.NODE_ENV=development",
    "prod": "webpack -p --env.NODE_ENV=production"
  }
}