【面试准备·2】webpack

/** 如果您发现错误,请一定要告诉窝,拯救一个辣鸡(但很帅)的少年就靠您了!*/

本文基于 webpack4

什么是 webpack

webpack 是一个打包工具。

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

什么是 loader 和 plugins

loader

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。通过 loader 可以把其他格式的文件转为 webpack 可以打包的模块。

loader 有三种配置方式

  • 配置文件:通过 module.rules 字段配置。
  • 内联:可以在 import 等引入语句中指定 loader。使用 ! 将资源中的 loader 分开。分开的每个部分都相对于当前目录解析。
  • CLI:通过 CLI 使用 loader

一组链式的 loader 将按照相反的顺序执行。

常用 loader :babel-loader、style-loader、css-loader、less-loader、postcss-loader、eslint-loader、vue-loader ……

plugins

插件目的在于解决 loader 无法实现的其他事。

常用 plugins:DefinePlugin(定义全局常量)、copy-webpack-plugin(复制文件)、extract-text-webpack-plugin(分离出CSS文件)IgnorePlugin(忽略文件)……

webpack 如何解析代码模块路径

webpack 能够解析三种文件路径

  • 绝对路径

  • 相对路径

    import/require 中给定的相对路径,会添加此上下文路径(context path),以产生模块的绝对路径(absolute path)。

  • 模块路径

    模块将在 resolve.modules 中指定的所有目录(默认是 [node_modules] )内搜索。

如果路径指向一个文件

  • 如果路径具有文件扩展名,则被直接将文件打包。
  • 否则,将使用 [resolve.extensions] 选项作为文件扩展名来解析,此选项告诉解析器在解析中能够接受哪些扩展名(例如 .js, .jsx)。

如果路径指向一个文件夹件

  • 如果文件夹中包含 package.json 文件,则按照顺序查找 resolve.mainFields 配置选项中指定的字段。并且 package.json 中的第一个这样的字段确定文件路径。
  • 如果 package.json 文件不存在或者 package.json 文件中的 main 字段没有返回一个有效路径,则按照顺序查找 resolve.mainFiles 配置选项中指定的文件名,看是否能在 import/require 目录下匹配到一个存在的文件名。
  • 文件扩展名通过 resolve.extensions 选项采用类似的方法进行解析。

hash 和 chunkhash 的区别

Webpack中hash与chunkhash的区别,以及js与css的hash指纹解耦方案

  • hash:项目中任何一个文件改动后就会被重新创建,所有的文件名都会使用相同的 hash 指纹。
  • chunkhash:是根据具体模块文件的内容计算所得的 hash 值,所以某个文件的改动只会影响它本身的 hash 指纹,不会影响其他文件。
  • contenthash:代表的是文本文件内容的 hash 值,是指打包后文件的内容。

webpack-dev-server

启动 webpack-dev-server 相当于先通过 webpack 打包,然后,启动本地静态服务器运行打包后的代码。通过设置 modedevelopment 可以使用一些 webpack 为 development 模式预设的一些配置。

可以通过 devServer 字段来配置 webpack-dev-server 。

模块热替换(HMR, hot module replacement)

模块热替换功能会在应用程序运行过程中,替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面期间丢失的应用程序状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 在源代码中对 CSS/JS 进行修改,会立刻在浏览器中进行更新,这几乎相当于在浏览器 devtools 直接更改样式。

通过设置 devServer.hot=true 可以在 webpack-dev-server 中使用 HMR 。

手写 webpack 配置

一个简单的 react 项目配置。使用了常用插件和 loader ,完整配置可见 github.com/G-lory/fron…

点击查看代码
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');


