webpack4学习笔记

一些核心概念文档都有,这里记录一下实例代码。

清除打包文件的插件:clean-webpack-plugin

npm install clean-webpack-plugin --save-dev

webpack.config.js

const {CleanWebpackPlugin} = require('clean-webpack-plugin');
plugins:[
        new CleanWebpackPlugin()
]

//可以查看clean-webpack-plugin插件 返回的是{CleanWebpackPlugin}

打包html文件:

npm install html-webpack-plugin --save-dev

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
new HtmlWebpackPlugin({
            // 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
            template: './src/index.html'
          })

打包图片文件:

npm install html-loader url-loader --save-dev

webpack.config.js
            {
                test:/.(png|jpeg)$/,
                use:[
                    {
                        loader:'url-loader',
                        options:{
                             // 图片大小小于8kb,就会被base64处理
                            // 优点: 减少请求数量(减轻服务器压力)
                            // 缺点:图片体积会更大(文件请求速度更慢)
                            limit: 8 * 1024,
                            // 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
                            // 解析时会出问题:[object Module]
                            // 解决:关闭url-loader的es6模块化,使用commonjs解析
                            esModule: false,
                            // 给图片进行重命名
                            // [hash:10]取图片的hash的前10位
                            // [ext]取文件原来扩展名
                            name: '[hash:10].[ext]'
                        }
                    }
                ]
            },
            {
                test:/.html$/,
                use:'html-loader'
            }

  1. 打包样式文件:
npm install style-loader css-loader sass-loader sass-node postcss-loader autoprefixer 


            {
                test:/.(scss)$/,
                use:['style-loader','css-loader','sass-loader','postcss-loader']
            }

postcss.config.js
module.exports = {
    plugins: [
        require('autoprefixer')({
            overrideBrowserslist: [
                "Android 4.1",
                "iOS 7.1",
                "Chrome > 31",
                "ff > 31",
                "ie >= 8"
            ]
        })
    ]
};



webpack-dev-server的使用:

npm install webpack-dev-server --save-dev
webpack.config.js

// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
  // 特点:只会在内存中编译打包,不会有任何输出
  // 启动devServer指令为:npx webpack-dev-server
  devServer: {
    // 项目构建后路径
    contentBase: resolve(__dirname, "build"),
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 3000,
    // 自动打开浏览器
    open: true,
  },

package.json

"server":"npx webpack-dev-server"

当运行npm run server时报错: Error: Cannot find module 'webpack-cli/bin/config-yargs’

因为webpack和webpack-dev-server兼容问题,官网中使用以下方式启动:
"server":"npx webpack serve"

目前前的webpack.config.js

const {resolve} = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "js/bundle.js",
    path: resolve(__dirname, "dist"),
    publicPath: "./",
  },
  module: {
    rules: [
      {
        test: /.(css)$/,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /.(scss)$/,
        use: ["style-loader", "css-loader", "sass-loader", "postcss-loader"],
      },
      {
        test: /.(jpg|png|jpeg)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              // 图片大小小于8kb,就会被base64处理
              // 优点: 减少请求数量(减轻服务器压力)
              // 缺点:图片体积会更大(文件请求速度更慢)
              limit: 8 * 1024,
              // 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
              // 解析时会出问题:[object Module]
              // 解决:关闭url-loader的es6模块化,使用commonjs解析
              esModule: false,
              // 给图片进行重命名
              // [hash:10]取图片的hash的前10位
              // [ext]取文件原来扩展名
              name: "[hash:10].[ext]",
              outputPath:'img'
            },
          },
        ],
      },
      {
        test: /.html$/,
        use: "html-loader",
      },
      // 打包其他资源(除了html/js/css资源以外的资源)
      {
        // 排除css/js/html资源
        exclude: /.(css|js|html|scss|jpg|png|jpeg)$/,
        loader: "file-loader",
        options: {
          name: "[hash:10].[ext]",
          outputPath: 'media'
        },
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      // 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
      template: "./src/index.html",
    }),
  ],
  // 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
  // 特点:只会在内存中编译打包,不会有任何输出
  // 启动devServer指令为:npx webpack-dev-server
  devServer: {
    // 项目构建后路径
    contentBase: resolve(__dirname, "build"),
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 3000,
    // 自动打开浏览器
    open: true,
  },
  mode: "development",
};

