Webpack学习-Webpack初识

时间:2021-01-13 15:16:42

一、前言 

webpack 到底是个什么东西呢,看了一大堆的文档,没一个能看懂的,因为上来就是给个module.exports 然后列一大堆配置,这个干啥,那个干啥,没一点用。但凡要用一个东西,一个东西火了,首先得知道为什么要用它,它究竟是来干什么的,它有什么好处。webpack 顾名思义,就是web打包,主要是打包一些前端资源的,再通俗点讲,就是把前端用的一些js,css压缩混淆,images fonts什么的也做相应处理,这只是webpack其中的一点功能,对于初学者来说,先知道这些就行了。

因为webpack是基于nodejs开发的一个前端打包工具,所以许多后端人员如果想学的话是比较吃力的,需要先学习一下nodejs,不然其中的一些语法什么都看不懂,一头雾水。webpack还有其他一些功能,也是比较重要的,比如:模块化开发,把所有资源都当成一个模块,用import的方式引入相关js中,甚至连css ,img 都引入进去,这一点也是让我比较吃惊的,具体里边怎么加载到页面上的我也不知道,以后学了再看。

总计一下一句话:webpack是一个前端模块化打包工具。

注意:前边已经说了,webpack是基于nodejs开发的一个前端打包工具,所以使用webpack需要安装node环境,而node环境运行起来需要一系列依赖的包(相当于java中的各种jar,c#中的各种类库了),webpack就属于其中的一个,这么多包就需要一个管理工具来管理,于是乎,就引出了npm,npm就是nodejs中的一个包管理工具,相当于java中的maven,c#中的nuget,这就是这三者之间的关系。

二、起步

2.1 webpack的两种安装方式

1.在cmd下或者其他命令行工具下运行 npm i webpack -g  全局安装webpack,这样 安装完成之后 在命令行工具下输入webpack就会起作用。

2.在项目根目录运行 npm i webpack --save-dev 安装到项目的依赖中,在构建项目时,使用本地开发版的webpack,打包完后就不再用了,因为webpack其实就是来进行打包的,运行的时候是构建好的html、js、css这些东西。

这两种方式的区别时,全局安装webpack,每次在终端运行webpack时,就是使用的全局的webpack,假设你全局安装的webpack是4.0的版本,而你的一个老项目用的是webpack3.0的版本,那你在项目构建的时候就不能直接运行webpack命令了,需要用npm i webpack@3.0 --save-dev ,安装一个3.0版本的webpack,然后这个项目就用刚才安装的3.0版本的webpack来进行构建,这也是要装到本地项目webpack的一个要用到的地方。webpack也是node_modules中的一个模块,如果本地安装后,就可以在本地的依赖中找到它。

局部使用webpack,一般在package.json中的scripts中配置执行的,我们用npm来帮助执行的话,那就是当前项目使用的。

2.2 使用webpack打包构建一个项目

1.新建一个文件夹叫webpack-study,在该目录下执行命令npm init -y,会生成package.json 文件,就是基于webpack的整个项目的配置文件,如图:

Webpack学习-Webpack初识

这里边包括 项目名称,版本号,描述

项目入口文件:index.js,webpack默认是会直接运行这个index.js文件 然后执行一系列的代码,这里和nodejs的思想是一样的。

脚本代码:scripts 这是项目启动时可以运行的脚本代码,你也可以添加别的代码,比如:使用npm run test,就是执行这里的test脚本,有可能一些命令非常长,直接打不方便,那么就可以在这里配置一下,相当于一个别名。

其他的就不说了。

2.创建项目的基本目录,如下所示,很简单的几个文件

Webpack学习-Webpack初识

3. 使用 npm i jquery --save 安装jquery类库

4.写代码

在index.html中写一个ul li列表    

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul id="list">
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
</body>
</html>

在index.js页面中写

 // 导入jquery类库
import $ from 'jquery'
//webpack 使用模块化开发 这里用import 语法 从jquery中导出一个模块 我们给他起个名字叫$ 接下来我们就可以像我们传统使用jquery一样使用它了
console.log($)
// 设置偶数行背景色,索引从0开始,0是偶数
$('#list li:even').css('backgroundColor','lightblue');
// 设置奇数行背景色
$('#list li:odd').css('backgroundColor','pink');

接下来我们把index.js引入到index.html 页面 ,直接在浏览器打开,然后就报错了,是因为浏览器现在还不认识 import语法,虽然在es6的标准中已经提到了,但是他们还不支持。

Webpack学习-Webpack初识  Webpack学习-Webpack初识

所以我们就不能直接引入这个index.js了,因为用了高级的语法,我们要用webpack对它打包处理一下,变成浏览器能识别的js。

运行 webpack .\src\index.js -o  .\dist\bundle.js,意思是把src下边的index.js 打包到dist下的bundle.js ,执行结果如下:dist下边生成了一个bundle.js,内容一大坨,不知道什么玩意。

Webpack学习-Webpack初识  Webpack学习-Webpack初识

接下来我们在index.html页面引入bundle.js,成功输出并显示。

Webpack学习-Webpack初识  Webpack学习-Webpack初识

以上就是webpack 最简单的使用方式。webpack不仅能打包js,包括css,img 等很多静态资源都能打包,还有很多的第三方插件,帮助前端页面优化,配置。一下简单说一下就不再演示了 。

2.3 实现webpack的实时打包构建

由于每次重新修改代码之后,都需要手动运行webpack打包的命令,比较麻烦,所以使用webpack-dev-server来实现代码实时打包编译,当修改代码之后,会自动进行打包构建。

运行cnpm i webpack-dev-server --save-dev安装到开发依赖。

安装完成之后,在命令行直接运行webpack-dev-server来进行打包,发现报错,因为此时使用的是全局的webpack-dev-server命令,但是我们并没有全局安装,此时需要借助于package.json文件中的指令,来进行运行webpack-dev-server命令,在scripts节点下新增"dev": "webpack-dev-server"指令,让它变成当前本地的命令就可以了,因为我们已经本地安装了,发现可以进行实时打包,但是dist目录下并没有生成bundle.js文件,这是因为webpack-dev-server将打包好的文件放在了内存中。

bundle.js放在内存中的好处是:由于需要实时打包编译,所以放在内存中速度会非常快。

这个时候访问webpack-dev-server启动的http://localhost:8080/网站,发现是一个文件夹的面板,需要点击到src目录下,才能打开我们的index首页,此时引用不到bundle.js文件,需要修改index.html中script的src属性为:<script src="../bundle.js"></script>

为了能在访问http://localhost:8080/的时候直接访问到index首页,可以使用--contentBase src指令来修改dev指令,指定启动的根目录:"dev": "webpack-dev-server --contentBase src" 同时修改index页面中script的src属性为<script src="bundle.js"></script>

2.4 使用html-webpack-plugin插件配置启动页面

由于使用--contentBase指令的过程比较繁琐,需要指定启动的目录,同时还需要修改index.html中script标签的src属性,所以推荐大家使用html-webpack-plugin插件配置启动页面。

运行cnpm i html-webpack-plugin --save-dev安装到开发依赖。

修改webpack.config.js配置文件如下:

// 导入处理路径的模块
var path = require('path');
// 导入自动生成HTMl文件的插件
var htmlWebpackPlugin = require('html-webpack-plugin'); module.exports = {
entry: path.resolve(__dirname, 'src/js/main.js'), // 项目入口文件
output: { // 配置输出选项
path: path.resolve(__dirname, 'dist'), // 配置输出的路径
filename: 'bundle.js' // 配置输出的文件名
},
plugins:[ // 添加plugins节点配置插件
new htmlWebpackPlugin({
template:path.resolve(__dirname, 'src/index.html'),//模板路径
filename:'index.html'//自动生成的HTML文件的名称
})
]
}

修改package.jsonscript节点中的dev指令如下:"dev": "webpack-dev-server"

将index.html中script标签注释掉,因为html-webpack-plugin插件会自动把bundle.js注入到index.html页面中!

2.5 实现自动打开浏览器、热更新和配置浏览器的默认端口号

修改package.json的script节点如下,其中--open表示自动打开浏览器,--port 4321表示打开的端口号为4321,--hot表示启用浏览器热更新:"dev": "webpack-dev-server --hot --port 4321 --open"

2.6 使用webpack打包css文件

运行cnpm i style-loader css-loader --save-dev

修改webpack.config.js这个配置文件:{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }

注意这里顺序不能乱,webpack默认是从右到左读取loader的。

2.7 使用webpack打包sass文件

运行cnpm i sass-loader node-sass --save-dev

webpack.config.js中添加处理sass文件的loader模块:{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }

2.8 使用webpack处理css中的路径

运行cnpm i url-loader file-loader --save-dev

webpack.config.js中添加处理url路径的loader模块:{ test: /\.(png|jpg|gif)$/, use: 'url-loader' }

可以通过limit指定进行base64编码的图片大小;只有小于指定字节(byte)的图片才会进行base64编码:{ test: /\.(png|jpg|gif)$/, use: 'url-loader?limit=43960' },

2.9 使用babel处理高级JS语法

运行cnpm i babel-core babel-loader babel-plugin-transform-runtime --save-dev安装babel的相关loader包

运行cnpm i babel-preset-es2015 babel-preset-stage-0 --save-dev安装babel转换的语法

webpack.config.js中添加相关loader模块,其中需要注意的是,一定要把node_modules文件夹添加到排除项:{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }

在项目根目录中添加.babelrc文件,并修改这个配置文件如下:

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

三、webpack中的配置文件   

3.1 webpack.config.js

按照以上打包方式肯定太麻烦,还没牵扯到配置什么的,如果文件太多就更麻烦。所以,webpack提供了一个配置文件,打包的时候webpack会自动找到目录下边的webpack.config.js ,它里边需要用nodejs的语法导出一个配置对象,这样webpack就会根据这个对象对目录下边你配置过的资源打包了。下面我们先来简单配置一波,实现我们前边的功能,添加一个webpack.config.js文件,写入下面内容:

const path = require('path')

module.exports ={
entry:{
index:path.join(__dirname,'./src/index.js')
},
output:{
path: path.join(__dirname, './dist'),
filename: 'js/[name].js'
}
}

直接在根目录下运行webpack 命令,就完成了我们刚才的功能。

Webpack学习-Webpack初识

3.2 项目中的其他文件

简单说一下:

dist:使用 webpack -p 命令后,会把相关配置的文件全部打包到这下面,也就是我们对外发布的目录。

package.json :使用 npm init -y 后生成的项目配置文件,学过nodejs的应该都是知道,这里边不仅有项目自己的配置,还有包的相关依赖啥的,相当于我们asp.net 中的Web.config、App.config,java中的web.xml等等。  

{
"name": "05",
"version": "1.0.0",
"description": "",
"main": "main.js",
"dependencies": {
"bootstrap": "^3.3.7",
"css-loader": "^1.0.0",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^3.2.0",
"jquery": "^3.3.1",
"style-loader": "^0.21.0",
"url-loader": "^1.0.1",
"webpack-dev-server": "^3.1.4"
},
"devDependencies": {
"webpack": "^4.16.1",
"webpack-cli": "^3.0.8"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --open --port 3000 --contentBase src --hot"
},
"keywords": [],
"author": "",
"license": "ISC"
}

package-lock.json: npm 4 以上会生成这个文件,里边各种包的依赖清晰明了,包的版本号也被锁定,当你重新安装或者还原node_modules文件夹时,以前是从package.json中解析依赖的比较耗时,而且版本号可以会 恢复的包的最新版本,现在是根据这个文件直接读取依赖关系并还原相关版本。

{
"name": "05",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@webassemblyjs/ast": {
"version": "1.5.13",
"resolved": "http://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.5.13.tgz",
"integrity": "sha1-gRVaVwvVgDow7DFDa8LJwO3jjyU=",
"dev": true,
"requires": {
"@webassemblyjs/helper-module-context": "1.5.13",
"@webassemblyjs/helper-wasm-bytecode": "1.5.13",
"@webassemblyjs/wast-parser": "1.5.13",
"debug": "3.1.0",
"mamacro": "0.0.3"
}
},
.....
}

