webpack3.10.1 升级webpack4 指南

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kingrome2017/article/details/82830688

随着模块化开发的普及,项目功能需求不断增加,Webpack已成为项目开发的标配,能够大大提高你的开发效率,下面整理了关键的两个文件,还在优化中,仅供参考

{
  "name": "demo",
  "version": "1.0.0",
  "description": "this is a obj",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack"
  },
  "author": "niko4",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^9.1.5",
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.7.0",
    "css-loader": "^1.0.0",
    "cssnano": "^4.1.0",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "file-loader": "^2.0.0",
    "glob-all": "^3.1.0",
    "html-webpack-plugin": "^3.2.0",
    "imagemin": "^5.3.1",
    "imagemin-pngquant": "^5.1.0",
    "img-loader": "^3.0.0",
    "node-sass": "^4.9.3",
    "postcss": "^7.0.2",
    "postcss-cssnext": "^3.1.0",
    "postcss-loader": "^3.0.0",
    "postcss-sprites": "^4.2.1",
    "purify-css": "^1.2.5",
    "purifycss-webpack": "^0.7.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.0",
    "url-loader": "^1.1.1",
    "webpack": "^4.17.2",
    "webpack-cli": "^3.1.0"
  },
  "dependencies": {
    "babel-polyfill": "^6.26.0",
    "babel-runtime": "^6.26.0",
    "lodash": "^4.17.10"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}

webpack.config.js

let path =  require('path')
let webpack = require('webpack')
const PurifyCSS = require("purifycss-webpack");
const glob = require("glob-all");
let ExtractTextPlugin = require("extract-text-webpack-plugin");

const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports={
    entry: {
        // page: './src/page.js'
        app: './app.js'
    },
    output: {
        publicPath: "./dist/",
        filename: '[name].bundle.js',
        chunkFilename: '[name].chunk.js'
    },
    resolve: {
        alias: {
          jQuery$: path.resolve(__dirname, "src/assets/js/jquery.min.js")
        }
    },
    module: {
        rules:[
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: '/node_modules/'
            },
            {
                test: /\.scss$/,
                // css处理为style标签
                use: ExtractTextPlugin.extract({
                    // 对于不提取为单独文件的css样式的loader
                    fallback: {
                      loader: "style-loader"
                    },
                    use: [
                      {
                        loader: "css-loader"
                      },
                      {
                        loader: "postcss-loader",
                        options: {
                            ident: 'postcss',
                            plugins: [
                                require('autoprefixer')(),
                                require('postcss-sprites')({
                                    spritePath: './dist/sprite'
                                })
                            ]
                        }
                      },
                      {
                        loader: "sass-loader"
                      }
                    ]
                })
            },
            {
                test: /\.(png|jpg|jpeg|gif)$/,
                use: [
                  {
                    loader: "url-loader",
                    options: {
                      name: "[name]-[hash:5].min.[ext]",
                      limit: 10000, // size <= 20KB
                      publicPath: "static/",
                      outputPath: "static/"
                    }
                  },
                  {
                    loader: "img-loader",
                    options: {
                      plugins: [
                        require("imagemin-pngquant")({
                          quality: "80"
                        })
                      ]
                    }
                  }
                ]
            }
        ]
    },
    plugins:[
        new ExtractTextPlugin({
            filename: '[name].min.css',
            allChunks: false // 只包括初始化css, 不包括异步加载的CSS
        }),
        new PurifyCSS({
            paths: glob.sync([
              // 要做CSS Tree Shaking的路径文件
              path.resolve(__dirname, "./*.html"),
              path.resolve(__dirname, "./src/*.js")
            ])
        }),
        new webpack.ProvidePlugin({
            jQuery: "jQuery" // 本地Js文件
        }),
        new HtmlWebpackPlugin({
            filename: "index.html",
            template: "./index.html",
            chunks: ["app"], // entry中的app入口才会被打包
            minify: {
              // 压缩选项
              collapseWhitespace: true
            }
        })
    ]
    // optimization: {
    //     splitChunks: {
    //       cacheGroups: {
    //         // 注意: priority属性
    //         // 其次: 打包业务中公共代码
    //         common: {
    //           name: "common",
    //           chunks: "all",
    //           minSize: 1,
    //           priority: 0
    //         },
    //         // 首先: 打包node_modules中的文件
    //         vendor: {
    //           name: "vendor",
    //           test: /[\\/]node_modules[\\/]/,
    //           chunks: "all",
    //           priority: 10
    //           // enforce: true
    //         }
    //       }
    //     }
    // }
}

由于项目从3.10.1升级到webpack 4+,有一些官方废弃的API,以上的一些配置请以官方文档为准,还在优化更新中

下面的config是配置devserver的相关选项

/**
 * 1. webpack-dev-server: 配置 devServer 选项
 * 2. SourceMap: 配置 devtool 选项( 不同的loader也应该打开对应的sourcemap选项 )
 * 3. 设置代理: devServer.proxy 进行跨域代理设置
 * 4. 路由 rewrite: devServer.historyApiFallback  配合前端路由使用,没有定义的路由不会出现404
 * 5. 模块热更新: HotModuleReplacementPlugin && NamedModulesPlugin, 更多请见 './app.js'
 */
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");

