前言
这篇文章是自己在整理webpack相关的东西时候突发奇想,想总结自己所学知识,也希望能够帮助想学习webpack的同学们,都是入门级别的,大佬请出门右转。
本文的webpack基于webpack4.0,具体是4.12.0版本
初识webpack
webpack是什么?借助官网的话来说,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
简单的来说,webpack是一个打包工具
webpack的基本配置项
作为入门,我们只需要明白几个核心概念:
- Entry(入口)
- Output(出口)
- Loaders
- Plugins(插件)
- Mode(模式)
Entry
入口起点指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
// webpack.config.js |
Output
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。
module.exports={ |
Loaders
首先,webpack 自身只理解 JavaScrip,所以针对其他的文件,我们需要借助 loader 去处理。
loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
比如对于css文件,我们可以这样写:
module.exports = { |
Plugins
loader 被用于转换某些类型的模块,而Plugins(插件)则可以用于执行范围更广的任务。
Mode
通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化
webpack初体验
通过上面基础概念的学习,我们开始动手写个小demo吧
安装使用webpack的方式有两种,一种是全局安装webpack,一种是在我们的项目中安装webpcak依赖,然后通过npm执行webpack命令。
通常建议用第二种方式安装,因为前端更新太过快捷,很多人的webpack版本和你的可能不太一样,导致出现一些问题
1、初始化我们的项目
- 新建一个文件夹,取名叫做webpack-demo
- 通过控制台或者git bash定位到当前文件下面,执行命令: npm init -y
2、项目结构搭建
新建src目录,用于放置我们的开发所需要的css、img、js和html文件(和平时开发一致就好)
在根目录新建index.html
在根目录新建webpack.config.js,这是webpack的默认配置文件
ps: webpack默认会读取webpack.config.js 中的相关配置,如果更换其他名字,webpack默是找不到的(当然我们也可以去指定webpack读取的配置文件,但在现阶段,我们暂不考虑)
index.html的格式如下:
|
安装 webpack 和 webpack-cli
在当前目录(webpackDemo)执行命令: npm install webpack webpack-cli –save
为什么要装 webpack-cli ,是因为以前webpack的cli工具移动到了一个专门的包(webpack-cli)里了
接下来我们配置下package.json,把”scripts”字段修改为:
"scripts": { |
新建入口文件和配置webpack.config.js
1、在src/js目录下新建index.js文件,作为webpack的入口文件,文件内容为:
console.log("hello world") |
2、接下来我们打开 webpack.config.js ,配置下我们的编译规则
const path = require('path') |
__dirname是node暴露给全局的一个变量,表示当前文件所在的目录,path模块是node自带的模块,用来处理路径的
3、在webpack-demo目录下执行npm run build命令
此时查看dist/js目录,会发现新增了一个bundle.js的文件,然后打开index.html文件,在f12打开控制台,是不是输出了hello world啊?
好了,本次教程到此结束了
看到这里,是不是很像拍死我了,输出hello world还这么麻烦,而且还什么都没学到,浪费我青春啊!!!骚年,开个玩笑嘛,别着急,有话好好说啊,接下来重头戏开始了。
针对css文件和img文件的Loaders
通过上面的小例子,发现好像少了些什么,一个页面不可以只有js的吧,我们强大的css和好看的img呢?
接下来我们就开始学习强大的Loaders啦
安装style-loader、css-loader 和 url-loader、file-loader
执行命令: npm install style-loader css-loader url-loader file-loader –save
这里特别说明下,file-loader与url-loader都是在webpack中引入图片的解决方案,但是与file-loader不同,url-loader封装了file-loader,并且可以在图片大小小于设定的limit的时候返回的是一个bDataURL(base64码),大于limit时会调用file-loader对图片进行处理。
添加webpack规则
在webpack.config.js添加规则
module: { |
添加规则之后,我们在src/css目录下新建index.css,在src/img目录下放一个img.jpg后,接下来就是修改我们的代码了
index.css文件如下
body { |
修改我们的入口文件index.js
import '../css/index.css' |
在运行一下npm run build,然后打开我们的浏览器,页面是不是有了个蓝色背景和一张图片呢?
这感觉是不是美滋滋
题外话,这里我们用了es6,浏览器也没有报错,因为现在新版浏览器对es6兼容相当不错了,可是对于旧版本,浏览器兼容还是不是很好的
所以我们针对我们写的js也需要做下babel编译
1、安装babel
执行命令: npm install babel-core babel-loader babel-preset-env –save
2、新建.babelrc文件
这里babel会默认读取根目录下的.babelrc文件作为babel的编译规则
{ |
3、配置js的loader规则
增加loader的配置项:
module.exports={ |
4、拓展下我们的output规则
现在我们细心的看一下,你会发现我的output的文件名使我们定死的,每次打包,名字都不会改变,我们怎么可以根据他的文件名生成同样的名字呢?webpack提供提议[name]的占位符,
表示入口的的文件名。
修改下webpack.config.js:
output: { |
那么问题又来了,我们怎么引入我们动态生成的[name].js呢?也许有人说改成和入口文件一样的名字不就行了吗?这样的确是一种方案,但是能不能可以通过一个模板,自动注入我们生成的js文件呢?接下来就是用我们更强大的插件啦
常用的插件
html-webpack-plugin
针对于上面的问题,我们就可以借助html-webpack-plugin自动生成我们的html啦。
1、安装html-webpack-plugin
肯定要先安装啦,不然怎么用╭(╯^╰)╮:npm install html-webpack-plugin –save
2、创建我们的模板页面
在src目录下新建index.html,用于我们的模板页面,代码如下:
|
3、配置webpack.config.js规则
增加plugins的配置项:
const HtmlWebpackPlugin = require('html-webpack-plugin') |
这样我们就可以直接打开dist的index.html文件就好,不需要根目录下的index.html文件了
打开index.html文件后,你会发现图片404,并且多了一些文件,我们先解决我们图片404的问题,因为我们的index.html所在目录目录发生了改变,所以js也需要跟着改变一下
import '../css/index.css' |
ps:目前只考虑单页面的生成
clean-webpack-plugin
到目前为止,我们学会了动态生成模板页面了,然后怎么清楚我们之前多余的文件呢,这里我们需要借助clean-webpack-plugin插件来删除我们多余的文件
1、安装clean-webpack-plugin
npm install clean-webpack-plugin –save
2、配置webpack.config.js规则
// 删除某些东西 |
这样每次执行我们命令的时候就会先删除dist目录在创建
copy-webpack-plugin
小知识,针对于一些我们不想修改的静态资源文件,我们可以通过copy-webpack-plugin处理这些静态资源文件
我们在src目录下新建一个asset目录,放置一个1.txt文件,内容为:此例子没有什么大的实际意义╭(╯^╰)╮
插件我们还是需要执行两个步骤的,先安装,在配置
1、安装copy-webpack-plugin
npm install copy-webpack-plugin –save
2、配置webpack.config.js规则
// 处理静态资源,静态资源输出 |
服务器运行
到目前为止,我们已经怎么通过模板自动生成页面,自动生成js,可是我们还是发现了一些问题,就是每次更改代码后都需要webpack重新去编译,并且我们的文件还是以文件系统在浏览器打开的,很显然,这不是webpack的正确姿势。
因此,我们考虑怎么让我们的项目运行在服务器端。
DIY一个临时的静态服务器
既然我们知道了我们最终生成的文件在dist文件夹,那么我们好像只要将dist文件夹的文件在服务器端跑起来不就好了吗?仔细一想,好像很有道理,那么我们尝试一下吧。
这里我们用express搭建一个静态的服务器
1、在根目录下新建一个app.js文件,并安装express
npm install express –save
2、在app.js中,我们利用express写一个简单的服务器
// app.js |
3、配置下我们package.json的script字段
为了统一下我们的命令,不在命令行执行node app.js,我们统一用npm执行我们的命令
"scripts": { |
然后我们可以在控制台执行:npm run server
接下来我们在浏览器输入localhost:3000,是不是可以看到我们打包后的文件了?
ps:如果控制台输出Error: listen EADDRINUSE :::3000,说明你的端口被占用,修改下app.js的端口号就行
DIY服务器存在的问题
写完这个,虽然他可以在服务器端运行我们的代码,但是我们还是要重新通过webpack编译,而且还不能实现热更新和自动从浏览器中打开,当然我们也可以通过引入node的child_process模块中的exec来自动打开我们的文件,因为本篇不是node的教程就不拓展了。
devServer
其实对于这个问题,webpack也早已经想到了,所以他就提供了一个devServer的配置字段,可以配置我们的本地服务器,解决热更新问题。
1、安装webpack-dev-server
npm install webpack-dev-server –save
2、配置webpack.config.js规则
增加一个devServer字段
module.exports = { |
3、配置package.json的script字段
"scripts": { |
然后控制台输入:npm run dev的命令后,激动的心扑通扑通的跳,打开浏览器一看,wtf,报了个Uncaught Error: [HMR] Hot Module Replacement is disabled.错误,原来是我们光是在devServer配置hot还不行,需要在plugins调用一下webpack提供的热更新模块
// webpack.config.js |
这样我们就可以实现热更新啦,热更新的好处不知道发现没有,他只会替换更新的部分,而不会把整个页面给刷新。我们可以尝试修改下index.css,把body的背景修改成红色就可以发现效果了,然后在尝试把hot去掉,在修改body背景色看看,会发现整个页面都刷新了。
打包优化
在服务器看到我们的页面没什么问题了之后,我们就可以打包我们的文件啦,打包过后其实我们会发现我们的文件好像有点大,知识在控制台输出一个helloworld还有创建了一个img标签,居然要50kb的代码,简直太大了吧。
接下来我们就要压缩我们的js,其实也很简单,webpack4提供了mode的production属性就是压缩js的,我们通过命令行开启,修改webpack.config.js或者package.json的script就可以了,这里我采用package.json的方式
"scripts": { |
这样之后,是不是发现小了很多啊,或许你还会问了,那css不是还在js里面吗,我们能不能单独提取出css呢?答案是肯定的
提取css
提取css官方提供了两个方式,一个是extract-text-webpack-plugin,另一个是mini-css-extract-plugin,这里我们采用extract-text-webpack-plugin,原因是extract-text-webpack-plugin提供更多的操作api,相比mini-css-extract-plugin更为的好用。想要使用,我们就需要安装,操作步骤我想大家都已经很清楚了
1、安装extract-text-webpack-plugin
npm install extract-text-webpack-plugin@next –save
ps: 这里提个醒,一定要安装extract-text-webpack-plugin@next,因为 extract-text-webpack-plugin 最新版本为 3.0.2,这个版本还没有适应 webpack 4 的版本
2、配置webpack.config.js规则
这里,loader的配置也需要修改一下
// 提取css |
这样不仅css提取出来了,连js也变的小了许多,然后打开css文件发现css文件居然没有压缩- -,然后我们接着配置一下我们的loader,实现对css的压缩,或许你之前听过一个叫cssnano的神器,想用他来压缩,不用担心css-loader是默认把cssnano封装进去了
实际上webpack对于loader的use写法有很多种,我们之前用的是比较简单的一种,不使用任何的配置项,接下来我们配置一下压缩的配置项
打开webpack.config.js,修改下loader的代码
注意:新版的css-loader已经把minimize参数删除掉,下面请不要使用
module.exports = { |
在引申一个问题,我如果想给我的页面加个背景图片也很正常吧,我们尝试着在我们的index.css修改以下代码
body { |
在打包一次,wtf,背景图片怎么不见了,仔细一看css代码,原来是img的路径有问题了,这里我们可以在loader上加多一个配置,解决背景图片的问题
use: ExtractTextPlugin.extract({ |
这样配置完,就没有问题了
暴露第三方库和提取公共js
暴露第三方库
很经常的时候,我们的页面不只是只有我们写的js,还可能引入各种各样的库,比如jquery,underscroe这种第三方工具库,我们怎么把它暴露给我们的js呢,其实只需要用到webpack的ProvidePlugin插件
这插件是webpack自带的所以不需要安装,只需要我们修改webpack的配置规则
// 向全局暴露第三方库 |
提取公共js
Webpack3的commonschunk hash问题非常的不雅,使用复杂, Webpack 4 直接将CommonsChunkPlugin 插件直接改为 optimization.splitChunks 和 optimization.runtimeChunk 两个配置
module.exports = { |
img压缩和css优化
目前为止,我们的webpack-demo已经相对完善了,然后其实还有一些优化空间的,比如css能不能自动增加前缀啊,比如我们的img大小好像都没有压缩啊,能不能压缩啊什么的
image-webpack-loader
这里我们使用image-webpack-loader进行img的压缩处理
1、安装image-webpack-loader
npm install image-webpack-loader –save
2、修改下loader配置
module.exports = { |
这样就可以压缩我们的img了
css优化篇——css自动增加前缀
我们知道在写css的时候由于要兼容不同厂商浏览器,一些比较新的属性需要给它们添加厂商前缀来兼容,移动端还好,一般只需要兼容webkit,pc接很苦逼啦,谷歌、火狐、欧朋、ie每个都不一样,可以说泯灭人性啊。
针对于这个,我们就可以通过webpack来实现帮我们自动给css增加前缀,这里采用最常用的postcss中的Autoprefixer插件来给我们自动增加前缀
题外话,为什么需要浏览器引擎前缀?
1、试验一些还未成为标准的的CSS属性——也许永远不会成为标准
2、对新出现的标准的CSS3属性特征做实验性的实现
3、对CSS3中一些新属性做等效语义的个性实现
postcss-loader
聊完了题外话,我开始配置我们的webpack啦。
1、安装postcss-loader和autoprefixer
npm install postcss-loader autoprefixer –save
2、新建postcss.config.js文件
代码如下:
module.exports = { |
3、配置webpack.config.js的规则
module.exports = { |
我们修改下index.css的代码,做个body的背景颜色由深到浅的悬浮过度动画
body { |
运行npm run dev,就可以看到我们的效果啦,并且该加上的前缀也加上了
总结:懒人绝对是推动世界发展的主要动力啊
css优化篇——去除冗余css代码
1、安装purify-css、purifycss-webpack和glob
npm install purifycss-webpack purify-css glob –save
2、配置webpack.config.js的规则
// 删除冗余css代码 |
测试一波,我们在index.css增加一些无用代码,比如
.a{ |
运行npm run build,再看看打包后的index.css是不没有这两个样式
使用less
作为一个称职的前端,怎么能不使用css预编译呢,这里我们使用less,然后通过webpack添加对less的支持
前文已经说了,webpack天生只对js支持,所以我们需要安装loader才能添加对于less的支持
1、安装less-loader
npm install less-loader –save
2、配置webpack.config.js的规则
其实和配置css-loader就类似了,这里就不详细说明了
module.exports = { |
插件传送门
webpack英文传送门 英文好的可以看这个
1、html-webpack-plugin
2、clean-webpack-plugin
3、copy-webpack-plugin
4、extract-text-webpack-plugin
5、purifycss-webpack
总结
学到这里,我想已经大概已经怎么使用webpack了,也算入了个门,对于一些常见的webpack配置也可以看得懂了,一些常用的插件也知道怎么的使用啦
当然,其实还有好多依然讲的不全,很多地方也没有做详细的解释,但是我相信,一步一步来,欲坑填坑,总会学习到更多东西的。
本篇webpack文章到此结束 O(∩_∩)O~
最后,感谢各位观众老爷观看