前端工程化面试题

简介: 前端工程化面试题

1.什么是 bundle, 什么是 chunk,什么是module?

module

module是我们经常所说的模块,不管是esModule(import/export或export default)、CommonJs(require/module.exports)、AMD(依赖前置require([‘Ma’,‘Mb’],(a,b)=>_/define({key:value}))都属于module


chunks

chunks是webpack依据module间的引用关系通过代码分割生成的不同chunk文件,同时wenpack也可对chunk文件做些一些操作(如加chunkname)


bundle

bundle是webpack最终经过编译输出output的文件集合,他可以包含多个经过加载和编译后的chunk文件,由于bundle是经过加载和编译的最终源文件,所以直接可以在浏览器运行


2.hash chunkhash contenthash三者区别

webpack实现热更新后,每次更新都会将我们的业务代码和第三方库的代码同时打包更新,降低构建效率,所以需要使用webpack的optimization.splitChunks分离第三方库和业务代码,公共模块直接缓存就不要每次更新都消耗资源


hash 是跟整个项目构建有关,只要项目的文件内容发生变化,整个项目构建的hash值都会更改,并且全部文件都共用相同的hash值,所以一旦修改任何一个文件,整个项目的文件缓存都将失效


chunkhash 为避免整个项目的文件因为hash不断变化而导致缓存失效,需要chunkhash,chunkhash根据模块之间引入关系生成不同的chunk文件的同时生成对应的hash值,而不再是所有文件共用同一个hash值 如果需要对chunkhash做进一步优化就需要使用上述所说的optimization.splitChunks或者dllPlugin,可以将公共库以及业务代码抽离而直接缓存公共库,只要公共库只要不发生版本迭代,那么公共库的chunkhash就一直不会变。


contenthash contenthash又是在chunkhash的进一步优化,webpack在根据模块引入关系生成对应的chunk文件,模块可能引入index.css以及index.js,那么当index.js变化而index.css没有变化,则项目更新时inedx.css也会被迫重新加载,导致资源损耗 + 优化方法: 我们可以使用extract-text-webpackplugin(webpack4)里的contenthash值,保证引入css文件所在的模块只要css文件内容不变,就不会重复构建css + 配置方法

var extractTextPlugin = require('extract-text-webpack-plugin') plugins:[ new extractTextPlugin('../css/bundle.[name].[contenthash].css') ]


补充:webpack5已经使用mini-css-extract-plugin代替extractTextPlugin


3.什么是脚手架吗?

脚手架的概念和作用:就是拥有完整的开发环境,帮助我们快速的生成一套既定的项目架构、文件、配置。

使用者只需要专注自己的业务代码即可,不需要使用者单独配置

脚手架的构成:

常见的脚手架的开发环境主要分为三种模式:生产模式,开发模式,测试模式。

以及需要配置完整的路由系统(vue-router,react-router-dom),和状态管理系统(vuex,redux)才能保证开发环境的完整性

常见的脚手架:Vue-cli,Creat-React-app,umi-app


4.webpack的核心思想是什么

万物皆模块:在webpacck的世界中,其他任何资源都可以当做模块的方式引入 代码分割:webapp 的优化关键在于代码体积,当应用体积增大,实现代码的按需加载是刚需,这也是 webpack 出现的根本原因

可定制化:任何一个工具都不可能解决所有问题,提供解决方案才是最可行的,webpack基于可定制化的理念构建,通过插件系统,配置文件,可实现大型项目的定制需求


5. Loader和Plugin的区别

loader是一个转换器

  • 用于对模块源码文件的预编译和转换,,loader描述了webpack如何处理非javascript模块。
  • 没有loader,构建的打包过程无法顺利完成
  • loader作用在打包前
  • 将A文件转换为B文件,操作的是文件,比如将A.scss转换为A.css,是单纯的文件转换过程


Plugin是插件扩展器


  • plugin构建过程更完整的补充和优化,如使用new UglifyJsPlugin(),new CssMinimizerPlugin()压缩js和css
  • 没有plugin,文件的打包过程可以完成
  • plugin作用于整个打包过程,
  • 针对webpack的打包过程,他不直接操作文件,而是基于事件机制工作,会监听webpack打包过程的事件钩子,执行任务,通过事件钩子拦截webpack的执行


6.有哪些常见的Loader和Plugin,他们各自的作用

用Loader


  • babel-loader使得webpack可以通过babel转译js代码
  • css-loader转译css文件,会对@import和url()进行处理,就像js解析import/require一样,
  • style-loadder把css-loader转译后的结果插入输出的脚本中显示样式效果
  • sass-loader/less-loader都是用来预编译和转换.sass/.less文件
  • file-loader将一个文件中的加载文件、图片import/require()解析为url,并且将文件发送到输出文件夹,并返回文件的publicURL,
  • url-loader是file-loader功能的扩展和封装,options选项中可以设置对引用图片大小的限制,如果大于等于限制,默认使用file-loader并传递所有参数,如果小于,则默认使用base64编码并返回输出,
// 示例
    use: [
        {
          loader: 'url-loader',//等价写法use:'url-loader'?limit=1024
          options: {
            limit: 8192,
          }
        },
    ]


常用Plugin


  • DllPlugin:作用和optimization.splitChunk的作用相似,都是用某种方法拆分bundles,可以大幅度提升构建速度
  • SplitChunksPlugin:分离公共的第三方模块以及业务代码
  • extract-text-webpackplugin: extract-text-webpackplugin(webpack4)里的contenthash值,保证引入css文件所在的模块只要css文件内容不变,就不会重复构建css
  • MiniCssExtractPlugin:抽离css文件,删除和压缩css代码,本插件是extract-text-webpackplugin插件的webpack5的升级用法,可以实现contenthash
  • HtmlWebpackPlugin:


1、为html文件动态引入外部资源给script、link添加compile(编译)后的hash,防止引用缓文件问题

2、可以生成创建html入口文件,比如单页面可以生成一个html文件入口,多页面生成多个html


  • UglifyjsWebpackPlugin:删除和压缩js文件
  • EslintWebpackPlugin:作用类似eslint-loader(eslint-loader已被弃用),审查代码是否符合编码规范和统一,审查代码是否存在语法错误


7.Webpack 的热更新原理

首先热更新所更新的内容是基于hash值发生改变的文件

更新的原理方法是webpack-dev-server启动本地服务,源码在webpack-dev-server的package.json中的bin命令,可以找到命令的入口文件bin/webpack-dev-server.js


一、webpack启动后,完成webpack所有编译工作,以及监听本地文件变化

二、使用express框架启动本地服务让浏览器可以请求本地的静态资源。

三、本地服务启动后,再启动websocket服务,通过websocket,可以建立本地服务和浏览器的双向通信,这样就可以实现本地文件变化,立马告知浏览器可以更新了


// node_modules/webpack-dev-server/bin/webpack-dev-server.js
// 生成webpack编译主引擎 compiler
let compiler = webpack(config);
// 启动本地服务
let server = new Server(compiler, options, log);
server.listen(options.port, options.host, (err) => {
    if (err) {throw err};
});
// node_modules/webpack-dev-server/lib/Server.js
class Server {
    constructor() {
        this.setupApp();
        this.createServer();
    }
    setupApp() {
        // 依赖了express
        this.app = new express();
    }
    createServer() {
        this.listeningApp = http.createServer(this.app);
    }
    listen(port, hostname, fn) {
        return this.listeningApp.listen(port, hostname, (err) => {
            // 启动express服务后,启动websocket服务
            this.createSocketServer();
        }
    }                                   
}


8.如何优化 Webpack 的构建速度

不要让loader做太多事情,以babel-loader为例

最常见的优化方式是,用include或exclude来帮助我们避免不必要的转译,除此之外,如果我们开启缓存转译结果缓存至文件系统,则至少可以提升两倍工作效率


use:{
  exclude:/(node_module|bower_components)/,
  loader:'babel-loader?cacheDirectory=true'
}


不要放过第三方库,以node_modules为代表,庞大又不可或缺。推荐使用DllPlugin

将loader由单进程转为多进程构建


Happypack–将loader由单进程转为多进程,进程是程序运行的数据集合,是系统资源分配基本单位,一般情况下单核cpu只有一个单进程,多核cpu在node的cpu利用率不足的情况下才会由单进程转为多进程。而Happypack帮我们做了这个事儿。多核并发,最大限度使用多核cpu的作用。大大提升效


可视化工具的使用,找出导致文件体积过大的原因


推荐使用webpack-bundule-analyzer,配置方法和普通的 plugin 无异,它会以矩形树图的形式将包内各个模块的大小和依赖关系呈现出来


9.代码分割的本质是什么?有什么意义呢?

代码分割的本质: 是能够把代码分离到不同的bundle中,避免出现大体积的代码包,然后可以按需加载或并行加载这些文件 + 代码分离的意义: 代码分离可以获取更小的bundle,以及控制资源加载优先级,合理使用可以极大的减少加载时间 + 代码分割的实现方式有三种: 入口起点:使用entry手动分离代码(不建议) 防止重复加载:使用optimization.splitChunks配置选项,可以将第三方公共模块和业务代码直接分离 动态引入:使用import()方法来分离代码,原理是当 Webpack 解析到该语法时,会自动进行代码分割,分割出不同的chunks > 语法:使用的时候再去下载对应的文件,返回一个Promise,当Promise成功后再去执行回调,(动态引入的另一种方式是require.ensure()) import("./math").then(math => { console.log(math.add(16, 26)); });

//所有可能匹配此模式的文件都会自动进行代码拆分。 const loadFile = file => import (` ./ $ { file } ` ) import动态语法实现异步加载的代码演示, js function getComponent(){ return import(./loadash).then(_=>{ const element = document.createElement('div'); element.innerHTML = _.join(['Hello', 'webpack'], ' '); return element; }) } getComponent().then(component=>{ document.body.appendChild(component); })

10.tree-shaking 的原理

作用:tree-shaking可以实现删除项目中未被引用的代码 原理:


//test.js
export const a =1;
export const b = 2;    
// main.js
import {a} from './test.js'


对于以上情况,test文件中的变量b如果没有在项目中使用的话,就不会被打包到文件中 使用: 在webpack4中,开启生产环境就会自动开启这个优化功能,也可以手动的引入ModuleConcatenationPlugin的支持



11. linux部署和windows sever服务器区别?

  • 性价比:Linux服务器性价比更高,Linux作为资源管理器和操作系统来说,是开源的,免费的,而正版windows的操作系统是收费的。
  • 性能方面:相同配置的Linux服务器的性能比windows服务器好一些,Linux服务器占用的资源少一点
  • 稳定性方面:Window系统用户量大,因而攻击者多一些,所以暴露了更多的系统安全漏洞。Linux是多用户多进程系统,意味着Linux能够一次性处理大量正在进行的进程,比windows处理的多
  • 安全性方面:Linux系统开源软件的开发方式有助于暴露错误,集众人智慧解决问题,补丁更新更快。这是windows不具备的,Windows的另一个不利因素是其许多应用程序依靠远程过程调用,这就迫使Windows的防火墙没有Linux那样严格。而Linux远程过程调用是限制使用的。


12. 什么是组件?什么是模块化?有什么区别?

组件化

就是基础库或者基础组件,意思是把代码重复的部分提炼出一个个组件供给功能使用


模块化

就是业务框架或者业务模块,也可以理解为框架,意思是把功能进行划分,将同一类型的代码整合在一起,所以模块的功能相对复杂,都属于同一个业务。


区别

使用:组件的使用能在不同项目(模块)重复应用的代码,而模块按照项目功能需求划分成不同类型的业务框架 目的:组件是复用,解耦,模块是为了隔离、封装 依赖:组件之间低依赖,比较独立,模块之间的依赖可通过路由进行耦合 架构定位:组件位于架构底层,被其它层所依赖,模块位于架构业务层


13.什么是长缓存,在webpack中如何做到长缓存优化?

  • 浏览器在用户访问页面的时候,都会对静态资源进行存储,但是每次代码更新或者升级的时候,我们都需要浏览器去重新加载代码,最方便的方法就是以文件名的方式引入,只下载新的代码块,不加载旧的没有变化的代码块,这就是长缓存,
  • 在webpack4中使用SplitChunkPlugin把第三方库和业务代码分离,由于第三方库的chunkHash未改变,所以只会对改变的业务代码的模块进行更新。而第三方库的代码块因为长缓存而不更新。
相关文章
|
2月前
|
缓存 前端开发 中间件
[go 面试] 前端请求到后端API的中间件流程解析
[go 面试] 前端请求到后端API的中间件流程解析
|
5天前
|
Web App开发 前端开发 Linux
「offer来了」浅谈前端面试中开发环境常考知识点
该文章归纳了前端开发环境中常见的面试知识点,特别是围绕Git的使用进行了详细介绍,包括Git的基本概念、常用命令以及在团队协作中的最佳实践,同时还涉及了Chrome调试工具和Linux命令行的基础操作。
「offer来了」浅谈前端面试中开发环境常考知识点
|
2月前
|
存储 XML 移动开发
前端大厂面试真题
前端大厂面试真题
|
2月前
|
存储 前端开发 JavaScript
44 个 React 前端面试问题
【8月更文挑战第18天】
37 2
|
2月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
28 0
|
2月前
|
存储 前端开发 JavaScript
44 个 React 前端面试问题
44 个 React 前端面试问题
|
2月前
|
存储 JavaScript 前端开发
|
2月前
|
Web App开发 存储 缓存
|
2月前
|
前端开发 容器
前端面试热门问题--浮动和清除浮动(CSS)
前端面试热门问题--浮动和清除浮动(CSS)
|
3月前
|
JSON 前端开发 JavaScript
前端工程化:Webpack配置全攻略
【7月更文挑战第14天】
52 6
下一篇
无影云桌面