Webpack面试题整理

文章目录

  • 基本概念与配置
  • 性能优化

基本概念与配置

  1. 什么是loader?什么是plugin

    • loader是模块转换器,使wenbpack拥有加载和解析非js文件的能力,是在module.rules中进行配置
    • plugin可以扩展webpack的功能,使得webpack更加灵活。可以在构建的过程中通过webpackapi改变输出的结果,在plugins中进行配置
  2. module, chunk, bundle

    • module是开发中的单个模块,我们直接写出来的是 module
    • chunk是指webpack在进行模块的依赖分析的时候,代码分割出来的代码块,是由多模块合并而成的,如entryimport()splitChunk
    • bundle是由webpack打包出来的文件,最后生成浏览器可以直接运行的 bundle
  3. 常见的loader与plugins

    • babel-loader:可以将ES6代码转化为ES5代码
    • vue-loader:解析vue代码
    • css-loader:加载css,支持模块化,压缩,文件导入
    • style-loader:将css代码注入到js中,通过dom加载css
    • file-loader:文件的解析,在代码中通过相对url引入文件
    • url-loader:与file-loader类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去

    • HtmlWebpackPlugin:简化了HTML文件的创建;使用模板,通过webpack生成html文件,并为html文件引入外部资源
    • CleanWebpackPlugin:在进行打包之前清空原来文件的打包内容
    • MiniCssExtractPlugin:抽离压缩css文件
    • webpack.HotModuleReplacementPlugin:热更新插件
    • ParalleUglifyPlugin :多进程打包js文件
  4. webpack 构建流程

    • 初始化参数,将配置文件和shell语句中的参数进行合并,得到最后的参数
    • 开始编译:用得到的参数初始化Compiler对象,加载所有配置的插件,执行对象的run方法开始编译
    • 确定入口:根据entry找到所有入口文件
    • 编译模块:从入口文件出发,调用所有的loader对模块进行编译,且对模块所依赖的模块进行编译
    • 完成模块编译:得到每个模块编译后的内容和依赖关系
    • 输出资源:根据模块之间的依赖关系,组装成一个个包含多个模块的chunk,再把每个chunk转换成一个单独的文件(这里是修改输出的最后机会)
    • 输出完成:确定输出的路径和文件名,把内容写到文件系统中
  5. 模块热更新

    • 自动刷新: 整个网页全部刷新,速度较慢,且会丢失状态
    • 热更新使得新代码生效,网页不刷新,状态不丢失
    • 只在开发环境下使用,不要在生产环境中使用
    • 通过配置new webpack.HotModuleReplacementPlugin()实现热更新
  6. 懒加载

    • 使用import语法实现懒加载,对比vue,react中路由及组件懒加载
  7. 多页面打包配置

    • 修改enter入口:将entry修改为多个入口
    • 修改output的输出:filename: '[name].[contentHash:8].js'
    • 创建HtmlWebpackPlugin, 也可以通过js来进行动态push到plugins
    • 也可以使用webpack的AutoWebPlugin来完成自动化构建
  8. 公共代码提取

    • 使用optimization.splitChunk进行公共代码提取
    splitChunks: {
        // 分割代码块(多页应用才会用到)
        cacheGroups: {
          //缓存组
          common: {
            // 公共的模块
            chunks: "initial", // 从开始处抽离,有多种配置,像异步模块什么的
            minSize: 0, // 最小大小
            minChunks: 2 //  引用次数
          },
          vendor: {  // 此处为了抽离第三方的公共模块,比如jquery(前提是index和other都引入jquery了)
            priority: 1,  //权重, 如果不给这个字段,那么就此例来说,会先走上边的“common”,会把jquery和a.js,b.js合并在一个文件中。
                          //如果还有别的入口只使用jquery了,但是a和b对于它来说就是无用的。加上权重之后,会将第三方模块单独抽离
            test: /node_modules/,
            minSize: 0, // 最小大小
            chunks: "initial",
            minChunks: 2 //  引用次数
          }
        }
      }
    
  9. DllPlugin动态链接库插件

    • 使用场景:有依赖包较大时,因依赖包不常改动(一般基本不会去改),如:react,axios,antd等,如果不将其分离打包,则每次打包时均会被打包,影响打包速度
    • DllPlugin——打包出dll文件
    • DllReferencePlugin——使用dll文件

    • 配置webpack.dll.js,将第三方模块单独进行打包,生成一个dll的打包结果,所有第三方模块都在这里
    • 通过library将第三方模块通过全局变量的方式暴露出去
    • 借助dllPlugin对暴露的模块进行代码分析生成mainfest.json文件,当发现引入lodash或者jquery就会从打包好的库的拿去,如果没有才从node_modules中取模块进行打包
    • AddAssetWebpackPlugin是将打包生成的库文件引入到html文件中,并导出全局变量vendor
    new AddAssetWebpackPlugin({  // 将path.resolve(__dirname, '../dll/render.dll.js')静态资源文件引入html中
      filepath: path.resolve(__dirname, '../dll/render.dll.js')
    }),
    new webpack.DllReferencePlugin({  // 当发现引入lodash或者jquery就会从打包好的库的拿去,如果没有才从node_modules中取模块进行打包
      mainfest: this.resolve(__dirname, '../dll/vendors.mainfest.json')
    })
    
    // webpack.dll.js
    let path = require('path');
    let webpack = require('webpack');
    module.exports = {
      entry: {
        vendors: ['lodash', 'jquery']
      },
      output: {
        filename: '[name].dll.js', 
        path: path.resolve(__dirname, '../dll'),
        library: '[name]'
      },
      plugins: [
        new webpack.DllPlugin({ // 生成打包分析文件
          name: '[name]',
          path: path.resolve(__dirname, '../dll/[name].mainfest.json')
        })
      ]
    }
    
  10. 抽离压缩css代码

    • MiniCssExtractPlugin对css文件进行代码分割,
    • OptimizeCSSAssetsPlugin对css代码进行压缩
    {
    	test:/\.less$/,
    	loader: [
    		MiniCssExtractPlugin.loader,  // 为css提取独立的文件的插件,不使用style-loader
    		'css-loader',
    		'less-loader'
    	]
    }
    
    plugins: [
    	// 如果css文件被页面直接引用那么会走filename,如果被页面间接引用,会走chunkFilename
      new MiniCssExtractPlugin({
        filename: '[name].[contentHash:8].css',
        chunkFilename: '[id].css',
      })
    ]
    
    // 对css代码进行压缩
    optimization: {
      minimizer: [new OptimizeCSSAssetsPlugin({})],
    }
    
  11. webpack-dev-server和http服务器如nginx有什么区别?

    • webpack-dev-server使用内存来存储webpack开发环境下的打包文件,并且可以使用模块热更新,他比传统的http服务对开发更加简单高效。

性能优化

  1. 优化产出代码

    • 小图片进行base64编码
    • bundlehash
    • 懒加载
    • 提取公共代码
    • 使用cdn加速(可以将静态文件之类的放于cdn)
    • IgnorePlugin
    • 使用production(该模式下,会进行代码压缩,tree-shaking [将没用的代码删除], scope-hosting [作用域提升])
  2. webpack优化构建速度(生产环境)

    • 优化babel-loader(加缓存,加hash)
    • noParse(不去解析属性值代表的库的依赖)
    • IgnorePlugin(忽略本地化内容,如引入了一个插件,只用到了中文语言包,打包的时候把非中文语言包排除掉)
    • happyPack(多进程进行打包)
    • parallelUglifyPlugin(多进程打包js,压缩,优化js)
  3. webpack优化构建速度(开发环境)

    • 自动刷新,热更新
    • DllPlugin
  4. 为何要进行打包和构建

    • 体积更小(tree-shaking , 压缩,合并), 加载更快
    • 编译高级语言和语法
    • 兼容性和错误检查(postcsseslint

你可能感兴趣的:(面试)