前端面试 · webpack

875 阅读6分钟

前端实习面试遇到的Webpack常见问题(附答案),完整版请看前端小白的面试问题集

1.描述一下Webpack的过程

Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程 :

  • 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数。
  • 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译。
  • 确定入口:根据配置中的 entry 找出所有的入口文件。
  • 编译模块:从入口文件出发,调用所有配置的 Loader,对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理。
  • 完成模块编译:在经过Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系。
  • 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会。
  • 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
  • 在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。

2.loader和plugin的区别

  • Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。
  • Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

3.Webpack4.0的新特性

①环境及依赖库更新
由于Webpack的更新,很多Loader也必须更新才能适应Webpack的最新版本:

  • 对ES语法进行转换:babel-loader7.1.3
  • 代码检查:eslint-loader2.0.0
  • 批量修改文件路径、或者指定编译后文件存储路径:file-loader1.1.10
  • 解析、编译vue单文件组件:vue-loader15.0.0
  • 解析、编译vue单文件组件中的样式:vue-style-loader4.1.0

②Webpack 4.x 的破坏性变更

  • config新增optimization的选项来代替之前版本中的webpack.optimize等。在optimization选项中,我们可以进行详细的设置,以达到分离CSS,分离Chunk,压缩文件等等操作
  • 取消了其内置插件,所以之前的JS及CSS文件压缩方法失效。可使用UglifyJsPluginOptimizeCSSPlugin插件来代替之前的内置插件,当然如果你只是想简单的压缩,而不做任何配置的话,可以按照官方文档中给出的方法使用optimization.minimizer: true即可
  • 在之前版本中,我们使用CommonsChunkPlugin进行JS文件分离,而在Webpack 4.x中,我们则借助于config.optimization来实现
  • 在之前版本中我们使用extract-text-webpack-plugin来提取CSS文件,在webpack 4.x中则应该使用mini-css-extract-plugin来提取CSS到单独文件中
  • webpack4中提供的mode有两个值:development和production,默认值是 production。mode是我们为减小生产环境构建体积以及节约开发环境的构建时间提供的一种优化方案,提供对应的构建参数项的默认开启或关闭,降低配置成本 参考:Webpack4升级篇

4.Webpack的优缺点有哪些

优点:

  • 专注于处理模块化的项目,能做到开箱即用、一步到位。
  • 可通过Plugin扩展,完整好用又不失灵活。
  • 使用场景不局限于Web开发。
  • 社区庞大灵活,经常引入紧跟业界的新特性,能为大多数场景找到已有的开源扩展。
  • 良好的开发体验。

缺点:

  • 只能采用模块化,配置复杂。(充斥着大量名字类似 what-the-fuck-is-this-plugin 的插件,以及这个插件附带的一千种配置和一万种副作用)

5.webpack如何实现部分更新

参考:深入理解WebPack打包分块

通过代码分离的思想对代码进行分离。比如 DLL 技术:指的是 Windows 系统的下的动态链接库文件,它的本意是将公共函数库提取出来给大家公用以减少程序体积。我们借助这种思想,将公共代码分离出来。使用 DLL 简单来说分为两步:

  • 输出 DLL 文件
  • 引入 DLL 文件 不过美中不足的是,你仍然需要在你最终的页面里引入 dll 文件,如果你的觉得手动配置 dll 仍然觉得繁琐,那么可以尝试使用 AutoDllPlugin

6.如何将公共的代码提取出来?

使用optimiztion.splitChunks插件,具体方法如下:

假设我们有两个文件:index.js和mode.js,都引入了user.js,希望把这部分单独打包:

//index.js
import '../users.js';
console.log("i love you");

//mode.js
import '../users.js';
console.log("me too");

//user.js
这里大于30k即可

//webpack.config.js
const path = require('path');
module.exports={
    entry:{
        'index':'./src/js/index.js',
        'mode':'./src/js/mode.js'
    },
    output:{
        filename:'./[name]-main.js',
        path:path.resolve(__dirname,'dist'),
        publicPath:'dist/'
    },
//公共模块插件:
    optimization: {
        splitChunks: {
            cacheGroups: {
                commons: {
                    name: "commons",
                    chunks: "initial",
                    minChunks: 2
                }
            }
        }
    }   

6.webpack如何实现部分代码编译为ES5

1.首先需要安装工具 babel-cli ========= npm i babel-cli -g install 可以使用i 代替

2.安装插件 npm i --save-dev babel-preset-es2015

3.在文件夹中增加一个文件名称为.babelrc的文件 win下可能需要用户名。最好在编辑器中简历,会主动识别文件;

4.将写好的es6文件 例如 testes6.js通过命令编译 babel testes6.js -o results.js  

5.这样就可以将result.js 引入浏览器环境中使用了;

7.urlloader,fileloader

介绍:

webpack加载css背景图片、img元素指向的网络图片、使用es6的import引入的图片时,需要使用url-loader或者file-loaderurl-loaderfile-loader可以加载任何文件。

区别:

  • url-loader封装了file-loader,但url-loader并不依赖于file-loader。
  • url-loader可以将图片转为base64字符串,能更快的加载图片,一旦图片过大, 就需要使用file-loader的加载本地图片,故url-loader可以设置图片超过多少字节时,使用file-loader加载图片。