webpack知识点总结及webpack面试中必掌握知识点

为什么要使用webpack进行构建

  1. 开发分工的变化:对整个项目的分工变得越来越细
  2. 框架的变化:(主流三大框架:Vue,React,Angular)
  3. 语言的变化:HTML5,CSS3,JavaScript,TypeScripe,es6,es7,不同浏览器对不同语言的支持力度不同,构建成浏览器能够读取的语言
  4. 环境的变化:曾经前端只需在浏览器运行,现在可以在服务端(node),移动端react-native等运行
  5. 社区的变化:github社区,npm的发展,各种包可以下载。代码管理,库管理更完善,项目要对自己需要的库进行打包
  6. 工具的变化:构建工具的变化,有gulp,grunt,webpack,rollup.js

webpack基础认识

webpack可以项目管理,项目打包,模块管理(依赖管理),加载器(js,css,html,png,jpg,woff,vue等),转换器(loader)。是基于node.js开发出来的一个前端工具

webpack安装的两种方法

1.运行 npm install webpack -g 全局安装webpack,这样就能在全局使用webpack命令

2.在项目跟目录中运行npm i webpack安装到项目依赖中

使用webpack打包构建项目

  1. 建立项目webpack-study文件夹
  2. 创建项目基本的目录结构src和dist,在src中新建index.html,也可创建js,css,image文件夹,来分别存放想要的文件
  3. 引用包jQuery前,先初始化项目
npm init -y	//直接创建,不会出现选项
  1. 引用jQuery包
npm i jquery -S	//安装jQuery类库
  1. 不推荐直接在index.html中引用任何包和css文件。所以创建main.js主文件,在该文件导入index.html中需要的包
import $ from 'jquery' //该导入方法为ES module
//webpack模块化开发支持多种模块化
//包括
//AMD:require.js
//CMD:sea.js
//common.js:node.js
//es6:ES module

7.直接在文件中使用main.js文件会报错,因为浏览器不认识import这种高级JS语法,需要使用webpack进行处理,webpack默认会把这种高级的语法转化为低级的浏览器能够识别的语法;
8.webpack 入口软件路径 出口文件路径 对index.js进行处理

webpack ./src/main.js ./dist/bundle.js

9.webpack4允许我们指定编译使用开发模式还是生产模式,这由mode进行控制,value为枚举值:development/production,分别对应开发模式和生产模式(这个配置可以作为命令行的配置参数也可以作为配置文件中的一个配置项,默认值为production,即生产模式)

 1 | webpack ./src/main.js ./dist/bundle.js --mode development

使用webpack配置文件简化带包时候的命令

  1. 在项目跟目录中创建 webpack.config.js文件
  2. 由于运行webpack命令的时候,webpack需要指定入口文件和输出文件的路径,所以,我们需要在webpack.config.js中配置这两个路径:
//导入处理路径的模块,该模块node.js中自带
const path = require('path');

//导出一个配置对象,将来webpack在启动的时候
//会默认来查找webpack.config.js,读取这个
//文件中导出的配置对象,来进行打包处理

//使用了common.js模块化导出
module.export = {
	//配置打包模式为开发模式
	mode: 'development',
	//配置入口文件,最好是创建一个对象,这样可以设置导出文件名,
	//并且webpack会把对象里面的文件分别打包成一个js文件
	//如果是数组,webpack会把数组中的所有文件打包成一个js文件
	entry:{
		main:path.resolve(__dirname, 'src/main.js')//表示在根目录下的文件
	},
	output:{
		path:path.resolve(__dirname, 'dist'), //配置输出文件路径
		filename:'[name][hash].js' //[name]表示用原有的chunk名称,
		//[hash]利用md5命名,目的用于浏览器的缓存机制
	}
}

当我们在控制台中直接输入webpack命令执行的时候,webpack做了以下几步

1.webpack发现没有通过命令行的形式给出指定入口和出口文件
2.webpack就会去项目的根目录中直接查找一个名为webpack.config.js的配置文件
3.当查找到配置文件后,webpack会去解析执行这个配置文件,当解析执行完配置文件后,就得到了配置文件导出的配置对象
4.当webpack得到配置对象后,就拿到了配置对象中指定的入口和出口文件,然后进行打包构建

