美文网首页
Webpack 5经验总结、常见问题

Webpack 5经验总结、常见问题

作者: 衡成飞 | 来源:发表于2022-01-04 15:12 被阅读0次

    <div align="center">
    <a href="https://github.com/webpack/webpack">
    <img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
    </a>

    <p>
    本文主要介绍,最新版本webpack 5在开发和生产环境下的常见配置、及常见错误。
    </p>
    </div>


    <h1 align="center">Dependencies</h1>

    Name Status Install Size Description
    <a href="https://github.com/webpack/webpack"><img width="48" height="48" src="https://cdn.worldvectorlogo.com/logos/webpack-icon.svg"></a>
    webpack
    模块打包器
    <a href="https://github.com/webpack/webpack"><img width="48" height="48" src="https://cdn.worldvectorlogo.com/logos/webpack-icon.svg"></a>
    webpack-cli
    webpack官方命令行工具
    <a href="https://github.com/webpack/webpack"><img width="48" height="48" src="https://cdn.worldvectorlogo.com/logos/webpack-icon.svg"></a>
    webpack-dev-server
    Serves a webpack app. Updates the browser on changes.
    <a href="https://github.com/webpack/webpack"><img width="48" height="48" src="https://cdn.worldvectorlogo.com/logos/webpack-icon.svg"></a>
    webpack-merge
    webpack配置文件merge
    <a href="https://github.com/webpack-contrib/style-loader"><style></a> Add exports of a module as style to DOM
    <a href="https://github.com/webpack-contrib/css-loader"><img width="48" height="48" src="https://worldvectorlogo.com/logos/css-3.svg"></a>
    css-loader
    Loads CSS file with resolved imports and returns CSS code

    <h1 align="center">Usage</h1>

    Description 解决办法
    根据不同环境进行打包,共同项配置抽取出来 创建3个文件common.js(通用配置),dev.js(开发环境),prod.js(生产环境),引入webpack-merge包,参考 环境配置
    path.resolve用法 解析为绝对路径,可理解为cd命令,一层层拼接
    禁止生成xx.js.LICENSE.txt文件 webpack已集成TerserPlugin,new TerserPlugin({ extractComments: false,})
    不打包js库,而通过cdn引入 externals: { jquery: "jQuery",axios:"axios",dayjs: "dayjs",},
    打包生成的js文件头部加上package版本号 const packageinfo = require("./package.json");
    依赖的node_modules不打包在使用的js文件中,而是全部打包到一个js文件中 splitChunks: {chunks: "all",},带来的问题是1个js文件过大,可采用externals优化或cacheGroups配置提取指定的module

    <h1 align="center">常见问题</h1>

    错误场景 Error Description 解决办法
    <img width="40" height="40" src="https://cdn.worldvectorlogo.com/logos/internet-explorer-2.svg"> Automatic publicPath is not supported in this browser 参考官方文档、定义publicPath
    <img width="40" height="40" src="https://cdn.worldvectorlogo.com/logos/internet-explorer-2.svg"> SCRIPT5022: SecurityError 重启IE浏览器
    <img width="40" height="40" src="https://cdn.worldvectorlogo.com/logos/internet-explorer-2.svg"> ES6、Promise等语法错误 使用babel、target设置其编辑环境
    <img width="30" height="30" src="https://cdn.worldvectorlogo.com/logos/chrome.svg"> <img width="30" height="30" src="https://cdn.worldvectorlogo.com/logos/internet-explorer-2.svg"> axios请求参数中文乱码 service.get(url,params)使用params参数,不要拼接到url后面

    <h1 align="center">webpack配置文件</h1>

    执行命令

      "scripts": {
        "start": "webpack serve --open --config webpack.dev.js",
        "build": "webpack --config webpack.prod.js"
      },
    

    webpack.prod.js

    const { merge } = require("webpack-merge");
    const common = require("./webpack.common.js");
    const TerserPlugin = require("terser-webpack-plugin");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const packageinfo = require("./package.json");
    const webpack = require("webpack");
    
    module.exports = merge(common, {
      mode: "production",
      target: ["web", "es5"],
      optimization: {
        minimizer: [
          new TerserPlugin({
            extractComments: false, //禁止生成注释到LICENSE.txt
          }),
        ],
      },
      plugins: [
        new HtmlWebpackPlugin({
          title: "Production",
          filename: "index.html", // 输出文件【注意:这里的根路径是module.exports.output.path】,即上面的dist
          template: "./src/index.html", // 源模板文件,复制此结构的文件
          hash: false,
          chunks: ["index"],
        }),
        new webpack.BannerPlugin(`dfzq-web@version=${packageinfo.version}`),
      ],
    });
    

    webpack.dev.js

    const { merge } = require("webpack-merge");
    const common = require("./webpack.common.js");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const webpack = require("webpack");
    
    //使用环境变量,反之则使用root “/”
    const ASSET_PATH = process.env.ASSET_PATH || "/";
    
    module.exports = merge(common, {
      mode: "development",
      output: {
        publicPath: ASSET_PATH,
      },
      //在webpack5版本中使用默认或者'web'参数时,hot热部署是有效的。但是编译的runtime代码IE浏览器不识别,语法不支持
      //使用target: ['web','es5'],可以使编译的代码使用es5的特性,能正常在IE中使用。但是热更新失效
      //webpack5热更新失效问题只能等待官方新版本中会得到优化解决,暂时建议在开发模式中使用target: 'web',在生产模式中使用target: ['web','es5']
      target: ["web"], //热启动生效,IE无法识别runtime代码
      devtool: "eval-source-map",
      devServer: {
        port: 3000,
        open: true,
        hot: true,
        historyApiFallback: true,
        allowedHosts: "all",
      },
      plugins: [
        new HtmlWebpackPlugin({
          title: "Development",
          filename: "index.html", // 输出文件【注意:这里的根路径是module.exports.output.path】,即上面的dist
          template: "./src/index.html", // 源模板文件,复制此结构的文件
          hash: false,
          chunks: ["index"],
        }),
        new webpack.DefinePlugin({
          "process.env.ASSET_PATH": JSON.stringify(ASSET_PATH),
        }),
      ],
    });
    

    webpack.common.js

    const path = require("path");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const { CleanWebpackPlugin } = require("clean-webpack-plugin"); // 清理dist文件夹
    const webpack = require("webpack");
    const CopyPlugin = require("copy-webpack-plugin"); //将单个文件或整个目录复制到构建目录
    
    const publishPath = path.resolve(__dirname, "dfzq-office"); //生成的路径
    module.exports = {
      entry: {
        index: path.resolve(__dirname, "./src/index.js"),
        author: path.resolve(__dirname, "./src/js/author.js"),
      },
      output: {
        filename: (chunkData) => {
          const name = chunkData.chunk.name;
          if (name === "excel"
          ) {
            return "js/[name].[chunkhash:5].min.js";
          } else {
            return "js/[name].min.js";
          }
        },
        path: publishPath,
      },
      optimization: {
        //将node_modules模板分离出来,不用打包在引用的各个js里,使得体积很大
        splitChunks: {
          chunks: "all",
        },
      },
      module: {
        rules: [
          { test: /\.txt$/, use: "raw-loader" },
          { test: /\.(css|sass|scss)$/, use: ["style-loader", "css-loader"] },
          {
            test: /\.(ico|png|jpe?g|gif)$/i,
            loader: "file-loader",
            options: {
              name: "[path][name].[ext]",
              context: "src", //上下文路径,如果没有此项,dist目录下将会多一个src文件夹
            },
          },
          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader",
            options: {
              presets: [
                [
                  "@babel/preset-env",
                  {
                    useBuiltIns: "usage",
                    corejs: {
                      // core-js的版本
                      version: 3,
                    },
                    // 需要兼容的浏览器
                    targets: {
                      chrome: "60",
                      firefox: "60",
                      ie: "9",
                      safari: "10",
                      edge: "17",
                    },
                  },
                ],
              ],
            },
          },
        ],
      },
      performance: { hints: false },
      externals: {
        jquery: "jQuery",
        axios: "axios",
        dayjs: "dayjs",
      },
      plugins: [
        // 执行顺序由上至下
        new CleanWebpackPlugin({
          cleanOnceBeforeBuildPatterns: [publishPath],
        }),
        new webpack.ProvidePlugin({
          //定义全局import
          $: "jquery",
          jQuery: "jquery",
        }),
        new HtmlWebpackPlugin({
          title: "作者页面",
          filename: "pages/author.html",
          template: "./src/pages/author.html",
          hash: false,
          chunks: ["author"],
        }),
        new CopyPlugin({
          patterns: [
            {
              from: "./src/js/office-js",
              to: "js/office-js",
            },
            {
              from: "./src/images/",
              to: "images",
            },
          ],
        }),
      ],
    };
    

    <h1 align="center">参考文献</h1>

    Production <span id="production"></span>

    https://webpack.js.org/guides/production/

    publicPath

    https://webpack.js.org/guides/public-path/#root

    DefinePlugin

    https://webpack.js.org/plugins/define-plugin/#usage

    Externals

    https://webpack.js.org/configuration/externals/#root

    相关文章

      网友评论

          本文标题:Webpack 5经验总结、常见问题

          本文链接:https://www.haomeiwen.com/subject/hbiqcrtx.html