由浅至深探探webpack
随着模块式的开发的盛行,webpack应景起势。webpack是什么呢?没吃过猪肉还没见过猪跑吗,项目打包工具!所以,想必大家或多或少对webpack都有所了解或不了解也有所听闻。那么,webpack的作用又是什么呢?它又是怎样实现的呢?下面,我们由浅至深的来解析解析webpack。
*********初识
先举个例子,假如一个页面分为头部和内容区域,然后我们通过js来创建头部和内容区的标签。如果你用面向过程的思维方式的话,再加上项目更为复杂,一个js页面将会出现很多繁琐的代码,给维护也带来了不利。为了解决以上问题,面向对象得到了青睐,所以我们用面向对象的方法构建项目目录如下:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="webpack"></div>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
header.js
function Header() {
console.log('创建header')
}
export default Header;
content.js
function Content() {
console.log('创建content')
}
export default Content;
index.js
import Header from './header';
import Content from './content';
new Header();
new Content();
如果不清楚es module引入,commonJs,AMD,CMD的朋友可以去了解了解相关的知识。
很多使用过vue,react的同学对import的模块引入应该是见怪不怪了。那么我们打开index.html看看控制台是否如愿console出我们想要的结果。
纳尼?!报报报报错了。。。
“这么简单的html也报错,你行不行啊”,“下去啊下去啊,滚下去啊”,众人起身,拿着香蕉鸡蛋仍向了台上的我,我留下了悔恨但也委屈的泪水。一位老者走来问到:“bug,你为什么哭泣,这不是你的错,这是浏览器不支持import罢了。”
好,回到现实生活中,那位老者说到了,浏览器不支持import的模块引入,那么怎么办呢?删代码走人吗?
webpack闪亮登场!!!!!
“灯光得打足了!场景得布置好了!”,“等等等等,导演,这webpack刚来我们也不知道怎样去搭配适用得场景啊。”,我听了,心想:“说得也有道理”,回复到:“没事,很简单”。
webpack是应node而生,所以首先你得在电脑上安装上node,然后安装上webpack-cli,在安装webpack-cli的时候也会默认的为你安装上webpack,webpack-cli的最基本的作用就是能让你在命令行中如愿的适用webpack。
在安装node和webpack的时候尽可能的安装稳定版本中最新的版本,有位高手说过,webpack4配上最新的稳定node,打包速度会比webpack3快上90%。至于到底说没说过以及又是谁说的,你们也别去验证了。。。还有,在安装webpack的时候具体是全局安装还是项目内部安装由你自己决定,个人更推荐项目内部安装,因为不确定每一个项目的配置都是webpack4嘛。
那么回到刚才的demo中,既然说到webpack可以解决到浏览器不支持import,那么怎么解决呢?
- 进入项目根目录打开命令行。
- 输入npx webpack index.js
通过上面两个步骤后,项目根目录中会多出一个dist文件以及文件中的main.js,如下:
那这个main.js就是webpack将模块打包到一起产出的文件。听说你小子就能解决页面报错是吧,那我index.html就先抛弃index.js来引入你试一试吧。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="webpack"></div>
<script type="text/javascript" src="./dist/main.js"></script>
</body>
</html>
运行!
果然,控制台如愿的console出了我们想要的内容。
到这里,那么好(duo)问(shi)的朋友就会问了,难道我们只能这样使用webpack吗,我们不能DIY吗,我们想要配置自己的风格呢。。。可以的,没毛病,那么下面讲讲webpack的基础配置。
webpack的配置
想必使用过vue的同学都有在build发现webpack.config.js这个文件,没错,它就是webpack的配置文件,那么这个配置文件必须这样命名吗,其实不是的,我们后面会讲到。那我们就在刚才的demo项目中创建一个webpack.config.js并写上这样一段内容:
const path = require('path');
module.exports = {
entry: {
main: './index.js'
},
output: {
filename: 'bundle.js',
path:path.resolve(__dirname, 'dist')
}
}
这段内容是什么意思呢?首先语法是commonJS的语法,entry是入口文件,意思就是我webpack从哪个文件来构建项目依赖图,output就是关于项目打包后的输出,filename是模块打包后输出文件以什么命名呢,path则是项目打包后放在那个位置,path也可以不写,如果不写的话webpack也会默认为根目录中的dist。
然后我们打开命令行输入npx webpack,这个时候就不用再在命令行中去指定具体的文件了,因为已经在配置文件中配置好了,输入命令行,敲回车,大家也会看到跟之前一样的结果dist->main.js。那刚才我说了,配置文件并不少必须以webpack.config.js命名,那么怎么自定义命名呢?
你只需要在命令行中输入npx webpack --config xxxx.js,这样你就可以自定义命名配置文件了。
那么又有多事哦不好学的朋友会问平时看到的项目打包不是这样的啊,是npm run build啊,对哈,我还可以用npm run bundle,npm run dabao来打包呢,那这是怎么实现的呢?在项目初始化npm init后会发现多处一个文件package.json,在script下面写上:
{
"name": "webpack_demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"bundle": "webpack"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack-cli": "^3.3.12"
},
"dependencies": {
"webpack": "^4.44.0"
}
}
scripts脚本下的内容是告诉你通过npm run 加上下面的属性会执行怎样的功能,所以npm run bundle就会执行webpack的打包功能,这个时候你需要注意你的配置文件的名字是否是默认webpack.config.js,不是的话需要npm run bundle --config xxx.js来打包。
loader
webpack默认只会编译打包js文件,而如果项目中包含非js文件的话肯定就会报错,它会告诉你这个非js文件它不会打包。而loader则就起到了引导作用,它会告诉webpack你放心打包,你不会的我会教你。例如:
loader需要放在module -> rules里面。
上面图片中我们就配置了loader,这个loader的意思是告诉webpack当遇到以jpg,png,gif为后缀名的文件时以file-loader的方法来打包,这样就避免了webpack默认只会打包以js为后缀的文件而报错。
就file-loader进行一个扩展,还有一个url-loader,大家可以把file-loader换成url-loader进行打包后看看效果。大家应该看到当我们用file-loader进行好命名配置以及打包后文件位置配置后,大家会如愿的看到文件出现在了相对应的位置,而以url-loader打包后则在自己配置的文件看不到相应的文件,那么文件去了哪里呢?打开dist下面的bundle.js(这里需要看你对打包配置输出文件名是否为bundle.js,不是就看你自己配置的文件名)。往下滑大家可以看到一串base64的字符串,这就是使用url-loader打包后将图片直接放在了bundle.js上而不会放到我们设置的位置。那么这两个又有什么区别呢?如果图片很大的话,我建议用file-loader来打包,如果图片很小的话就可以用url-loader来打包,因为不会出现因图片太大页面加载过慢出现长时间白屏。那么怎样来切换file-loader和url-loader的使用呢?
图片中loader配置的意思就是如果要打包的图片大小超过了10kb,那么就用file-loader打包,并放到images文件夹下,如果小于10kb,那么就直接用url-loader打包并把base64字符串放到bundle.js里面。
当然loader肯定不止这一些,还有很多loader,所以大家在使用的时候要配置webpack文档来使用。webpack loader
如果同时使用多个loader大家需要记住loader的执行顺序是由下到上,由右到左。
plugin
使用过vue和react的同学应该对生命周期很熟悉了,而plugin的使用则跟这个有点类似,plugin就是在打包过程中的某个时间点执行一些特定任务,从而使我们更轻易简单的达到我们想要的打包结果。
拿clean-webpack-plugin来举例(这个插件不是官方推荐的插件,是一个第三方插件),我们想要的效果的在我们每一次执行npm run bundle打包的时候会把前一次打包的dist自动删除掉。代码如下:
先要下载我们要使用的插件,然后在plugins中去实例化。上图中的plugins配置的意思就是在下次打包前将自动删除掉dist文件夹。当然,webpack还有很多很方便的插件,不建议一个一个挨着去看,当你需要什么功能的时候可以到百度,google去查询webpack相应的插件再来看看如何配置使用。webpack plugins
好了,关于webpack的初始就写到这了,静候webpack的核心概念吧!