Webpack 入门
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。
从图中我们可以看出,Webpack 可以将多种静态资源 js、css、less 转换成一个静态文件,减少了页面的请求。
接下来开始webpack的之从入门到放弃 之旅。。。
正式使用Webpack前的准备
1、创建项目文件目录结构
Webpack可以使用npm安装,先新建一个空的练习文件夹(此处命名为webpack-study)并新建如下图目录文件夹:
2、创建package.json文件
在上述练习文件夹中创建一个package.json文件,这是一个标准的npm说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等等。
在终端中使用npm init
命令可以自动创建这个package.json文件。
我是用的编程工具是vsCode,使用快捷键ctrl + ~ 打开终端,在当前项目路径下输入 npm init -y
npm init -y 【(-y 代表yes ,省去了默认选项点击)】
可以看见项目目录下自动生成了package.json文件
3、创建index.html页面
现在开始在index.html文件中写入最基础的html代码,实现一个ul-li 列表隔行变色的功能。
使用vdcode 在body 中写入 ul>li*10{这是第$个li} ,会自动补全以下代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <ul> <li>这是第1个li</li> <li>这是第2个li</li> <li>这是第3个li</li> <li>这是第4个li</li> <li>这是第5个li</li> <li>这是第6个li</li> <li>这是第7个li</li> <li>这是第8个li</li> <li>这是第9个li</li> <li>这是第10个li</li> </ul> </body> </html>
4、引入jquery来实现隔行变色功能
这里我们用jquery来完成这个功能,打开vscode终端安装jquery包。
npm i jquery -s
jquery包已安装成功后, 按照平时一般的开发步骤,此时我们应该在index.html中引入jquery包供当前页面使用,但是在webpack中是不推荐在html页面中直接引用安装的包和任何css文件。
我们直接在main.js中引用jquery.
main.js 中代码如下:
//这里是main.js 项目的js入口文件
//1、导入jquery
//import ** from ** 是es6中导入模块的方式
import $ from 'jquery'
//使用jquery选择器分别渲染奇数行和偶数行的颜色
$(function(){
$('li:odd').css('backgroundColor','lightblue')
$('li:even').css('backgroundColor',function(){
return '#' + 'D97634'
})
})
然后在index.html 中引入main.js
<script src = "./main.js"></script>
现在在浏览器中 打开index.html 页面,查看结果
发现隔行变色效果没有实现,报错语法错误,import语法不能被识别。这是由于es6的写法比较高级,当前浏览器还不能够识别,解析不了。
5、正式使用Webpack
此时可以用webpack来进行处理,全局安装webpack 和 webpack-cli。(webpack4.x版本以后,需要分别安装webpack 和 webpack-cli,之前版本只需要安装webpack即可)
npm install webpack webpack-cli -g
可以看见安装成功的版本为webpack@4.44.1 ;webpack-cli@3.3.12
安装成功后,使用webpack来对main.js进行处理
webpack .srcmain.js -o .distundle.js
可以看见webpack帮我们生成的 bundle.js已经成功。
然后在index.html中引入bundle.js。
<!-- <script src = "./main.js"></script> --> <script src="../dist/bundle.js"></script>
此时在浏览器中打开index.html。发现隔行变色功能已经成功了。
经过刚才的演示,总结webpack可以为我们做什么?
1、webpack能够处理js文件间的相互依赖关系。(整个页面只需要引入一个js就完事了)
2、webpack能够处理js的兼容问题,把高级的、浏览器不识别的语法 转为低级的 浏览器能够识别的语法
(语法格式为:webpack ‘需要打包的文件路径’ -o ‘输出打包文件的路径’ )
6、webpack最基本的配置文件的使用
现在有一个问题:我们每改变一次main.js文件,就要重新运行一次 webpack .srcmain.js -o .distundle.js 命令。通过配置文件将命令简化为webpack。
修改mian.js中 li:odd 偶数行的颜色 为 :yellow
在webpack-study 根目录下,创建一个webpack.config.js文件,输入以下内容
1 const path = require('path') 2 3 //这个配置文件其实就是一个js文件,通过node中模块化操作,向外暴露一个配置对象 4 module.exports = { 5 //入口,表示要使用webpack打包的文件 6 entry:path.join(__dirname,'./src/main.js'), 7 output:{ 8 //指定打包好的文件输出的目录 9 path:path.join(__dirname,'./dist'), 10 //这是指定输出文件的名称 11 filename:'bundle.js' 12 } 13 }
现在在终端运行webpack命令,这样在dist文件下就生成了一个新的bundle.js文件
刷新index.html页面,可以看到修改后的效果:
总结:当在控制台输入 webpack 命令执行编译的时候,weboack做了以下几步:
7 、webpack-dev-server的基本使用
现在有一个问题是:我们每改变一次main.js文件,就要重新运行一次webpack命令,想要一个自动编译刷新页面的功能
使用webpack-dev-server这个工具,来实现自动打包编译的功能
![](https://img2020.cnblogs.com/blog/1044627/202009/1044627-20200902222424035-1359832891.png)
![](https://img2020.cnblogs.com/blog/1044627/202009/1044627-20200902223411778-76416792.png)
![](https://img2020.cnblogs.com/blog/1044627/202009/1044627-20200902224052716-1691206808.png)
红框中说明项目本地运行地址,在浏览器中输入 http://localhost:8080/ 就可以打开项目
绿框中说明webpack打包输出的文件在该项目根路径下,下面绿字说明打包生成的文件为bundle.js
所以:在index.html中要将<script src="../dist/bundle.js"></script>换成<script src="/bundle.js"></script>
这个bundle.js文件是托管在项目的根路径下,所以我们看不见这个文件,但是这个文件存在,可以在浏览器中输入地址http://localhost:8080/bundle.js打开文件。
运行完npm run dev以后,我们改动main.js文件中的内容,保存以后,项目就会自动运行,重新打包生成新的bundle.js文件替换原来的
但是,运行npm run dev以后,需要我们手动点击http://localhost:8080/ 才可以打开项目。
8、webpack-dev-server的常用命令参数
在package.json文件中配置(更改以下配置文件后,使用ctrl + c 终止终端服务,npm run dev 重启服务器):
"dev": "webpack-dev-server --open" 运行npm run dev 会自动打开浏览器
"dev": "webpack-dev-server --open --port 3000" 运行npm run dev 会自动打开浏览器,此时的端口号为3000
"dev": "webpack-dev-server --open --port 3000 --contentBase src" --contentBase src指定运行的根路径,这样打开http://localhost:3000/就直接是我们的项目主页面了,因为src文件夹下有index.html
"dev": "webpack-dev-server --open --contentBase src --hot" --hot 添加这个命令以后,更新main.js中的代码,自动运行不会重新生成bundle.js文件替换之前的bundle.js文件,而是以补丁的形式更新,如下图
9、webpack-dev-server配置命令的第2种方式(了解即可)
: "webpack-dev-server" 除了可以在package.json文件中配置,还可以在webpack.config.js中配置
10、html-webpack-plugin插件的两个基本作用
index.html是物理磁盘上的HTML页面,但bundle.js是托管到内存中的文件,那么,如何把HTML页面也导入到内存中呢?
(1)安装插件 npm i html-webpack-plugin -D
(2)在webpack.config.js中配置
当使用了这个插件以后,我们就不需要手动处理bundle.js的引用路径了,因为这个插件,已经自动帮我们创建了一个合适的script,并引用了正确的bundle.js的路径。因此就可以把物理磁盘中的index.html中<script src="/bundle.js"></script>注释掉了。
运行npm run dev,打开页面以后,可以查看页面源代码,我们就会发现:
内存中的index.html比我们磁盘中的index.html,在body底部多了一行<script type="text/javascript" src="bundle.js"></script>
html-webpack-plugin插件的两个基本作用是:
(1)自动在内存中根据指定页面生成一个内存中的页面
(2)自动把打包好的bundle.js追加到页面中去
11、loader-配置处理css样式表的第三方loader
在css文件夹下,建一个index.css文件,以前我们是在index.html中直接用link引入CSS文件,但是这样会发起二次请求,所以不建议这样做。
在mian.js中,使用import导入index.css
webpack默认只能处理js类型的文件,无法处理其他非js类型的文件
如果要处理非js类型的文件,我们需要手动安装一些合适第三方 loader加载器
1、打包处理css文件,需要安装 npm i style-loader css-loader -d
2、在webpack.config.js配置文件中新增一个配置节点,叫做modul对象,在这个对象里面,有一个rules 属性的数组,这个数组中可以配置所有第三方文件的 匹配和处理规则
在webpack.config.js文件的exports中增加module:
12、loader-分析webpack调用第三方loader的过程
例如,在处理CSS文件,找到对应规则后,会先调用'css-loader',然后把处理结果给'style-loader',调用'style-loader'处理完以后,直接交给webpack进行打包合并,输出到bundle.js中去。
13、loader-配置处理less文件的loader
(1)在css文件夹下建一个文件index.less,写一些样式,然后,在mian.js中,使用import导入index.less
1 //使用import 语法,导入less样式 2 import './css/index.less'
(2)装包
npm i less-loader -D
npm i less -D
(3)配置规则
14、loader-配置处理scss文件的loader
步骤同less-loader的配置
15、webpack中url-loader的使用
默认情况下,webpack无法处理CSS文件中的URL地址,不管是图片还是字体库,只要是URL地址,都处理不了
(1)npm i url-loader file-loader -D
file-loader是url-loader的内部依赖,配置匹配规则时只需要加入url-loader
16、webpack中使用url-loader处理字体文
(1)安装bootstrap3 npm install bootstrap@3
(2)在index.html中应用bootstrap中的图标
1 <span class="glyphicon glyphicon-heart" aria-hidden="true"></span>
(3)bootstrap中的图标依赖bootstrap.css,所以在main.js文件中引入bootstrap.css
1 //如果通过路径的形式去引入node_modules中的相关文件,可以直接省略路径前面的node_modules这层目录 2 import 'bootstrap3/dist/css/bootstrap.css'
(4)bootstrap中的图标依赖bootstrap的字体文件,所以需要配置处理这些字体文件的
1 //引入bootstrap后处理字体文件的loader 2 {test:/.(ttf|eot|svg|woff|woff2)$/,use:'url-loader'}
17、关于webpack和npm中几个问题的说明
注意:.json文件里面不能写注释
之前安装过包,会在package.json里面有记录,但不一定代表项目node_modules下就有这个包,如果运行报错,找不到相应的包,注意查看是否包不在了
18、webpack中babel的配置
在main.js中写以下几行代码
1 class Person { 2 static info = {name: 'zs', age: 20 } 3 } 4 // 访问Person类身上的info静态属性 5 console.log(Person.info);
class关键字,是ES6中提供的新语法,是用来实现ES6中面向对象编程的方式
使用static关键字,可以定义静态属性,所谓静态属性,就是可以通过类名,直接访问的属性
实例属性:只能通过类的实例,来访问的属性,叫做实例属性
在webpack中,默认只能处理一部分ES6的新语法,一些更高级的ES6或者ES7语法,webpack是处理不了的,例如class定义的类;
这时候需要借助第三方的loader,帮助webpack处理这些高级的语法,当第三方loader把高级语法转为低级的语法之后,会把结果交给webpack去打包到bundle.js中。
通过Babel,可以将高级语法转换为低级语法
1.在webpack中,可以运行如下两套命令,安装两套包,去安装Babel相关的loader功能:
1.1 第一套包(Babel的转换工具): cnpm i babel-core babel-loader babel-plugin-transform-runtime -D(这里有坑:babel-loader@7.x 对应 babel-core@6.x 需要安装对应的版本,不然会报错)
1.2 第二套包(Babel语法插件):cnpm i babel-preset-env babel-preset-stage-0 -D
2.打开webpack的配置文件,在module节点下的rules数组中,添加一个新的匹配规则:
2.1 { test:/.js$/, use: 'babel-loader', exclude:/node_modules/ }
2.2 注意:在配置babel的loader 规则的时候,必须把node_modules目录,通过exclude选项排除掉,原因有二:
2.2.1 如果不排除掉node_modules,Babel会把node_modules中所有的第三方JS文件,都打包编译,这样,会非常消耗CPU,同时打包速度非常慢;
2.2.2 就算Babel把所有node_modules中的JS转换完毕,项目也无法正常运行。
3. 在项目根目录中,新建一个叫做.babelrc的Babel配置文件,这个配置文件属于JSON格式,所以在写Babel配置文件的时候,必须符合JSON语法规范:不能写注释,字符串必须用双引号
3.1 在.babelrc配置文件中,写如下配置:
1 { 2 "presets": [ "env", "stage-0" ], 3 "plugins": [ "transform-runtime" ] 4 }
运行项目可以看见页面控制台打印出 Person对象的静态属性info: