记录一个包含大多数功能的webpack配置。

//webpack 是用nodejs写的,是node语法

let path = require('path')//node提供的 相对路径 转 绝对路径 的插件
let HtmlWebpackPlugin = require("html-webpack-plugin")//html webpack 插件
let MiniCssExtractPlugin = require("mini-css-extract-plugin")//抽离css 插件
let OptimizeCssPlugin = require("optimize-css-assets-webpack-plugin")//压缩css 插件
let UglifyJsPlugin = require("uglifyjs-webpack-plugin")//压缩js 插件
let { CleanWebpackPlugin } = require("clean-webpack-plugin")//清除打包目录再打包
let CopyWebpackPlugin = require("copy-webpack-plugin")//拷贝文件到打包目录
const webpack = require('webpack')
module.exports = {
  // optimization: {//优化项
  //   minimizer: [
  //     new UglifyJsPlugin({
  //       cache: true,
  //       patallel: true,
  //       sourceMap: true,
  //       test: /\.js(\?.*)?$/i,
  //     }),//js优化
  //     new OptimizeCssPlugin()//css优化插件
  //   ]
  // },
  // resolve:{//解析地第三方包 common
  //   modules:path.resolve("node_modules"),//指定从node_modules文件夹下面找包
  //   alias:{//别名,如: vue = vue.runtime.js
  //     bootstrap:"bootstrap/dist/css/bootstrap.css"
  //   },
  //   mainFields:["style","main"],//先找package.json里配置的style,再找main
  //   mainFiles:[],//指定入口文件的名字,如果为空,默认入口文件为index.js
  //   extensions:[".js",".css",".json",".vue"],//以拓展名顺序查找,先找.js,如果没找到,再找.css,再找.json,再找.vue
  // },
  devServer: {//开发服务器配置
    port: 3000,//端口号
    progress: true,//进度条
    contentBase: "./dist",//返回的资源目录
    compress: true,//是否压缩
    //添加代理路径,转发请求
    // proxy: {
    //   "/api": "http://localhost:3000"
    // },
    //通过重写的方式,将请求代理到服务器
    // proxy: {
    //   "/api": {
    //     target: "http://localhost:3000",
    //     pathRewrite: { "/api": "" }
    //   }
    // },
    //前端模拟数据 mock
    // before(app) {
    //   app.get('/api/user', (req, res) => {
    //     res.json({ name: '毛毛呀' })
    //   })
    // },
    //有服务端,不想用代理,在服务端启动webpack,后端与前端一起打包,访问服务端端口请求数据



  },
  mode: "development",//模式,两种模式,产线模式"production"、开发模式"development"。产线模式会把编译文件进行压缩优化,代码变成一行。
  entry: "./src/aaa.js",//入口,相对路径
  output: {
    filename: "bundle.[hash:8].js",//打包后的文件名
    path: path.resolve(__dirname, "dist"),//打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
  },
  devtool: "source-map",
  // watch: true,//开启监控,只要改代码就会实时编译
  // watchOptions: {//监控配置
  //   poll: 1000,//每一秒询问1000次(需要更新吗?)
  //   aggregateTimeout: 500,//防抖,500毫秒内输入的代码只打包一次(连续输入代码时不打包)
  //   ignored: /node_modules/,//node_modules文件夹不需要监控
  // },

  plugins: [//存放所有插件
    new webpack.DefinePlugin({
      // DEV: "dev",//这样写会被解析为dev变量,如console.log(dev)
      // DEV: "'dev'",//这样写会被解析为dev字符串,如console.log("dev")
      DEV: JSON.stringify("dev"),//这样写会被解析为dev字符串,如console.log("dev")
      FLAG: "true",//表示赋值true boolean类型
      EXPORESSION: "1+1",//表示赋值1+1的结果(2)
    }),
    new HtmlWebpackPlugin({
      template: "./src/index.html",//模版文件(源文件)地址
      filename: "index.html",//打包后文件名
      // minify:false,
      // minify: {
      //   removeAttributeQuotes: true,//删除双引号
      //   collapseWhitespace: true,//折叠空行(变成一行)
      // },
      hash: true,//引用时文件名加上hash戳
    }),
    new MiniCssExtractPlugin({
      filename: "css/main.css"//抽离css之后输出的文件名
    }),
    // new OptimizeCssPlugin(),//css优化插件
    // new UglifyJsPlugin(),//js优化插件
    new webpack.ProvidePlugin({//将jquery在每个模块都注入成 $
      $: "jquery"
    }),
    // new CleanWebpackPlugin(),//清除打包目录再打包
    // new CopyWebpackPlugin({//拷贝文件到打包目录
    //   patterns: [{
    //     from: "./doc",//源路径
    //     to: "./doc",//目标路径
    //   }]
    // }),
    // new webpack.BannerPlugin("2021年6月1日,作者:毛毛"),//版权声明
  ],
  externals: {
    jquery: "$",
  },
  module: {//模块
    rules: [//规则,多个loader
      {
        test: /\.css$/,//匹配到css结尾的文件,加载css-loader,
        //css-loader负责解析@import语法,将多个css文件合并成一个
        //style-loader负责把css文件插入到<head>标签中
        //loader的特点:功能单一
        //loader的用法:
        //use:"css-loader"字符串形式只能用一个loader
        //use:[]数组形式可以用多个loader
        //多个loader时,加载顺序是从后往前加载(从右向左执行)
        use: [{
          loader: "style-loader",
          options: {
            // insert: "top",//将当前loader添加到<head>标签内容的最上面

            insert: function (element) {
              var parent = document.querySelector('head');
              var lastInsertedElement = window._lastElementInsertedByStyleLoader;
              if (!lastInsertedElement) {
                parent.insertBefore(element, parent.firstChild);
              } else if (lastInsertedElement.nextSibling) {
                parent.insertBefore(element, lastInsertedElement.nextSibling)
              } else {
                parent.appendChild(element)
              }
            }
          }
        },
          "css-loader",
          "postcss-loader"]
      },
      {
        test: /\.styl$/,//匹配到styl结尾的文件,加载stylus-loader,
        use: [
          MiniCssExtractPlugin.loader,//抽离成css文件,用link形式链接
          "css-loader",
          "postcss-loader",
          "stylus-loader"
        ]
      },
      {
        test: /\.js$/,
        use: {
          //用 babel-loader 把es6转es5
          loader: "babel-loader",
        }
      },
      {
        test: require.resolve("jquery"),//判断如果代码中引入了jquery
        loader: "expose-loader",//就使用expose-loader 将jQuery输出成$并绑定在window上
        options: {
          exposes: ["$", "jQuery"],
        },
      },
      // {
      //   test: /\.(png|jpg|gif)$/,
      //   use: [{
      //     loader: 'file-loader',
      //     options: {
      //       esModule: false
      //     }
      //   }]
      // },
      {
        test: /\.(png|jpg|gif)$/,
        //可以做限制,如:图片小于200k,用base64转化,否则用file-loader产生真实图片
        use: {
          loader: "url-loader",
          options: {
            esModule: false,
            limit: 200 * 1024,
            outputPath: "img/",
            publicPath: "http://localhost:3000/",
          }
        }
      },
      {
        test: /\.html$/,
        use: "html-withimg-loader"
      }
      // {
      //   test: /\.js$/,
      //   use: {
      //     //用 eslint-loader 检查代码语法问题
      //     loader: "eslint-loader",
      //     options: {
      //       enforce: "pre",//前置该loader,不受loader加载顺序限制,似乎不生效?
      //       exclude: "./node_nodules/",//排除node_nodules检查
      //     }
      //   }
      // },
    ]
  }
}