前言
很多小白朋友应该都听过vite、webpack等,其实每天都在用但是自己并不清楚,那么今天,一文带你彻底了解webpack。
webpack
如何理解
假设我们现在有一份html还有一份js,把js拿到html中使用我们可能会用script标签以CDN的方式引入,如果我们用的是vue、react等框架去开发,js可能会有成千上百个,那么每次我们创建xxx.vue/xxx.jsx文件 都要手动引入,还要考虑哪个先生效,哪个后生效,包括后续的上线打包压缩,这些繁琐操作要我们自己干也可以,但是很麻烦。
我们只希望现在有一份html还有一份js,不需要我们引入,他自己就能完成,此时就需要构建工具来完成。
webpack官网:webpack
可以看到,他能够将js文件等等各类依赖模块打包成静态资源,目前,webpack依旧是企业中使用最多的工具
接下来我们来实操。
实操演练
目录结构:
npm init -y // nodejs项目初始化
npm i webpack webpack-cli // 安装依
add.js
export const add = (a, b) => a + b
main.js 注意add.js js后缀要写全,平常我们在vue、react中引入时不需要是因为构建工具帮我搞定了
import {add } from './tools/add.js' console.log(add(1,2));
那么接下来,我们就希望有构建工具帮我们把这份main.js引入到index.html中,我们已经下载了webpack的源代码,接下来就是把他用起来,根目录创建webpack.config.js
。
这个文件怎么写呢,看官方文档。
步骤
我们只需要搞明白圈起来的这5个概念,搞明白了你就学会了,但是学会了不等于你精通了。其中loader和插件会稍稍麻烦些。
-
那么首先,就需要设置一个mode模式,是开发环境还是线上环境,我们当前设置为开发环境development。
-
设置入口,即当前项目的入口文件是谁,我们将其设置为main.js
-
设置出口,打包完了之后叫什么,放在什么位置,通常是dist
const path = require('path') module.exports = { mode: 'development', entry:{ main:'./src/main.js' }, output:{ path:path.resolve(__dirname,'./dist'), filename:'js/chunk-[contenthash].js' } }
刚刚说的5个概念,现在已经了解了3个,接下来我们先来跑一下,首先npx 启用一下webpack这个命令,他会自动帮你跑webpack.config.js这个文件。
npx webpack
现在我们能够看到根目录下帮你打包好了,创建了dist文件夹,下面有chunk-xxxxx.js,我们要把这份打包好的js应用到html中,这就完成了我们的目的。
如果我们手动引入,那就是script标签引入,然后打开这份html后我们势必能看见控制台打印了3
index.html
<!doctype html> <html lang="en"> <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>Document</title> </head> <body> <h1>hello world</h1> <script src="../dist/js/chunk-5198ac7c775e23c5b00d.js"></script> </body> </html>
存在的问题
缓存
此时一个问题出现了,浏览器存在缓存
试想,实际开发中,很多资源都是会做强缓存协商缓存等等,那么假设我们把add函数修改了,填了一些新的东西,然后重新打包,此时就会生成一个新的dist下的chunk-xxxhash值.js 打包文件,我们在html中script标签中重新引入。
如果我们没有更改文件名,那么由于缓存的存在打印的还是3,我们添加的东西不会生效,这就是为什么我们在创建dist下的打包文件时,用一个唯一的hash值来取名,然后引入一份新的打包文件。
删除无效文件
接下来我们考虑下一个问题,打包一次,创建一个文件,打包多了dist下面就多了很多没有用的曾经的打包文件,因此我们要删除clean
const path = require('path') module.exports = { mode: 'development', entry:{ main:'./src/main.js' }, output:{ path:path.resolve(__dirname,'./dist'), filename:'js/chunk-[contenthash].js', clean:true } }
运行指令
曾记否,我们都习惯npm run dist、npm run build这样的指令来做打包,因此我们可以做一下配置 package.json
{ "name": "webpack", "version": "1.0.0", "description": "", "main": "src/main.js", "scripts": { "build":"npx webpack", "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "webpack": "^5.96.1", "webpack-cli": "^5.1.4" } }
自动引入
上面都是我们手动重新引入,这样很麻烦,回到最开始说的,如何自动引入这份打包好的js到html中呢?
这就需要webpack能读懂html,否则如何修改html中的script标签并做引入呢引入到什么位置呢?但是是事实webpack能读懂js不懂html
因此,官方打造好了一个插件HtmlWebpackPlugin,一个东西刚打扫出来都是很纯粹的,拥有自己的基本能力,但是接下来的东西就需要不断拓展,这就是插件
npm install --save-dev html-webpack-plugin
配置webpack.config.js
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry:{ main:'./src/main.js' }, output:{ path:path.resolve(__dirname,'./dist'), filename:'js/chunk-[contenthash].js', clean:true }, plugins: [new HtmlWebpackPlugin({ template: './public/index.html', // 读懂哪份html filename: 'index.html', // 文件名是什么 inject: 'body', // 注入到哪个位置 })], }
接下来我们删除我们在index.html中手动引入的script标签,重新跑一遍打包,看看他是否帮我们自动引入了
<!doctype html> <html lang="en"> <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>Document</title> </head> <body> <h1>hello world</h1> </body> </html>
可以看到,它自动帮我们引入成功了,并且加上了defer,不阻塞页面的渲染
loader
至此我们已经介绍完4个概念了还剩下最后一个loader
我们也来体验一下。
如果我们想在main.js中引入一份css
import {add } from './tools/add.js' import './styles/index.css' console.log(add(1,2)); console.log(add(2,3)) console.log('hello world')
然后我们去执行打包,就会发现会报错,原因就是还是那样只能读懂js,不懂css,他会告诉你你需要一个loader来操作这个css类型的文件
官方打造了css-loader
注意一定要装style-loader,css-loader是为了读懂css,后面是为了让css能写入到html中。
npm install --save-dev css-loader style-loader
配置
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry:{ main:'./src/main.js' }, output:{ path:path.resolve(__dirname,'./dist'), filename:'js/chunk-[contenthash].js', clean:true }, plugins: [new HtmlWebpackPlugin({ template: './public/index.html', // 读懂哪份html filename: 'index.html', // 文件名是什么 inject: 'body', // 注入到哪个位置 })], module: { rules: [ { test: /.css$/i, use: ['style-loader', 'css-loader'], }, ], }, }
原文链接:https://juejin.cn/post/7433603120477339683=