module.exports = {
  // mode: 'production'
  /**
   * 配置入口文件
   * 相当于
   * entry { main: './src/index.js' }
   * 可以配置多个入口
   */
  entry: './src/index.js',

  /**
   * 配置输出路径和文件名
   */
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[chunkhash].js'
  },

  module: {
    rules: [
      /**
       * 配置 babel-loader 来使用 ES6 和 react 语法
       * test 和 include/exclude 指定作用的文件
       * use 指定 loader 和相关配置
       */
      {
        test: /\.js$/,
        include: [
          path.resolve(__dirname, 'src') // 指定哪些路径下的文件需要经过 babel-loader 处理
        ],
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react']
          }
        }
      },
      /**
       * 将 eslint-loader 设置为前置 loader
       * 因为 eslint 检查的是未经处理的源代码
       * 要保证最先进行处理
       * 通过 npx eslint --init 命令初始化一个 eslint 配置文件
       */
      {
        enforce: "pre",
        test: /\.js$/,
        include: [
          path.resolve(__dirname, 'src')
        ],
        loader: "eslint-loader"
      },
      /**
       * v4 以后使用 mini-css-extract-plugin 代替 extract-text-webpack-plugin
       * style-loader 是把样式通过 js 生成样式插入到 html 
       * MiniCssExtractPlugin 是提取样式到文件
       * 所以使用 MiniCssExtractPlugin 就不需要 style-loader 了
       * css-loader 处理 css 文件的引用 @import and url() like import/require()
       * postcss-loader 配置见文件 postcss.config.js 自动添加浏览器前缀
       */
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader"
        ]
      },
      /**
       * 处理图片
       */
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[ext]'
            }
          },
        ],
      }
    ]
  },

  plugins: [
    /**
     * 将打包好的js和css文件在指定html文件中自动引入
     */
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'public/index.html'
    }),
    /**
     * 提取css到指定文件
     */
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css",
      // chunkFilename: "[id].css"
    }),
    /**
     * 打包前删除之前的生成文件
     * 默认删除 <PROJECT_DIR>/dist/ 下的所有文件
     */
    new CleanWebpackPlugin(),
    /**
     * 用于创建一些在编译时可以配置的全局常量
     */
    new webpack.DefinePlugin({
      VERSION: JSON.stringify('5fa3b9')
      // 如果指定了 mode 会自动添加变量 process.env.NODE_ENV = mode
      // "process.env.NODE_ENV": JSON.stringify("production")
    }),
    /**
     * 复制文件 不经过webpack处理 直接复制到指定目录
     * from 配置来源,to 配置目标路径
     */
    new CopyWebpackPlugin([
      { from: 'src/assets/favicon.ico', to: 'favicon.ico' }
    ])
  ],

  /**
   * 配置代码的解析路径
   */
  resolve: {
    /**
     * 配置路径别名
     */
    alias: {
      '@src': path.resolve(__dirname, 'src')
    },
    /**
     * 搜索模块路径的目录
     */
    modules: [
      "node_modules"
    ],
    // 查找路径是自动添加的文件后缀
    // 减少配置以防降低查找效率
    extensions: [".js", ".jsx"]
  },

  optimization: {
    // mode 为 production 时
    // 默认开启压缩
    // minimize: true
    // 可以通过提供一个或多个定制过的 TerserPlugin 实例,覆盖默认压缩工具(minimizer)。
    minimizer: [new UglifyJsPlugin()],
  },

}
复制代码

webpack 的流程、webpack 的原理、手写 plugin 和 loader

看了多篇文章之后,确定是我学不起的内容……只找到一篇相对简单的文章。

干货!撸一个webpack插件(内含tapable详解+webpack流程)

更深入的以后再学习……

转载于:https://juejin.im/post/5c893cab518825766355d72a

webpack和gulp是两个常用的构建工具,用于优化和打包前端资源。它们在一些方面有着不同的特点。 Webpack是一个现代化的模块打包工具,它将所有文件都视为模块,并通过加载器(loader)来解析和转换这些文件webpack的主要目标是将多个模块打包成一个或多个文件,以便在浏览器中使用。它具有强大的模块化支持和灵活的配置选项,可以处理各种类型的文件,如JavaScript、CSS、图片等。同时,webpack内置了一些功能,如代码分割、懒加载等,使得开发者可以更好地优化和管理前端资源。 Gulp是一个基于任务的构建工具,它使用流(stream)来处理前端资源。gulp通过编写任务(task)来定义源文件处理过程,并将处理结果输出到指定目录。它可以进行文件的合并、压缩、重命名等操作,并且可以自定义任务的执行顺序。相对于webpack,gulp更加灵活,可以处理更多种类的任务,如自动化测试、文件的复制和移动等。但是,gulp相对于webpack来说,对于模块化的支持相对较弱,需要借助其他插件来实现。 综上所述,webpack和gulp在功能和使用方式上有所不同。webpack更适用于模块化的项目,可以更好地处理复杂的依赖关系和模块管理;而gulp更适合处理一些简单的任务和流程,具有更大的灵活性。在面试中,常常会涉及到webpack和gulp的使用和配置,以及它们之间的区别和优劣势。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [webpack-interview-questions:可用于准备面试或测试知识的Webpack问题答案](https://download.csdn.net/download/weixin_42121754/15101046)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [webpack 常见面试题](https://blog.csdn.net/write_bug_job/article/details/124355413)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [面试官常问 webpack 面试题](https://blog.csdn.net/weixin_59519449/article/details/123983352)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值