webpack从入门到上手全流程

webpack学习路径,有个青铜就好

《一文彻底解决新手对 webpack 的恐惧!》

webpack是一个现代JavaScript应用程序的静态模块打包器。所以webpack本质就是为我们打包js的引用,而我们常听到各种loader、各种plugin、热更新、热模块替换等等都是webpack的一个升华,使得webpack能为我们提供更多的帮助。

loader
总结:loader是处理编译js和json以外的文件时用的
常见的loader:

style-loader  
css-loader  
sass-loader  
ts-loader  
file-loader  
babel-loader  
postcss-loader  

plugin: plugin可以在webpack运行到某个阶段时候,帮你做一些事情,类似react/vue中的生命周期。具体的某个插件(plugin)就是在webpack构建过程中的特定时机注入扩展逻辑来改变构建结果,作用于整个构建过程。

postcss:postcss是一个用 JavaScript 工具和插件转换 CSS 代码的工具。

babel:babel 是一个 JavaScript 编译器,他可以让我们不再考虑兼容性,尽情的使用下一代的 JavaScript 语法编程。

es6+语法:babel默认会转换语法,例如:let、const、() => {}、class

es6+特性:babel不会转换特性,特性需要js代码垫片来兼容低版本的浏览器。

@babel/core:@babel/core是babel的核心库

@babel/preset-env:这是一个预设的插件集合,包含了一组相关的插件

@babel/polyfill:需要polyfill来做js的垫片,弥补低版本浏览器缺失的这些新功能

core-js:它是JavaScript标准库的polyfill,而且它可以实现按需加载。

egenerator-runtime:提供generator函数的转码

browserslist:browserslist实际上就是声明了一段浏览器的合集

// 在.browserslistrc中的写法  
> 1%  
last 2 versions  
// 在package.json中的写法  
{  
  "browserslist": ["> 1%", "last 2 versions"]  
}

chunk:它不是库也不是插件,它就是一个名词,顾名思义就是代码块。
chunks:一个chunks至少包含一个chunk,chunks是多个chunk的合集

webpack配置核心概念
  • chunk:指代码块,一个chunk可能由多个模块组合而成,也用于代码合并与分割(这里的合并分割主要指指纹策略的判断),指纹策略简单来说就是文件名后的hash
  • bundle:资源经过webpack流程解析编译后最终输出的成果文件(一个.js格式的文件,也就是我们的output文件)
  • entry:文件打包的入口,webpack会根据entry递归的去寻找依赖,每个依赖都将被它处理,最后打包到集合文件中
  • output:配置打包输出的位置、文件名等
  • loader:默认情况下,webpack仅支持js和json文件,通过loader,可以让它解析其他类型的文件。理论上只要有相应的loader,webpack可以处理任何类型的文件
  • plugin:loader主要的职责是让webpack认识更多的文件类型,而plugin的职责则是让其可以控制构建流程,从而执行一些特殊的任务。插件的功能非常强大,可以完成各种各样的任务
  • mode:目标环境,不用的目标环境会影响webpack打包时的决策
  • production:码进行压缩等一系列优化操作
  • development:有利于热更新的处理,识别哪个模块变化代
  • none:什么都不做,打包时会有提示警告
配置webpack.config.js
const path = require('path')  
const MiniCssExtractPlugin = require('mini-css-extract-plugin')  
const HtmlWebpackPlugin = require('html-webpack-plugin')  
const { CleanWebpackPlugin } = require('clean-webpack-plugin')  
const HtmlPlugin = require('./plugin/htmlPlugin')  
const Webpack = require('webpack')  
  
module.exports = {  
  entry: './src/index.js',  
  output: {  
    filename: 'main.js',  
    path: path.resolve(__dirname, './dist')  
  },  
  mode: 'development',  
  module: {  
    rules: [  
      {  
        test: /\.js$/,  
        use: path.resolve(__dirname, './loader/replaceLoader.js')  
      },  
      {  
        test: /\.css$/,  
        use: [  
          // MiniCssExtractPlugin.loader,  
          'style-loader',  
          'css-loader',  
          'postcss-loader'  
        ]  
      },  
      {  
        test: /\.(png|jpe?g|gif)$/,  
        use: {  
          loader: 'url-loader',  
          options: {  
            name: '[name].[ext]',  
            limit: 1024 * 3,  
            outputPath: "images/",  
            publicPath: "/images",  
          }  
        }  
      }  
    ]  
  },  
  devServer: {  
    open: true,  
    port: 8080,  
    hot: true  
  },  
  plugins: [  
    new MiniCssExtractPlugin({  
      filename: "css/[name].css",  
    }),  
    new HtmlWebpackPlugin({  
      template: './src/index.html'  
    }),  
    new CleanWebpackPlugin(),  
    new HtmlPlugin(),  
    new Webpack.HotModuleReplacementPlugin()  
  ]  
}  

《尚硅谷 Web 前端之 Webpack5 教程》

为什么
  • 开发代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、Css 等语法
  • 打包工具还能压缩代码、做兼容性处理、提升代码性能等
5 大核心概念

Webpack 是基于 Node.js 运行的,所以采用 Common.js 模块化规范

  1. entry(入口)

指示 Webpack 从哪个文件开始打包

  1. output(输出)

指示 Webpack 打包完的文件输出到哪里去,如何命名等

  1. loader(加载器)

webpack 本身只能处理 js、json 等资源,其他资源需要借助 loader,Webpack 才能解析

  1. plugins(插件)

扩展 Webpack 的功能

  1. mode(模式)

主要由两种模式:

  • 开发模式:development
    1)编译代码,使浏览器能识别运行
    2)代码质量检查,树立代码规范
  • 生产模式:production
    1)优化代码运行性能
    2)优化代码打包速度
处理 js 资源

Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法,导致 js 不能在 IE 等浏览器运行,所以我们希望做一些兼容性处理。

  • 针对 js 兼容性处理,我们使用 Babel 来完成
  • 针对代码格式,我们使用 Eslint 来完成
生产环境的webpack.config.js配置(基础版)
const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

// 获取处理样式的Loaders
const getStyleLoaders = (preProcessor) => {
  return [
    MiniCssExtractPlugin.loader,
    "css-loader",
    {
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          plugins: [
            "postcss-preset-env", // 能解决大多数样式兼容性问题
          ],
        },
      },
    },
    preProcessor,
  ].filter(Boolean);
};

module.exports = {
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "../dist"), // 生产模式需要输出
    filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
    clean: true,
  },
  module: {
    rules: [
      {
        // 用来匹配 .css 结尾的文件
        test: /\.css$/,
        // use 数组里面 Loader 执行顺序是从右到左
        use: getStyleLoaders(),
      },
      {
        test: /\.s[ac]ss$/,
        use: getStyleLoaders("sass-loader"),
      },
      {
        test: /\.(png|jpe?g|gif|webp)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024, // 小于10kb的图片会被base64处理
          },
        },
        generator: {
          // 将图片文件输出到 static/imgs 目录中
          // 将图片文件命名 [hash:8][ext][query]
          // [hash:8]: hash值取8位
          // [ext]: 使用之前的文件扩展名
          // [query]: 添加之前的query参数
          filename: "static/imgs/[hash:8][ext][query]",
        },
      },
      {
        test: /\.(ttf|woff2?)$/,
        type: "asset/resource",
        generator: {
          filename: "static/media/[hash:8][ext][query]",
        },
      },
      {
        test: /\.js$/,
        exclude: /node_modules/, // 排除node_modules代码不编译
        loader: "babel-loader",
      },
    ],
  },
  plugins: [
    new ESLintWebpackPlugin({
      // 指定检查文件的根目录
      context: path.resolve(__dirname, "../src"),
    }),
    new HtmlWebpackPlugin({
      // 以 public/index.html 为模板创建文件
      // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
      template: path.resolve(__dirname, "../public/index.html"),
    }),
    // 提取css成单独文件
    new MiniCssExtractPlugin({
      // 定义输出文件名和目录
      filename: "static/css/main.css",
    }),
  // css压缩
    new CssMinimizerPlugin(),
  ],
  // devServer: {
  //   host: "localhost", // 启动服务器域名
  //   port: "3000", // 启动服务器端口号
  //   open: true, // 是否自动打开浏览器
  // },
  mode: "production",
};

vue.config.js 和 webpack.config.js差别

以下为vue项目中实际使用的vue.config.js配置文件

const httpUrl = "www.baidu.com";
// const path = require("path");
const os = require("os");
function getNetworkIp() {
  let needHost = ""; // 打开的host
  try {
    // 获得网络接口列表
    let network = os.networkInterfaces();
    for (let dev in network) {
      let iface = network[dev];
      for (let i = 0; i < iface.length; i++) {
        let alias = iface[i];
        if (
          alias.family === "IPv4" &&
          alias.address !== "127.0.0.1" &&
          !alias.internal
        ) {
          needHost = alias.address;
        }
      }
    }
  } catch (e) {
    needHost = "localhost";
  }
  return needHost;
}
module.exports = {
  publicPath: "./",
  outputDir: "./dist",
  lintOnSave: false,
  // webpack-dev-server 相关配置
  devServer: {
    open: true,
    // host: "192.168.101.167",
    host: getNetworkIp(),
    port: 8088,
    https: false,
    hotOnly: false,
    //设置代理
    proxy: {
      "/api": {
        target: httpUrl,
        changeOrigin: true,
        pathRewrite: {
          "^/api": "/",
        },
      },
    },
  },
  // 第三方插件配置
  pluginOptions: {},
  // webpack相关配置
  chainWebpack: (config) => {
    config.resolve.alias
      .set("vue$", "vue/dist/vue.esm.js")
      .set("@", path.resolve(__dirname, "./src"));
  },
  // css相关配置
  css: {
    // 是否分离css(插件ExtractTextPlugin)
    extract: true,
    // 是否开启 CSS source maps
    sourceMap: false,
    // css预设器配置项
    loaderOptions: {},
    // 是否启用 CSS modules for all css / pre-processor files.
    modules: false,
  },
};

区别

vue-cli2.0时代,webpack的配置文件写在config/index.js 文件
vue-cli3.0时代,没了config文件夹,vue.config.js写在项目的根目录下

  • webpack.config.js是webpack的配置文件,所有使用webpack作为打包工具的项目都可以使用,vue的项目可以使用,react的项目也可以使用。
  • vue.config.js是vue项目的配置文件,专用于vue项目。通过vue.config.js中常用功能的配置,简化了配置工作,当然如果需要更专业的配置工作,webpack.config.js和vue.config.js在vue项目中是可以并存的。

项目中主要做了哪些配置

配置多环境变量
配置基础的vue.config.js
配置 proxy 代理
配置别名
添加IE兼容
开启gzip压缩

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容