webpack.config.js :是webpack打包的配置文件

const path = require('path');
const webpack = require('webpack');
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.join(__dirname, './src/main.js'),
output: {
path: path.join(__dirname, './dist'),
filename: '[name].js'
},
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},{
test:/.(jpg|png|bmp|gif)$/,
use:'url-loader?limit=31&name=[hash:16]-[name].[ext]'
},{
test:/.(eot|svg|ttf|woff|woff2)$/,
use:'url-loader?limit=31&name=[hash:16]-[name].[ext]'
}]
},
plugins:[
new htmlWebpackPlugin({
template:path.join(__dirname,'./src/index.html'),
filename:'index.html'
})
]
}

3.3 常用命令

npm i webpack -g  //全局安装webpack
npm i webpack --save-dev // 本地项目安装webpack 要与全局安装配置使用
npm i nrm - g //全局安装 nrm 可以选择 nrm 的包地址
npm i cnpm -g // 全局安装cnpm 和npm差不多 比较快
npm i webpack-dev-server -g //全局安装dev-server 模拟服务器
webpack -p //按配置打包到dist 目录中
//PS: -S就是--save的简写,-D就是--save-dev 这样安装的包的名称及版本号就会存在package.json的devDependencies这个里面,而--save会将包的名称及版本号放在dependencies里面四、

四、总结

关于webpack的使用这里只介绍一下它是什么,它能干什么,它有什么好处。也能让我们最起码知道,具体深入,以后自己找时间玩。