实现webpack的实时打包构建

  1. 每当修改完代码后,在命令行中都要输入webpack并回车命令,比较麻烦,所以使用webpack-dev-server来实现自动带包编译功能,当修改完代码后,会自动进行打包编译
  2. 运行npm install webpack-dev-server -D 安装到开发依赖中
  3. 安装完毕后,这个工具的用法和webpack命令的用法完全一样。
  4. 如果直接执行webpack-dev-server会报错,由于我们项目是在本地安装的,所以无法把它当做我们的脚本命令在命令行终端中直接运行(只有那些安装到全局-g 的工具,才能在终端运行)
  5. 所以,这个工具要正常运行,要求必须在本地项目中安装 npm install webpack -D
  6. 如果再执行webpack-dev-server还会报错,那么此时需要借助package.json文件中的指令,来运行webpack-dev-server命令,在scripts节点下新增"dev": "webpack-dev-server"指令,然后直接运行这个指令npm run dev 发现实时打包
  7. 如果在index.html中导入的js文件不是根路径,会出现错误
  8. webpack-dev-server帮我们打包生成的出口文件,并没有存放到实际的物理磁盘上,而是直接托管到了电脑的内存中,所以我们在项目根目录中根本找不到这个打包好的出口文件
  9. 所以,我们可以认为webpack-dev-server把打包好的文件以一种虚拟的形式托管到了咱们项目中的根目录中,虽然我们看不见它,但是我们可以认为在dist文件夹中
  10. 这样把出口文件放在内存的好处是:由于需要实时打包编译,所以放在内存中速度会很快
  11. 不想直接打开浏览器 ,所以修改package.jsonscripts中的配置
"dev": "webpack-dev-server --open"

12.修改了package.json文件,所以要重启服务器,npm run dev
13.修改端口

"dev": "webpack-dev-server --open --port 3000"

14.启动服务器后打开的http://localhost:3000/网站,发现会出现一个文件夹面板,需要点击到src目录下,才能打开index.html首页,所以,为了打开网站后直接打开index首页,可以配置为

"dev": "webpack-dev-server --open --port 3000 --contentBase src"

15.每次修改了文件后,在浏览器中还要刷新才能实时的把修改的内容添加到浏览器中,所以可以配置热更新来进行无刷新加载页面,热更新,不会重新生成新的出口文件,会把修改的内容以补丁的形式添加到出口文件中

"dev": "webpack-dev-server --open --port 3000 --contentBase src --hot"

在配置文件中配置端口,热更新等

devServer:{
	open:true, //自动打开浏览器
	port:3000, //设置启动时候运行的端口
	contentBase:"src", //指定托管的根目录
	hot:true //启动热更新
}

如果页面没有加载并报错
1.在头部引入webpack模块

const webpack = require("webpack")

2.在plugins节点下新增

plugins:[
	new webpack.HotModuleReplacementPlugin()
]

每次打包生成的HTML文件都要手动引用js文件,如何解决呢
1.安装

npm i html-webpack-plugin -D

2.配置webpack.config.js

const htmlWebpackPlugin = require("html-webpack-plugin")

3.在plugins中设置

plugins:[
	new webpack.HotModuleReplacementPlugin(),
	new htmlWebpackPlugin({
		template:'./src/index.html',//以当前目录下的index.html文件为模板生成dist/index.html文件
		filename:'index.html',//输出的文件名
	})
]

最后会发现打包好的index.html中多生成了一个

<srcipt type='text/javascripte' src='./bundle.js'></script>

直接插入页面自动追加

删除指定文件

使用创建clean-webpack-plugin,删除指定文件,更多配置,因为打包后会在dist中一直生成出口文件,出现重复文件,所以在重新打包时,删除上次打包的文件
1.安装

npm i clean-webpack-plugin -D

2.配置webpack.config.js

const cleanWebpackPlugin = require("clean-webpack-plugin")

3.在plugins中设置

plugins:[
	new webpack.HotModuleReplacementPlugin(),
	new htmlWebpackPlugin({
		template:'./src/index.html',//以当前目录下的index.html文件为模板生成dist/index.html文件
		filename:'index.html',//输出的文件名
	}),
	new cleanWebpackPlugin(['dist']),//错误配置,传入数组,指定要删除的目录
	new cleanWebpackPlugin(), //正确配置
]

4.执行npm run dev 可以看出dist目录被删除,又生成一个新的dist目录,之前的js文件被删除

配置CSS

  1. webpack 默认只能打包处理js类型的文件,无法处理其他非js的文件
  2. 要处理非js文件,想要安装一些合适第三方loader加载器
  3. loader是什么呢?它就是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,单纯的文件转换过程。也能够对文件进行一些处理,诸如编译、压缩、等,最终一起打包到指定的文件中

注意
处理一个文件可以使用多个loaderloader的执行顺序和配置中的顺序是相反的,即最后一个loader最先执行,第一个loader最后执行
第一个执行的loader接收源文件内容作为参数,其他loader接收前一个执行的loader的返回值作为参数,最后执行的loader会返回此模块的JavaScript源码

4.想要打包处理css文件,想要安装

npm i style-loadr css-loader -D

5.打开webpack.config.js这个配置文件,在里面新增一个配置节点,叫做module,它是一个对象,在这个对象上,有一个rules属性,该属性为数组,这个数组中存放了所有第三方文件的匹配和处理规则

module:{
	rules:[{
	text:/\.css$/,
	use:[{
		loader:style-loader
	},
	{
		loader:css-loader
	}
]
}]
}

6.webpack 处理第三方文件类型的过程

1.发现这个要处理的文件不是js文件,然后就去配置文件中,查找有没有对应的第三方loader规则
2.如果能找到对应的规则,就会调用对应的loader处理这种文件类型
3.在调用的时候,是从后往前调用
4.当最后一个loader调用完毕,会把处理的结果交给webpack打包合并,输出到打包文件中

