关于webpack的一些面试题(缓慢更新)

拟墨画扇 提交于 2019-12-10 16:28:15

1.webpack与Grunt、Gulp这类打包工具有什么不同

像Grunt、Gulp这类构建工具,打包的思路是: 遍历源文件 → 匹配规则 → 打包,这个过程中做不到按需加载,即对于打包起来的资源,到底页面用不用,打包过程中是不关心的。

webpack跟其他构建工具本质上的不同之处在于: webpack 是从入口文件开始,经过模块依赖加载、分析和打包三个流程完成项目的构建。在加加载、分析和打包的三个过程中,可以针对性的做一些解决方案,比如code split(拆分公共代码等)。

当然,webpack还可以轻松的解决传统构建工具解决的问题:

  • 模块化打包,一切皆模块,js是模块,css等也是模块
  • 语法糖转换:比如ES6转ES5、TypeScript
  • 预处理器编译:比如less、sass等
  • 项目优化:比如压缩、CDN
  • 解决方案封装:通过强大的Loader和插件机制,可以完成解决方案的封装,比如PWA;
  • 流程对接:比如测试流程、语法检测等。

2.wepback有几种写法

webpack的配置类型是多样的,最常见的是直接作为一个对象来使用,除了使用对象,webpack还支持函数 promise和多配置数组。

3.我们要开发一个jQuery插件、vue组件等,需要怎么配置webpack

如果我们打包的目的是生成一个共别人使用的库,那么可以使用output.library来指定库的名称库的名称支持占位符与普通字符串。使用output.library确定了库的名称之后,还可以使用output.libraryTarget指定库打包出来的规范。使用output.externals配置项去除输出的打包文件中依赖的某些第三方js模块(例如jquery,vue等)。这些被依赖的模块应该由使用者提供,而不应该包含再js库文件中。

4.webpack的占位符[hash],[chunkhash],[contenthash] 有什么区别和联系。

  • [hash]:是整个项目的hash值,其根据每次编译内容计算得到,每次编译之后都会生成新的hash,即修改任何文件都会导致所有文件的hash发生改变;在一个项目中虽然入口不同,但是hash是相同的;hash无法实现前端静态资源在浏览器上长缓存,这时候应该使用chunkhash

  • [chunkhash]:根据不同的入口文件(entry)进行依赖文件解析,构建对应的chunk,生成相应的hash;只要组成entry的模块文件没有变化,则对应hash也是不变的,所以一般项目优化时,会将公共代码库拆分到一起,因为公共代码库代码变动较少的,使用chunkhash可以发挥最长缓存的作用

  • [contenthash]:使用chunkhash存在一个问题,当在一个js文件引入css文件,编译后他们的hash是相同的。而且,只要js文件内容发生改变,与其关联的css文件hash也会改变,针对这种情况,可以把css从js中抽离出来并使用contenthash。

5.什么是bundle,chunk,module

  • module:开发中的每一个文件都可以看作是module,模块不局限于js,也包含css,图片等。
  • chunk:表示代码块,一个chunk可以由多个模块组成。
  • bundle:最终打包完成的文件,一般就是和chunk一一对应的关系,bundle就是对chunk进行编译压缩打包等处理后的产出。

6.能不能手写一个Webpack配置?

// 手写一个webpack配置最主要的就是 entry, output,module.rules(loader)和plugin

module.exports = {
	entry: './src/index.js',
	output: {
		filename: '[name].js',
		path: path.resolve(__dirname, 'dist')
	},
	module: {
		rules: [
			{
				test: /\.css$/,
				use: ['style-loader', 'css-loader']
			}
		]
	},
	plugins: [
		new ExtractTextPlugin({
			filename: 'style.css'
		})
	]
}

7.在js中怎么调用Loader来处理一个模块?

const html = require('html-loader!./test.html');
console.log(html)

8.Loader的解析顺序是怎样的?

从右向左或者从下至上。

9.什么是JavaScript模块化开发,有哪些可遵循的规范

模块是指为了完成某种功能所需的程序或者子程序,模块是系统中职责单一且可替换的部分。模块化开发是指如何开发新的模块和复用已用的模块来实现应用的功能。JavaScript可遵循的主流规范有:commonJS,AMD和ES6 module。

10.webpack中怎么获取一个模块引用另外一个模块时传入的query

// main.js
const component = require('./component-loader?commponent=demo')

// component-loader.js
const querystring = require('querystring')
const query = querystring.parse(__resourceQuery.slice(1)) // 去掉 ? 
consolelog(query);  // {comonent: demo}

11.怎么实现webpack的按需加载?什么是神奇注释?

在webpack中,import不仅仅是ES6 module的模块导入方式,还是一个类似require的函数,我们可以通过import('module')的方式引入一个模块,import()返回的是一个Promise对象;使用import()方式就可以实现webpack的按需加载。在import()里可以添加一些注释,如定义该chunk的名称,要过滤的文件,指定引入的文件等等,这类带有特殊功能的注释被称为神器注释。

12.Babel的preset-env是什么

babel的语法转换是通过强大的插件系统来支持的。babel的插件分为两类:转换插件和语法解析插件。

不同的语法对应着不同的转换插件,比如我们要将箭头函数转换成为es5的函数写法,那么可以单独安装@babel/plugin-transform-arrow-functrions插件,如果不想一个个的添加插件,那么可以使用插件组合preset(插件预设,插件组合更加好理解一些),最常见的preset是@babel/preset-env。

13.懂得babel的原理妈?你会手写babel插件吗?

babel是一个JavaScript的静态解析分析编译器,所谓静态分析指的的在不需要执行代码的前提下对代码进行分析和处理的过程。要实现babel从一个语法转换成另外一种语法,需要经过三个主要步骤:解析,转换,生成。

  • 解析:指的的首先将代码经过词法解析和语法解析,最终生成一棵AST(抽象语法树),在babel中,语法解析器是Babylon;

  • 转换:得到AST之后,可以对其进行遍历,在此过程中对节点进行添加,更新和移除等操作,babel中AST遍历工具是@babel/traverse;

  • 生成:经过一系列转换之后得到的一棵新树,要将树转换成代码,就是生成的过程,babel用到的是@babel/generator。

在babel中,代码会由babel先进行解析AST,babel插件做的事情就是写vistor而已,所以babel插件固定的模板如下:

module.exports = () => { return { name: 'example-plugin', visitor: { Identifier(path, state) {

		}
	}
}

}

14.babel怎么做polyfill,polyfill的最佳实践是什么?

babel只负责进行语法转换,即将es6语法转换成es5语法,但如果是在es5中,有些对象,方法实际在浏览器中可能是不支持的,例如:promise,array.prototype.includes,这时候就需要@babel/polyfill来做模拟。

@babel/polyfill虽然可以解决模拟浏览器不存在对象方法的事情,但是有以下两个问题:

  • 直接修改内置的原型,造成全局污染;
  • 无法按需引入,webpack打包时,会把所有的polyfill都加载进来,导致产出文件过大。

为了解决这个问题,babel社区又提出了@babel/runtime的方案,@babel/runtime不再修改原型,而是采用替换的方式,比如我们用promise,使用@babel/polyfill会产生一个window.promise对象,而@babel/runtime则会生成一个_Promise(示例而已)来替换掉我们代码中用到的Promise.另外@babel/runtime还支持按需引入。

babel怎么针对不同的浏览器打包不同的适配代码

browserslist就是帮助我们来设置目标浏览器的工具。它实际上就是声明了一段浏览器的集合,我们的工具可以根据这段集合描述,针对性的输出兼容性代码。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!