webpack学习笔记(一)

194 阅读5分钟

首先安装webpack

yarn global add webpack@4.41.2 webpack-cli@3.3.10

之后创建一个webpack-demo,并进入这个文件

安装它的两个依赖

npm init -y
yarn add webpack webpack-cli --dev

安装完成之后,就会多一个node_modules目录

接下来,分成几个小目标,逐步完成它们,从而学习webpack

目标一:用webpack编译JS

在webpack-demo中创建一个src文件夹,并在这里创建一个index.js文件,里面输入console.log('hi')

QQ图片20211229205309

运行webpack,
由于webpack只是局部安装,所以需要指定在哪里去找webpack的执行程序

 ./node_modules/.bin/webpack

除此之外,还有一种简单的方法

npx webpack

npx会自动找出webpack在本地的哪个位置,但是这种方法有时候不太稳定

当我们运行了之后,就会发现webpack-demo中多出了一个dist文件夹,里面有一个main.js文件

QQ图片20211229205859

点开main.js之后,会发现里面有console.log('hi')

QQ图片20211229210350

试试稍微复杂一点的状况,现在src目录下创建一个x.js文件,写入

export default 'xxx'

之后,更改index.js的内容

import x from './x.js'
console.log(x)

再次运行webpack,得到一个新的main.js

QQ图片20211229210922

这里会得到console.log("xxx"),至此我们发现一个问题:

在index.js文件中console.log(x)中的x,实际是从x.js中引入的,而x.js只导出了xxx三个字符,所以实际上最后打印出的就是xxx三个字符,

于是webpack敏锐的发现了这一点,它就直接的打印出了xxx这三个字符

也就是说webpack会分析JS代码,然后把JS代码变成IE或者更低版本浏览器可以用的JS,而main.js中前面的一大串代码,是兼容代码,是为了保证import,require等代码可以运行而写得代码 ————————————————————————————————————————————————

在做这些操作时,一直有一个警告

QQ图片20211229211942

意为mode没有被设置,

于是,我们在webpack-demo下创建一个webpack.config.js文件,并在里面写入

module.exports = {
    mode: "development",
    }
}

再次运行webpack,并点开新的main.js,会发现main.js大不一样

QQ图片20211229212613

这个development模式,就是开发者模式

而之前使用的模式默认是production模式,是生产者模式,是直接给用户使用的

目标二:理解文件名中的hash的用途

先给webpack.config.js添加一些东西

const path = require('path');
module.exports = {
    mode: "development",
    entry: './src/index.js',//默认入口
    output: {
        path: path.resolve(__dirname, 'dist'),//默认创建出口的目录
        filename: 'index.js'//出口名
    }
}

删除之前的dist文件,再次运行webpack

会得到一个新的dist文件,里面有index.js

20211229232052.png

这样,我们就大概清楚了它的入口和出口的一些配置 ————————————————————————————————————————————————

更改上述文件中的 filename: 'index.js'filename: '[name].[contenthash].js'

再次运行webpack,就会得到一个文件名很复杂的文件

QQ图片20211229222421

为什么会创建这么一个文件?

这与HTTP缓存有关

HTTP缓存

比如去访问baidu.com

  • 假设它会给我们返回一个index.html(首页)
  • 这个index.html会去加载1.css,2.css,3.js,4.js…,并就把这些文件缓存
  • 当我第二次访问baidu.com时,
  • 它就不会再去加载这些文件,
  • 这时,只需要下载index,html(首页),它会去从内存(或硬盘)之中得到1.css,2.css,3.js,4.js…
  • 这么一来,就能加快访问速度

QQ图片20211229215805

图中可以看出,缓存的文件可以不费时就完成加载

QQ图片20211229215912

而禁用缓存,加载每个文件就会耗费一些时间

取消禁用缓存,我们点开一个JS文件,查看它的响应头

QQ图片20211230105141.png

可以看到它的cache-control:max-age-25920000
这串数字的单位是秒,换算成天就是300天,
也就是说300天之内,再次访问baidu.com时,不需要重复下载这个文件

这就是缓存的作用

现在有一个问题,如果百度要更新这个JS文件怎么办?

很简单,因为缓存是跟着文件名走的,所以只要改了文件名就好了

QQ图片20211229221703.png

更改文件名

怎么改文件名?

只要对文件内容做一个哈希就可以,webpack就会自动做这么一件事

做一个简单的实验,我们再更改了上述的filename之后,对index,js做一点简单的改动

import x from './x.js'
console.log(x)
console.log('hi')

再次运行webpack

QQ图片20211229222324

就会得到一个新的以main开头的文件

所以只要每次发布,内容不一样,文件名就会跟内容有一一对应,(可以理解为不同文件名对应不同版本)

这样在重新发布时候,根据文件名不同,浏览器就知道要更新一个新的文件,之前的缓存也就作废了

这里可以看出上述更改的filename的意义,就是产生一个新的哈希

但是首页不能缓存,如果首页都缓存了,就没办法更新里面的文件内容了

—————————————————————————————————————————————

在图中可以看到,每次重新webpack都会生成一个新的文件,为了不让文件增加,需要更改一下webpack-demo里的package.json文件

{
    ...
    "scripts": {
        ...
    	"build": "rm -rf dist && webpack", 
   		...
  },
    ...
}

加上这么一句,这样每次需要打包的时候,直接运行yarn build,它就会删除之前的dist文件,重新webpack

目标三:用webpack生成HTML

首先安装html-webpack-plugin

yarn add html-webpack-plugin@3.2.0 --dev

再次更改webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: "development",
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].[contenthash].js'
    },
    plugins: [new HtmlWebpackPlugin()]
}

运行yarn build,会发现dist里多了一个index.html文件

20211229224919

点开这个文件,可以看到生成了一个空的html,这个html自动引用了dist里的main.xxxxxxx.js

QQ图片20211229225058

且每一次更新JS,再次打包,生成新的JS文件,这里面引用的JS文件也会自动更新

—————————————————————————————————————————————

但是这个html文件里面,不能随便加东西,加了之后下次打包加的东西就不见了

这里,需要再次更改webpack.config.js里的plugins

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
	...
    },
    plugins: [new HtmlWebpackPlugin({
        title: 'My App',
        template: "src/assets/index.html"
    })]
}

并在src文件夹中,创建assets文件夹,assets里创建index.html文件

进入这个assets/index.html文件,将其初始化

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
  <!-- 根据配置里的title生成 title-->
	<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="app"></div>
</body>
</html>

再次yarn build

完事之后,进入dist/index.html,就会发现这个文件的title为My APP,且在这个文件的body里也有一个id为app的div

用这个的方法,就可以往dist/index.html里添加东西