为什么要有webpack
在没有webpack时,回忆我们是如何引入js文件的呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>为什么要用webpack</title>
</head>
<body>
<p>引入js文件</p>
<script src='./index.js'></script>
</body>
</html>
那如果引入很多js呢
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>为什么要用webpack</title>
</head>
<body>
<p>引入js文件</p>
<script src='./index.js'></script>
<script src='./a.js'></script>
<script src='./b.js'></script>
<script src='./c.js'></script>
</body>
</html>
这样的缺点显而易见
1、如果都放在一起引入,增加了js文件请求,页面加载会变得缓慢
2、如果定义了相同变量或报错根本不知道从何查找
于是有了各种模块引入方式,例如ES Moudule
//index.js
import A from './a.js';
new A();
//a.js
function A() {
//do something...
}
export default A;
以下的前提是是已经安装了node npm webpack
实际上浏览器是不认识import、export default是什么东西的,那最终是引入并生效的呢,这就是webpack的功劳了,它把这些模块识别出来翻译成了浏览器所认识的语言,那我们有了初步的认识,“webpack是个js翻译器!”,nonono~so young so simple,其实他也就认识一点点而已,他只是识别出了这是一个模块,然后把它们打包到一起去,最终我们只需要引入打包后的那个文件就可以了
除了ES Moudule的引入方式还有其他的引入方式,例如CommonJs:var a = require("./index")、CMD、AMD等等
由此我们引出了模块的思想,模块真是个好东西啊,解决了我们不少麻烦,了解模块推荐webpack的文档[https://www.webpackjs.com/concepts/modules/#%E4%BB%80%E4%B9%88%E6%98%AF-webpack-%E6%A8%A1%E5%9D%97]
图片占位模块1
我们继续webpack的了解,从实际例子开始
创建一个文件夹webpack-file
终端进入文件夹 执行npm init命令,发现文件夹下生成了一个package.json文件,npm init就是把你的文件夹初始化成node要求的标准
然后我们安装webpack-cli,我建议在文件内局部安装,而非全局安装,假设我们全局安装后,有两个项目,一个是webpack版本3一个是4,那我们全局安装了一个版本3的,就会导致另一个项目运行不起来
//局部安装
//进入当前文件目录下再安装
npm install webpack webpack-cli --save-dev
//上面和下面是一个意思
npm install webpack webpack-cli -D
这里遇到一个问题,当安装完之后有的小伙伴可能习惯性去webpack -v检查一下是否安装成功,安装的是什么版本,但是却没有检查到,这并不一定是安装失败了,而是检查版本时会默认查找全局安装版本,局部安装可能就不会成功看到版本,node提供了方法,可以用下面命令查看局部安装版本
npx webpack -v
当你拉了一个别人的项目时,通常不会拉到安装的webpack生成的node_modules,而需要npm install一下才会生成
我们还用最开始的例子来打包,执行npx webpack index.js就可以打包好一个简单的项目,这个命令的意思是把index.js作为入口文件,从index.js开始进行模块打包,但是你会发现只执行npx webpack也可以打包成功啊,因为webpack在不断优化,他会做很多操作,将index.js作为默认入口文件,webpack也并没有逆天到可以直接找到你的入口文件,所以我们应该配置一个webpack配置文件,告诉webpack你需要的东西我放在哪个文件里了
webpack的默认配置文件叫做webpack.config.js,当然,你也可以换名字,可以但是没有必要啊,但是你就要换非要换,也是可以的,执行下面命令 将yourconfigname.js作为你的默认打包配置文件
npx webpack --config yourconfigname.js
这样就可以在yourconfigname.js中配置你的webpack文件了,以下我们还是用标准的webpack.config.js文件来配置
然后我们来配置我们自己的webpack.config.js
//webpack.config.js
//先写一个入口,把./index.js作为我们的入口文件,使用的是相对路径
module.exports = {
entry:'./index.js'
}
其实这种入口方式是一种简写,完整版的应该是
module.exports = {
entry:{
main:'./index.js'
}
}
有了入口,还要把打包好的文件输出到某个文件夹下,再配置一个出口文件
module.exports = {
entry:'./index.js',
output:{
filename:'bundle.js'
}
}
这时候再执行npx webpack,就会看到目录下生成了一个dist文件夹,dist文件下多了个bundle.js文件,这就是打包后的文件了
dist是默认的文件名称,那我不想叫dist,我也不想叫bundle,怎么办呢,先删掉dist文件夹
const path = require('path')
module.exports = {
entry:'./index.js',
output:{
filename:'myBundle.js',
path:path.resolve(__dirname,'myDist')//绝对路径
}
}
这里初学者绝对会有疑问,后面这一串是什么鬼东西,因为我当时就是这么想的,首先path后面是绝对路径,我们要引入path,就是第一行的内容,然后接受node内的参数__dirname,把myDist混入进去,这样就可以指定文件夹名,文件名只要更改filename就可以了
再执行npx webpack就可以看到生成了一个myDist文件下里面有个myBundle.js文件了
学习过vue的伙伴可能会想,平时打包的时候或者运行的时候也没有用过npx webpack这种方式啊,确实是这样的
还记得我们最开始安装的是webpack-cli么,如果没有安装webpack-cli,是不可以直接执行npx,webpack这两种命令的
因为我们是自己手写的简陋的代码,那其他框架中直接运行的npm run xxx等等的是从哪里来的呢
我们来看package.json文件
//package.json
{
"name": "webpack-file",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
看这个scripts,就是他,当我们执行npm run xxx时,就会到package.json下的scripts去寻找xxx,例如他给的这个test,我们执行命令npm run test,就会输出后面的报错了,改一下命令,改成我们想要的打包命令
{
"name": "webpack-file",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
},
"devDependencies": {},
"scripts": {
"bundle": "webpack"
},
"author": "",
"license": "ISC"
}
执行npm run bundle 就会打包了,实际上执行的是 webpack,但是之前不是说局部安装的不能用webpack么,要不要写成npx webpack呢,这么看的时候,他会从项目内部开始找webpack而不是从全局开始找了
举一反三,看看你的项目中npm run dev执行了什么吧~
细心的同学打包时候还会发现这样一段警告
图片占位2
没有设置mode,但是只是警告而不是报错,因为webpack会默认设置为production,我们手动设置一下就不会再报警告了
const path = require('path')
module.exports = {
mode:'production',
entry:'./index.js',
output:{
filename:'bundle.js',
path:path.resolve(__dirname,'dist')
}
}
看一下打包后的文件
图片占位3
是被压缩成一行的代码,我们试一下另外一种模式development
图片占位4
区别很明显,一个被压缩了 一个没有被压缩,这就是两种模式的简单区别
这样再去结合webpack规范的文档看一下起步内容效果更佳[https://www.webpackjs.com/guides/getting-started/#%E5%9F%BA%E6%9C%AC%E5%AE%89%E8%A3%85]