生产环境下的操作

提取css文件

npm install mini-css-extract-plugin --save-dev

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

rules:[
{
        test: /.(css)$/,
        use: [
        // 创建 style 标签,将样式放入 
        // 'style-loader', 
        // 这个 loader 取代 style-loader。作用:提取 js 中的 css 成单独文件
        MiniCssExtractPlugin.loader,
        "css-loader"],   
      },
]

        

plugins:[
new MiniCssExtractPlugin({ 
// 对输出的 css 文件进行重命名 
filename: 'css/built.css' 
})
]

压缩css文件

npm install --save-dev optimize-css-assets-webpack-plugin


plugins:[
      // 压缩 css 
    new OptimizeCssAssetsWebpackPlugin()
]

配置eslint

npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import

webpack.config.js

 /*语法检查: eslint-loader eslint 注意:只检查自己写的源代码,第三方的库是不用检查的 设置检查规则: package.json 中 eslintConfig 中设置~ "eslintConfig": { "extends": "airbnb-base" } airbnb --> eslint-config-airbnb-base eslint-plugin-import eslint */
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
          // 自动修复 eslint 的错误
          fix: true,
        },
      },
package.json
"eslintConfig": {
    "extends": "airbnb-base",
    "env": {
      "browser": true
    }
  }

测试的时候使用console.log输出,如果提示 warning  Unexpected console statement  no-console 则eslint成功。

js兼容问题:这里只记录以下webpack4对js兼容处理问题

package.json
"devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/preset-env": "^7.12.7",
    "babel-loader": "^8.2.2",
    "core-js": "^3.8.0",
    "html-webpack-plugin": "^4.5.0",
    "webpack": "^4.41.6",
    "webpack-cli": "^3.3.11"
  },

webpack.config.json
module: {
    rules: [
      /*
        js兼容性处理:babel-loader @babel/core 
          1. 基本js兼容性处理 --> @babel/preset-env
            问题:只能转换基本语法,如promise高级语法不能转换
          2. 全部js兼容性处理 --> @babel/polyfill  
            问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~
          3. 需要做兼容性处理的就做:按需加载  --> core-js
      */  
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          // 预设:指示babel做怎么样的兼容性处理
          presets: [
            [
              '@babel/preset-env',
              {
                // 按需加载
                useBuiltIns: 'usage',
                // 指定core-js版本
                corejs: {
                  version: 3
                },
                // 指定兼容性做到哪个版本浏览器
                targets: {
                  chrome: '60',
                  firefox: '60',
                  ie: '9',
                  safari: '10',
                  edge: '17'
                }
              }
            ]
          ]
        }
      }
    ]
  },

压缩HTML


const HtmlWebpackPlugin = require("html-webpack-plugin");

new HtmlWebpackPlugin({
      // 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
      template: "./src/index.html",
      // 压缩html代码
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    }),

生产环境的webpack.config.js配置

主要提取公共配置,明确loader的执行先后顺序

const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = 'production';

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader',
  {
    // 还需要在package.json中定义browserslist
    loader: 'postcss-loader',
    options: {
      ident: 'postcss',
      plugins: () => [require('postcss-preset-env')()]
    }
  }
];

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /.css$/,
        use: [...commonCssLoader]
      },
      {
        test: /.less$/,
        use: [...commonCssLoader, 'less-loader']
      },
      /*
        正常来讲,一个文件只能被一个loader处理。
        当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
          先执行eslint 在执行babel
      */
      {
        // 在package.json中eslintConfig --> airbnb
        test: /.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                useBuiltIns: 'usage',
                corejs: {version: 3},
                targets: {
                  chrome: '60',
                  firefox: '50'
                }
              }
            ]
          ]
        }
      },
      {
        test: /.(jpg|png|gif)/,
        loader: 'url-loader',
        options: {
          limit: 8 * 1024,
          name: '[hash:10].[ext]',
          outputPath: 'imgs',
          esModule: false
        }
      },
      {
        test: /.html$/,
        loader: 'html-loader'
      },
      {
        exclude: /.(js|css|less|html|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/built.css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  mode: 'production'
};

原文地址:https://www.cnblogs.com/justsus/p/14070045.html