webpack配置css单独分离打包

  1. 安装插件
npm install extract-text-webpack-plugin -D

2.webpack.config.js配置

const ExtractPlugin = require('extract-text-webpack-plugin')

3.正式环境中去掉style-loader,因为style-loader是将css-loader处理后的内容外面包了一层js代码,这个js代码就是把css写进html里,写成style标签。正式环境需要拆分出单独的css文件,所以不需要style-loader

module:{
	rules:[{
	text:/\.css$/,
	use:ExtractPlugin.extract[{
		fallback:'style-loader',
		use:[{
		loader:css-loader
	}]	
	},	
]
}]
}

4.添加一个插件

plugin:{
	new ExtractPlugin('style.[constentHash:8].css'),//打包后的文件名
}

处理其他如less.sass.scss文件类型时,与配置css文件类似

webpack配置高级js语法

  1. webpack中,默认只能处理一部分es6新语法,一些高级的es6语法或者es7语法webpack处理不了,这时候,就需要借助第三方loader,来帮助webpack处理这些高级的语法,当第三方loader把高级语法转为低级语法之后,会把结果交给webpack打包到bundle.js
  2. 安装loader转换器的相关loader包
npm install babel-core babel-loader babel-plugin-transform-runtime --save-dev

3.安装babel转化的语法

npm install babel-preset-env babel-preset-stage-0 --save-dev

4.打开webpack的配置文件,在module节点下的rules数组中,添加一个新的匹配规则

{
	test:/\.js$/,
	use:'babel-loader',
	exclude:/node_modules/
}

5.注意在配置babelloader规则的时候,必须把node_modules目录通过exclude选项排除掉,原因如下

如果不排除node_modules,则babel会把 node_modules中所有的第三方js文件,都打包编译,这样会非常消耗cpu,同时。打包速度非常慢
哪怕最终,babel把所有的node_modules中的js转换完毕了,但是项目也无法正常运行

6.在项目根目录中,新建一个 .babelrcbabel的配置文件,这个配置文件,属于json格式语法规范,不能写注释,字符串必须用双引号

{
	"presets":["env","stage-0"],
	"plugins":["transform-runtime"]
}

补充,Vue配置文件

  1. 默认webpack无法打包 .vue文件,需要安装相关的loader
npm install vue-loader vue-template-compiler -D

2.在配置文件中,新增loader配置项

{
	test:/\/vue$/,
	use:{
		loader:'vue-loader'
}
}

3.在webpack中,如果想要通过 Vue把一个组件放到页面中去,以实例中的 render函数可以实现
4.如果报错,说明在 webpack.config.js文件中没有配置好

const vueLoaderPlugin = require('vue-loader/lib/plugin')
plugin:{
	new vueLoaderPlugin()
}

webpack核心面试考点

概念问题一:什么是webpack和grunt和gulp有什么不同?

答案:webpack是一个模块打包器,他可以递归的打包项目中的所有模块,最终生成几个打包后的的文件,他和其他的工具最大的不同在于他支持code-splitting(代码分割)、模块化(AMD、ESM、Common.js)、全局分析

概念问题二:什么是bundle,什么是chunk,什么是module?

答案:bundle是由webpack打包出来的文件,chunk是指webpack在进行模块的依赖分析的时候,代码分割出来的代码块,module是开发中的单个模块

概念问题三:什么是loader?什么是plugin?

答案:loader是用来告诉webpack如何转化处理某一类型的文件,并且引入到打包出的文件中
plugin是用来自定义webpack打包过程的方式,一个插件是含有apply方法的对象,通过这个方法可以参与到整个webpack打包的各个流程(生命周期)

概念问题四:如何可以自动生成webpack配置?

答案:webpack-cli / vue-cli /etc 各种脚手架工具

开发问题五一:webpack-dev-server和http服务器如nginx有什么区别?

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

开发问题二:什么是模块热更新?

答案:模块热更新是webpack的一个功能,他可以使得代码修改过后不用刷新浏览器就可以更新,是高级版的自动刷新浏览器

优化问题一:什么是长缓存?在webpack中如何做到长缓存优化

答案:浏览器在用户访问页面的时候,为了加快加载速度,会对用户访问的静态资源进行存储,但是每一次代码升级或是更新,都需要浏览器去下载新的代码,最方便和简单的更新方式ius引入新的文件名称。在webpack中可以在output给输出的文件指定chunkhash,并且分离经常更新的代码和框架代码。通过NamedModulePlugin或是HasnedModuleIdsPlugin使再次打包文件名不变

优化问题二:什么是Tree-shaking?CSS可以Tree-shaking吗

答案:Tree-shaking是指在打包中去除那些引入了,但是在代码中没有被用到的那些死代码。在webpack中Tree-shaking是通过uglifyJsPlugin来Tree-shaking JS。CSS需要使用purify-CSS

你可能感兴趣的:(webpack)