接下来这几章,我们就和webpack死磕到底。学之前,还是我们的经典三问
- webpack是什么吗
- 为什么要学webpack
- 怎么学webpack
webpack是什么吗?
先来个权威解释
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
--webpack官网
通俗解释
webpack是一款模块加载器兼打包工具,它能把各种资源,都作为模块来使用和处理。开发的时候我们可以使用模块化来开发,开发完成后webpack可以帮我们解析出模块之间的依赖,把代码打包成浏览器可识别的普通代码
为什么要学webpack?
- 从狭义上来讲webpack是一门前端必备的技能,了解和学习webpack是一个前端工程师的标配
- 从广义来讲学习webpack是一种思维上的晋升,是让自己具备工程化思维,拥有对整个前端架构的把控能力
- 个人认为
对webpack的理解,是一个初级前端工程师迈向中级前端工程师的关键
怎么学webpack?
如果说学习其他技术核心是多练,那学习webpack的核心就是多想。不满足与现状,通过对webpack的配置改变原有项目的各种槽点,是学习webpack的捷径
下面就让我们整二两好酒,弄几个小菜,搭配着这篇新鲜刚出炉的文章一起食用吧!
webpack初次偷窥
安装webpack
一下代码及操作均以webpack4为例
局部安装
新建一个文件夹,在文件夹执行
npm i webpack webpack-cli -D // 检查是否安装成功 webpack -v webpack-cli -v
全局安装
npm i webpack webpack-cli -g //一些简写说明 -d == --save-dev -s == save -g == global
推荐使用局部安装,防止在一台电脑上要同时运行两个不同版本的webpack项目
完成一个小目标
弄一个小项目, 可以npm run dev 运行项目,可以npm run build 打包项目。项目文件包括
- js文件
- css文件
- 图片资源
webpack约会开始
初始化package.json文件
package.json 文件是对项目或者模块包的描述可以通过 npm init 得到这个文件
安装webpack,webpack-cli
使用命令
npm i webpack webpack-cli -D
这时,我们的项目文件是这样的
+ node_modules + package.json
新建css文件,js文件和图片文件,并把它们放在对应文件夹
─package.json ├─src | ├─index.html | ├─js | | └index.js | ├─img | | └baidu.png | ├─css | | ├─base.css | | └init.css
一切准备就绪,开干!
我们说过,学习webpack的核心就是要多思考,我们要实现什么功能先给自己定个详细的计划!
实现两个环境dev,和build,其他的先什么都不管!(计划是不是很详细,哈哈)
配置webpack.config.js文件
webpack没有智能到我们说什么它就做什么的地步,很多配置都需要我们自己写
新建文件夹 webpack.config.js
先来看看webpack几个核心的概念
- 入口(entry)
- 输出(output)
- loader
- 插件(plugins)
入口(entry)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
webpack中文网
entry可以配置多个,这里我们就配置一个入口
module.exports = { entry: './src/js/index.js', }
输出(output)
就是我们打包后要输出的文件,包括文件名称和文件路径
const path = require('path'); //path包 module.exports = { entry: './src/js/index.js', //入口 output: { //输出 filename: 'bundle.js', //文件名字 path: path.resolve(__dirname, './dist'), //文件路径 } }
配置完这两个,我们的webpack就可以工作了在命令行输入
webpack
可以看到webpack打包成功且自动成功打包后的文件夹dist和bundle.js文件
但是我们通常用build命令来打包,那就需要我们设置package.json文件
{ "name": "webpack-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack" }, "author": "", "license": "ISC", "devDependencies": { ... } }
只要在scripts里面加上build命令即可
webapck.config.js的其他配置我们先放一放,现在我们的webpack已经可以在build环境下正常工作了,现在让我们设置下dev环境
dev环境设置
dev环境就是开发环境,首先我们要安装一个重要的包,这个包可以帮助我们启动一个服务并实现热更新
+ webpack-dev-server //使用npm i webpack-dev-server -D 安装
配置package.json文件
{ "name": "webpack-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack", "dev": "webpack-dev-server --open" }, "author": "", "license": "ISC", "devDependencies": { ... } }
加--open 是为了在执行npm run dev开启服务时自动打开浏览器
现在我们在index.js文件写一句测试代码
alert('webpack')
然后打包生成dist文件,index.html中引入bundle.js
Document
打开浏览器,效果正常显示
但是如果我们在dev环境下也引用build后的js,势必不能实现热刷新,且每一次更改都需要打包后看效果
在dev环境中,其实webpack也给我们生成bundle.js文件,只不过它在内存中,没有显示出来,
更改index.html引用的js路径
Document
这时,我们发现一切又正常了,热刷新也好使
但问题有出来了,我们总不能在切换环境的时候总是手动更改js引入路径吧
车到山前必有路,又一个插件上场啦
+ html-webpack-plugin
plugin是用于扩展webpack的功能,各种各样的plugin几乎可以让webpack做任何与构建先关的事情
html-webpack-plugin干的就是可以生成创建html入口,且为html文件中自动引入的外部资源
使用起来也是非常的简单
const path = require('path'); const HTMLWebpack =require('html-webpack-plugin'); //引入插件 module.exports = { entry: './src/js/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, './dist'), }, plugins:[ // 使用插件 new HTMLWebpack({ template:path.resolve(__dirname,'./index.html') //index.html模板路径 }) ] }
这时候我们npm run build的时候dist里面又多了一个index.html文件
且对应的给我们自动引入了js文件
Document
不得不说,这简直是造福人类啊
到现在,我们这两个环境分别可以正常运行,且完全自动,美滋滋
配置loader
说webapck自动其实离不了各种loader的使用,没有loader,webpack什么都做不了
比如我们给我们的页面写点css
// init.css body,html{ padding: 0; margin: 0; }
// base.css body{ background: pink; }
在index.js中引入
我们发现会报错,需要对应的loader去处理对应的文件
安装loader
+ style-loader + css-loader
书写配置文件
const path = require('path'); const HTMLWebpack =require('html-webpack-plugin'); //引入插件 module.exports = { entry: './src/js/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, './dist'), }, module:{ rules:[ { test: /.css$/i, //规则 正则匹配css文件 use: [ "style-loader", //使用的loader "css-loader", ] } ] }, plugins:[ // 使用插件 new HTMLWebpack({ template:path.resolve(__dirname,'./index.html') //index.html模板路径 }) ] }
这时我们在运行代码,渴望已久的pink背景终于出来啦
这时,我们希望在加些背景色
body{ background: url("../img/baidu.png") no-repeat center center;}
又报错了,看来图片也需要用loader处理呢
安装loader
+ file-loader + url-loader
如法炮制
module:{ rules:[ // 处理css { test: /.css$/i, //规则 正则匹配css文件 use: [ "style-loader", //使用的loader "css-loader", ] }, // 处理图片 { test: /.(jpg|png|gif)$/i, use: { loader: 'url-loader', options: { outputPath: 'imgs/', limit: 2 * 1024 //小于2k的图片转换为base64格式的图片 } } }, ] },
url-loader需要依赖于file-loader,所有需要安装两个loader
这时一定要重新启动webpack
重启后,image is show
现在我们简易版的webpack配置基本结束,看一下现在的项目目录
最简单的配置,书写最核心的功能,非常适合拿来学习使用
需要源码的私信哦!
需要思考的几个问题:
- 输出的文件,能不能按照文件名称分类?
- 打包时css能不能和js能不能分开?
- 使用less,scss的时候怎么处理?
- dev和build(pro)两个环境有不同的配置时怎么处理?
希望大家持续关注哦!下一章会一一解答