const path = require("path");

module.exports = {
  entry: {
    app: "./app.js"
  },
  output: {
    publicPath: "/",
    path: path.resolve(__dirname, "dist"),
    filename: "[name]-[hash:5].bundle.js",
    chunkFilename: "[name]-[hash:5].chunk.js"
  },
  devtool: "source-map",
  devServer: {
    contentBase: path.join(__dirname, "dist"),
    port: 8000,
    hot: true,
    overlay: true,
    proxy: {
      "/comments": {
        target: "https://m.weibo.cn",  //代理地址
        changeOrigin: true, //改变代理源
        logLevel: "debug",
        headers: {
          Cookie: ""
        }
      }
    }
    // historyApiFallback: {
    //   rewrites: [
    //     // {
    //     //   from: /^\/([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/,
    //     //   to: function(ctx) {
    //     //     return "/" + ctx.match[1] + ctx.match[2] + ".html";
    //     //   }
    //     // },
    //     {
    //       from: /./,
    //       to: "dist/index.html"
    //     }
    //   ]
    // }
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "./index.html",
      chunks: ["app"]
    }),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.ProvidePlugin({
      $: "jquery"
    })
  ]
};

关于模块热更新的应用

import sum from "./vendor/sum";
console.log("sum(1, 2) = ", sum(1, 2));
var minus = require("./vendor/minus");
console.log("minus(1, 2) = ", minus(1, 2));
require(["./vendor/multi"], function(multi) {
  console.log("multi(1, 2) = ", multi(1, 2));
});

$.get(
  "/comments/hotflow",
  {
    id: "4263554020904293",
    mid: "4263554020904293",
    max_id_type: "0"
  },
  function(data) {
    console.log(data);
  }
);

if (module.hot) {
  // 检测是否有模块热更新
  module.hot.accept("./vendor/sum.js", function() {
    // 针对被更新的模块, 进行进一步操作
    console.log("/vendor/sum.js is changed");
  });
}

生产、开发模式的切换,config相关的配置
webpack

下面的三块内容区,依次对应上图的build目录

const webpack = require("webpack");
const merge = require("webpack-merge");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

const path = require("path");

const productionConfig = require("./webpack.prod.conf");
const developmentConfig = require("./webpack.dev.conf");

const generateConfig = env => {
  let scriptLoader = [
    {
      loader: "babel-loader"
    }
  ];
  let scssLoader = [
    {
      loader: "css-loader",
      options: {
        minimize: true,
        sourceMap: env === "development" ? true : false
      }
    },
    {
      loader: "sass-loader",
      options: { sourceMap: env === "development" ? true : false }
    }
  ];
  let styleLoader =
    env === "production"
      ? ExtractTextPlugin.extract({
          fallback: {
            loader: "style-loader"
          },
          use: scssLoader
        })
      : [
          {
            loader: "style-loader",
            options: { sourceMap: env === "development" ? true : false }
          }
        ].concat(scssLoader);

  return {
    entry: { app: "./src/app.js" },
    output: {
      publicPath: env === "development" ? "/" : __dirname + "/../dist/",
      path: path.resolve(__dirname, "../dist"),
      filename: "[name]-[hash:5].bundle.js",
      chunkFilename: "[name]-[hash:5].chunk.js"
    },
    module: {
      rules: [
        { test: /\.js$/, exclude: /(node_modules)/, use: scriptLoader },
        { test: /\.scss$/, use: styleLoader }
      ]
    },
    plugins: [
      new HtmlWebpackPlugin({
        filename: "index.html",
        template: "./index.html",
        chunks: ["app"],
        minify: {
          collapseWhitespace: true
        }
      }),
      new webpack.ProvidePlugin({ $: "jquery" })
    ]
  };
};

module.exports = env => {
  let config = env === "production" ? productionConfig : developmentConfig;
  return merge(generateConfig(env), config);
};

const webpack = require("webpack");

const path = require("path");

module.exports = {
  devtool: "source-map",
  devServer: {
    contentBase: path.join(__dirname, "../dist/"),
    port: 8000,
    hot: true,
    overlay: true,
    proxy: {
      "/comments": {
        target: "https://m.weibo.cn",
        changeOrigin: true,
        logLevel: "debug",
        headers: {
          Cookie: ""
        }
      }
    }
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin()
  ]
};

const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");

const path = require("path");

module.exports = {
  plugins: [
    new ExtractTextPlugin({
      filename: "[name].min.css",
      allChunks: false // 只包括初始化css, 不包括异步加载的CSS
    }),
    new CleanWebpackPlugin(["dist"], {
      root: path.resolve(__dirname, "../"),
      verbose: true
    })
  ]
};

对应的package.json

{
  "scripts": {
    "server": "webpack-dev-server --env development --open --config build/webpack.common.conf.js",
    "build": "webpack --env production --config build/webpack.common.conf.js"
  }
}

猜你喜欢

转载自blog.csdn.net/kingrome2017/article/details/82830688
今日推荐