近在咫尺的webpack5马上就要发布,在这个4的尾巴阶段,留一份一看就懂的教程。但无论是哪个版本,只是升级了而已,总而言之,webpack是一个高级前端工程师必会的(虽然博主不是)。
博主也在不断学习中,复习到webpack,想借此博客写一篇容易看懂的。因为如果你是小白,其他的博客文章,自己很难看懂。
本次,我们从一个空文件夹开始,一步一步的搭建一个webpack,如果你静下心来,好好看看这篇文章,相信你会有收获。开发前提:安装nodeJs。
本篇文章的学习知识(并非按照下边顺序讲解):
1、webpack的作用。
2、自己搭建webpack项目
3、webpack的默认配置(entry/output等等)。
4、hash和chunkhash
5、webpack自定义配置。
6、loader模块处理。
7、plugin插件。
8、mode(production生产环境和development开发环境)。
以上这些就是打算今天要学习的,几乎学习完了,自己也就都懂了。所以知识不少,跟住思路,我们一起来学习。
------------ 一、webpack的作用: ----------
webpack 的主要目标是将 JavaScript 文件打包在一起,打包后的文件用于在浏览器中使用。
曾经的前端并没有现在这么复杂,如今我们前端的发展,已经到了承接各种需求的地步,那么我们现在开发代码很多,逻辑也很多,慢慢的一些技术或者插件也就随之而来。比如vue或react,这两种开发方式都是模块化开发,模块开发对我们前端来说固然方便了很多,但上线后在加载上会出现一些性能问题。这就是模块过多,请求数量引起的。
那工程师想到的办法就是,将这些模块,打包成一个文件,这样将请求数量降到最低,提高加载速度。所以打包工具就出来了。
webpack一大亮点是,它能分析代码结构,按需打包,会将无用的代码过滤掉,只打包有用到的代码,减少体积。这也是取代了gulp的原因(据说gulp会将有用的没用的代码或插件都打包在一起)。
------------ 二、使用webpack搭建项目 ----------
我们今天不弄的那么复杂,就简单搭建一个有html、css、js和图片的一个项目,从建立一个空文件夹开始搭建一个项目。这种教程还是比较少的,最少需要掉三根头发才能写完教程(博主先去哭一会)。
1、首先,我们建立一个空文件夹,记住文件夹的名字不要是webpack,否则将会创建不成功。名字随便起(本文先以博主名字建个文件夹:villin)
2、进入到这个文件夹,打开你的终端,空文件夹第一步需要生成一个叫package.json
的文件。它是“做肾”的?package.json
就是管理你本地安装的npm包,用于定义了这个项目所需要的各种模块,以及项目的配置信息。如版本、描述、作者、运行脚本(如:npm run dev
)等等。最主要的是我们有了这个模块,稍后下载的时候,就可以在文件夹中自动生成一个node-modules文件夹。然后会将以后的模块下载到node-modules文件夹中。
简单来说,你可以把它看成是一个项目说明书,上边记录了这个项目的所有权,我们下载第三方插件时,也会记载到这里,以后我们传文件时,可以删掉node-modules文件包,但只要有package.json这个文件,npm i 时就可以重新按照这个说明说下载回来。所以package.json这个文件始终都不能删!!!
运行: npm init
运行之后,第一次会询问一些问题,我们可以设置,也可以一直按回车键。之后我们就生成了package.json
文件夹了,可以打开看一下:
我们可以看一下,里边有一个devDependencies
字段,这里放着的就是我们这个项目所用到的插件,每次安装一个插件时,就会被记录当这里。
3、安装webpack:
不建议全局安装,就是后边带一个-g
的这种,原因是:我们一旦全局安装后,所有项目都会用到这个版本的,如果你有其他的项目用到的是旧版本,那么会有冲突。
所以我们进入到这个文件夹后,直接安装即可。除了安装webpack,在V4+版本时,还需要安装webpack-cli,所以我们一起安装:
npm i -D webpack webpack-cli
4、安装后看一下目录,是这个样子:
5、现在我们就可以运行webpack了,这里涉及到了一个知识点,自定义构建脚本命令,我们进入到package.json文件,里边有一个“scripts”字段,里边就是自定义的命令,因为这里除了默认的,就没有命令了,我们没办法运行。所以我们想要运行webpack,就构建一条命令,然后运行它就可以。
在“scripts”字段里添加一个命令,"key":"value"的形式,我们随便起一个名字叫dev,后边放上webpack命令就可以了。
6、我们刚才添加了命令,现在就可以运行npm run dev
了,记住,定义了什么,就可以npm run 什么。这句话比较粗糙,但你能明白就好。
保存运行一下:npm run dev
。发现会报错:
报错的原因并不是因为我们的命令写错了,看上边的提示:没有找到./src文件
。
这就是为什么我们开发时,要把页面写在src中的原因。webpack在打包时,会自动的识别src目录下的根目录index.js
,所以这都是必须要有的。为了防止报错,我们就建立一个src文件夹,里边放入index.js文件,并且在index.js中随便写点内容,就写一个:
console.log("villin你好")
创建文件,如下:
我们重新运行:npm run dev
。运行成功。
我们这个时候再返回来看一下文件目录,会多出一个dist文件夹,里边会有一个main.js文件,这就是运行了webpack打包后的文件。打包成功!如果你也跟到这里,没有任何问题的话,恭喜你,可以自己打包成功了,我们继续进行;如果有问题,不要往下进行,返回找到问题后继续哈哈
------------ 三、webpack配置 ----------
1、webpack的配置文件叫webpack.config.js
,我们在构建项目时,并没有这个文件,但这个文件确实真实存在的,webpack在打包时会自动识别叫这个名字的文件,如果有,就按照这里边配置的打包,如果没有,就按照它自己默认的打包。我们开发时需要配置,所以我们需要自己创建出来,和 package.json 同级,我们创建这个文件:
2、因为webpack在默认情况下,只打包src下边的index.js文件,但我们开发会有很多其他文件,我们就需要配置了,所以我们现在开始学习怎样配置这个文件。在webpack.config.js
文件中,我们的配置项,写在module.exports
对象中:
基本配置:entry和output
entry是入口的配置,webpack打包时,需要问,我打包哪一个文件啊?那么我们就把我们想打包的文件,放这里,webpack这个小可爱就知道了,就会将这个文件,以及这个文件引入的相关的一些文件,将它打包。打包成一个文件。然后又问,我打包后放在哪里呀?那么我们就把想要放的位置写在output中,这个小可爱就会按照我们给它的路径,放到这个里边。那怎么写呢?
entry可以写成字符串的形式,或者写成数组的形式,或者写成对象的形式,这三种形式都可以。
output一般我们写成对象的形式,重要的一点是,输出的路径一定一定要写成绝对路径。
我们先写entry,先用字符串的模式写,那我们打包哪一个文件呢?是src下边的index.js文件,如下:
如上图,output写成对象的形式,默认有两个参数,path和filename
,path就是我们打包后要放的地方(根目录下),filename是打包的文件名称(比如之前的main.js)。
为了方便直接定位到根目录,我们可以引入一个另外叫path的方法,从node中引进来,path下有一个resolve,里边有一个叫__dirname
的参数(双下划线),它就代表根目录,我们可以通过这个方法直接定位到根目录下。
默认情况下webpack打包出来的文件夹叫dist,文件叫main.js。为了方便理解,我们这次在配置中自定义更改一下,设置打包文件夹叫newDist,文件叫newMain.js。
// 引入path
const path = require("path");
module.exports = {
entry: "./src/index.js", // 入口文件
output: {
// 利用引入进来的path,定义到根目录。
// 两个参数:__dirname:根目录;"./newDist" 跟目录下的文件夹名称
path: path.resolve(__dirname, "./newDist"),
filename: "newMain.js" // 打包后文件的名称
}
}
然后,我们将之前打包的dist文件夹删除(一定要先删除,现在webpack不能帮我们删除旧的打包文件,防止重复,需要手动删除),重新执行打包,看一下效果。
这次打包新的版本,名称就变成了我们自定义设置的效果。这就是配置文件的厉害,可以随意的配置我们想要得到的东西。
3、src文件夹就是我们开发的文件夹,这个大家都知道。那么我们就可以在src中随意的创建文件。我们创建一个css文件,写点样式,然后在index.js中引入这个文件,再次打包一下:
在index.js根目录将它引入(因为webpack在默认情况下,只打包src下的index.js和跟它有关系的文件,想要把css也打包进来需要将css引入进来):
再次打包运行npm run dev
,发现报错了:
报错原因是webpack不识别css。
注意:webpack默认支持js和json模块,其他都不支持!所想让它支持,需要安装对应的loader
这就明白了,loader是干啥的?就是让webpack不识别的,识别一下。
4、那就开始配置loader吧,loader的配置也是固定的,记住就好。loader是一个模块,所以需要写在 module里,loader它是一个规则,并且有很多,所以是用 rules:[]
数组的形式写,里边就可以写各种loader规则了。写规则的时候,两个常用的参数,一个是 test ,一个是 use :
// 引入path
const path = require("path");
module.exports = {
entry: "./src/index.js", // 入口文件
output: {
// 利用引入进来的path,定义到根目录。
// 两个参数:__dirname:根目录;"./dist" 文件夹名称
path: path.resolve(__dirname, "./newDist"),
filename: "newMain.js" // 打包后文件的名称
},
module: {
rules: [{
test: /\.css$/, // /\这里写要识别的后缀$/
use: ["style-loader", "css-loader"] // css 需要这两个loader
}]
}
}
test后边是将要识别的后缀写在\
后,$
结束。use后是数组,需要的loader,就写在里边。这是规定。
现在运行会报错的,因为loader是插件,我们只引用了,可项目中并没有这两个插件,所以,我们需要下载进来,才能运行。
下载 style-loader和 css-loader:
npm i style-loader css-loader
下载完后再运行,看一下,没问题了,无报错信息。
有人可能会有疑问,你怎么知道需要这两个loader呢?这两个louder都是做什么的呢?为什么css会需要两个?
这个问题是这样的,用什么loader我也不知道,这些是在webpack官网中,会写明的,可以参考官网的文本,如果你需要什么到项目中,需要的loader都有什么。大家可以参考webpack官网。
loader的执行顺序是从右到左(去看代码),也就是先执行 css-loader,后执行style-loader。css-loader会将css文件解析成webpack所识别的文件,style-loader会将这个文件镶嵌到我们的html中(大概是这个意思)。
同样,我们引入一个图片也会报错,我们也需要按照这个方法,放进src一张图片,js引进来,写一个loader,图片需要file-loader
,下载loader:
npm i file-loader
如图所示,loader中的use是可以写成对象的写法的。
我们把旧的打包文件删掉,然后重新运行,然后运行打包成功。我们看一下打包后的文件目录:
发现多了一些文件,其中有一个就是图片文件,这个图片的名字很长,其他打包的文件名字也很奇怪。这是因为我们图片的名字是webpack自动解析的,而其他的名字,我们在之前的filename中设置成了固定的了。
在loader中,有一个options属性,属性里可以设置打包后的name名称。出口文件的filename也可以写成"[name].js"
的写法,改变名称。其他方法,可以参考官网设置,本次只讲常用的。仔细看代码,我们改变了出口的名字,和图片的名字:
// 引入path
const path = require("path")
module.exports = {
entry: "./src/index.js", // 入口文件
output: {
// 利用引入进来的path,定义到根目录。
// 两个参数:__dirname:根目录;"./dist" 文件夹名称
path: path.resolve(__dirname, "./newDist"),
filename: "[name].js" // 打包后文件的名称
},
module: {
rules: [{
test: /\.css$/, // /\这里写要识别的后缀$/
use: ["style-loader", "css-loader"] // css 需要这两个loader
},
// 图片loader
{
test: /\.png$/,
// use可以写成对象的写法
use: {
loader: "file-loader",
options: {
name: "[name].[ext]" // ext 在打包后,会生成对应的后缀名
}
}
}
]
}
}
删除之前打包文件,重新打包,打包后的文件名字就改变了:
其实这个时候,我们就可以写一个html文件放里了,然后在页面查看
我们刚才的css文件没有写全,可以在文件中,写个样式颜色:
然后再次重新打包。
5、写html文件,在打包中的文件里,可以放一个html文件,引入主文件的mian.js,然后可以放到网页中查看这个页面:
在文件夹中,可以双击html打开这个页面,我们就能看到页面变成了蓝色,控制台也有输出我们的数据:(没写图片标签,所以没有图片)
6、plugins的使用:
plugin是插件,可以帮助我们做一些事情,webpack插件真的是太多了,项目不同,我们用到的就不同,今天先讲两个常用的插件。既然是插件,那么这些插件功能,大神们已经给我们写好了,我们只需要下载后,引入进来,然后new一下使用就可以了。
clean-webpack-plugin
插件:
这个插件有什么用呢,如果这篇文章你好好看的话,会发现我们刚才每次打包之前,都需要提前删除旧的文件包,否则就会把新的文件也打包在之前那里,这样就会有问题。所以我们每次打包前,就需要提前删除一下。但这样不光浪费时间,而且还很危险啊,如果一不小心删错了,把src文件删了,那不是傻眼了。所以大神们就开发了CleanWebpackPlugin
插件,它能在我们运行打包命令的时候,自动的将之前旧的文件包删掉,然后再打包出新的文件(这不就是个宝贝吗),这就是插件的功能,那我们来尝试一下把:
首先先下载这个插件:
npm i clean-webpack-plugin --save-dev
然后引入进来:
怎么使用呢,刚才说了,写在plugins当中(插件不只是一个别忘了加s,复数!还得教你们英语,我太难了),我们只需要new一下就可以了,插件有很多,所以用数组的方式放进来就可以了。截取片段:
“不信邪的”(东北话:译为不相信的),自己再重新打包一下,是不是之前的会被删除,然后重新打包出新的文件。
再讲讲html-webpack-plugin
插件:
我们刚才想看一下页面,是需要自己手动创建html文件的。
这个插件可以自动的将我们src文件下的html文件(一般项目必有这个文件),打包后自动放入我们的包中。
我们现在根目录下创建html文件
和刚才一样,我们尝试一下:
然后下载:
npm i html-webpack-plugin --save-dev
使用时可以设置三个参数:
title(打包后html文件下title标签中的标题名)
template(目标html文件,也就是根目录下的html页面路径)
filename(打包后的html名称)
plugins: [
new CleanWebpackPlugin(),
new htmlWebpackPlugin({
title: "villin",
template: "./index.html",
filename: "villin.html"
})
]
打包一下,会看到打包文件夹newDist下有了这个文件,并且仔细观察,这个插件还会自动的将我们需要的js引入进来。
这就是这两个插件的用法,其他插件,自己可以查阅官网。
------------ mode开发环境和生产环境: ----------
我们在打包时,会有自己的环境配置,开发环境development和生产环境production。
这两个有什么区别?在webpack打包时,这两个打包后的代码就有区别,开发环境下,打包出的代码是不压缩的,原因是便于我们开发人员在出错的时候,查找bug代码;生产环境下,代码会压缩成“自己爹都不认识了”。会去掉空格、回车、注释等,减少体积。我们可以看一下这两个环境。
1、我们可以设置环境,写上mode,后边跟上生产环境:(截取片段)
我们重新打包,打包成功后,看下打包后的main.js代码:
有兴趣的自己看到底,反正我是没兴趣……………………
2、我们再看一下开发环境下的打包代码:
更换环境mode: "development", // 开发环境
3、我们这样来回换环境,不如换个执行命令,我们还可以这样做,在创建一个js文件,里边写上不同的开发环境,然后再自定义一个执行命令,当我们想执行不同的配置时,只执行不同的命令即可。
新建一个文件,起名叫:webpack.config.pro.js
里边换一个环境:
自定义命令:这个命令执行的也是webpack,但是需要通过--config
来告诉webpack,是哪个文件,所以在--config
后边写上要执行的路径即可。我们刚才之前定义的叫dev
,这次我们定一个叫build
:
这样我们再执行npm run build
的时候,就可以打包成生产环境的代码了。两个不同的环境,只需要执行不同的命令即可。
------------ hash和chunkhash: ----------
为了提高每次加载时的资源速度,我们在项目开发时,就需要缓存,不变的需要缓存起来。所以就出来了hash值得问题,hash有三个,本次简单说说两个。
hash的使用,我们就在输出文件的name后边加上hash即可。
filename: "[name]_[hash].js"
这样就可以了,再次打包看一下,是不是打包后的名字发生了“蛇”一样的加长了,这就是hash,打包后,在使用时,就会将不变的文件进行缓存,每次加载时就不用了重复的加载。
但是这样看着名字太长了,我们可以设置名字后边乱码的的长度,在hash后边加上长度即可,比如,我就留5位数,那么这样写:
filename: "[name]_[hash:5].js"
再次打包,看一下名字长度,发生了变化。
但是这个hash在开发时,我们方便测试,可以使用。但是在发布时,要使用chunkhash,原因是,每次打包,即使仅仅一个文件更改,所有文件的名字都会重新更改。这样版本更新,用户可能在加载时,就要全部重新加载了。为了提高效率,我们换成chunkhash,这样针对性的的更新,更友好一下,使用方法和hash一样,只是名字换了。
当然除了输出文件可以用hash,其他名字也可以,比如loader,后边设置名字后,也可以使用hash。
以上就是webpack入门的简单使用,我们可以根据这些基本方法,查看自己公司的webpack配置 ,查看官网,深入的学习