webpack4小白学习全过程记录

30次阅读

共计 9884 个字符,预计需要花费 25 分钟才能阅读完成。

webpack:现代 JavaScript 应用程序的静态模块打包器
前言:本文描述一个小白学习 webpack4 从零开始的完整过程全纪录,可以说完全以一个初学者的口吻来写这篇文章的,与此同时这篇文章还会长期更新,不足之处还望大佬雅正!
大白话讲 webpack
对于小白来说,看到一些专业的术语就脑壳疼什么是 webpack? 简单来讲,就是把我们写好的代码打包。怎么个打包法,压缩代码,相同资源抽取,处理一下浏览器不识别的代码(如 ES6+、TS、SASS 等)。一句话,用不到就扔掉,能压缩就压缩,能兼容就兼容
初探 webpack
①、安装 npm
npm 是世界上最大的软件注册表,使用 npm 我们可以快速安装各种大小型软件和库下载:在 node.js 中都自带了 npm,所以我们下载 node.js 即可 node.js 官网:https://nodejs.org/en/ 下载完后,我们可以在 dos 命令行下可以看到 node.js 的版本和 npm 的版本 node -v npm -v
②、建好目录架构
①、新建练习文件目录 ex1①、在 ex1 目录下新建源文件目录 src②、在 src 目录下新建入口文件 index.js 形成的目录结构如下:
③、初始化 package.json
package.json 文件定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。在 ex1 目录下使用命令:
npm init -y
init 指令会询问一系列的问题,并将你的配置写成一个 package.json 文件。如果使用了 -f|–force|-y|–yes 这些参数,那么会生成一个默认的 package.json 文件。这个 init 过程很快,可以看到在 ex1 目录下多了个 package.json 文件
④、安装 webpack
提示:webpack4.0 以上版本的 webpack 的脚手架 webpack-cli 已经被分离出来,需要另外安装。安装 webpack 分为全局安装和本地安装(局部安装)
全局安装(不推荐) npm install webpack webpack-cli -g (- g 就是全局安装) 本地安装 npm install webpack webpack-cli -D (-D 就是安装到开发环境)
安装成功后如图所示:
再来看下我们的文件目录发生了什么变化:node_modules 文件夹主要是用于放用包管理工具下载安装了的包,这个文件的内容有很多 package-lock.json 锁定了包的版本,确保能够避免包版本不同产生的问题。
⑤、使用 npx 进行打包
npx 会帮你执行依赖包里的二进制文件。npx 会自动找到 node_modules/bin 的 webpack.cmd 去执行,免去了 script 的配置
在 src 的目录下新建一个名为 demo1.js 的文件
在 demo1.js 中写入如下内容
module.exports = ‘ 这是 common.js 的语法,在 node 端运行, 把我用 webpack 打包之后,就可以在浏览器上运行了 ’
在 index.js 中写入如下内容
let d1 = require(‘./demo1.js’);
console.log(d1);
使用命令进行打包
npx webpack

结果如图:
打包后我们可以发现在 ex1 目录下多了个 dist 文件夹这个 dist 文件夹中有个 main.js 文件,是打包后的 js 文件
为了查看结果,我们可以在 dist 目录下新建一个 index.html 文件在 index.html 使用 script 标签引入 main.js <script src=”./main.js”></script> 在控制台里面就可以看到这么一句话:’ 这是 common.js 的语法,在 node 端运行, 把我用 webpack 打包之后,就可以在浏览器上运行了 ’
细心的你可能会发现上面打包的结果有一个 黄色的警告
WARNING in configurationThe ‘mode’ option has not been set, webpack will fallback to ‘production’ for this value. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for each environment.You can also set it to ‘none’ to disable any default behavior. Learn more: https://webpack.js.org/concep…

黄色警告意为 webpack 没有指定是开发模式 development 还是 生产模式 production 那我们就可以在命令后面加上 –mode development 看,是不是没有了黄色警告提示。
npx 的缺点:虽然使用 npx 可以快速的帮我们打包,但是不够灵活,比如打包后文件夹名字都是固定 dist,因此我们需要定义 webpack 打包的配置文件,这样才可以随心所欲的打包
webpack 配置
①、新建配置文件
我们现在 ex1 的目录下新建一个名为 webpack.config.js 文件
由于 webpack 是基于 node,所以要遵循 common.js 规范
②、入口(entry)
入口起点 (entry point) 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。entry 属性的单个入口语法
module.exports = {
entry: ‘./src/index.js’
};
③、出口(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件。默认值为 ./dist。
在 webpack 中配置 output 属性的最低要求是,将它的值设置为一个对象,包括以下两点:

filename 用于输出文件的文件名。
目标输出目录 path 的绝对路径。

④、入口和出口的整合
webpack.config.js
// 基于 node,遵循 common.js 规范
const path = require(‘path’) // 引入 node.js Path 模块
module.exports = {
entry: ‘./src/index.js’, // 入口
output: {
filename: ‘bundle.js’,
path: path.join(__dirname, ‘./build’)
}
}
由于 path 要求为绝对路径,所以我们使用了 path.join 拼接路径这个 node 的语法,
node 不能在浏览器端运行,所以我们可以利用 vscode 编辑器 的 Code Runner 插件来查看当前路径的结果在 webpack.config.js 保留如下代码:
const path = require(‘path’) // 引入 node.js Path 模块
console.log(path.join(__dirname, ‘./build’));
结果如图:
在 webpack.config.js 配置好出入口后,那我们可以尝试着打包了打包结果如图:在 ex1 的目录下多了个 build 文件以及其目录下的 bundle.js 文件那么说明了我们的配置是成功的!
⑤、npm 脚本
可以参考阮一峰老师的博客:http://www.ruanyifeng.com/blo…npm 允许在 package.json 文件里面,使用 scripts 字段定义脚本命令。npm 脚本。它的优点很多

项目的相关脚本,可以集中在一个地方。
不同项目的脚本命令,只要功能相同,就可以有同样的对外接口。用户不需要知道怎么测试你的项目,只要运行 npm run test 即可。可以利用
npm 提供的很多辅助功能。

在我们原有的 package.json 中,我们可以发现有一个这样 ”scripts” 字段
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1″
}
因此我们可以尝试使用 npm test 命令看下会有什么结果结果执行了 echo 语句
我们可以利用 npm 脚本来替代 webpack 语句,我们修改一下 test 字段对应为 webpack 命令
“scripts”: {
“test”: “webpack”
}
接着我们尝试使用 npm test 命令来运行一下可以发现我们已经打包成功了。
那么有的朋友就会问了,一定要 test 吗?好,我们随便来个命令,就 abc 在 test 字段下,我们加多一个 abc 字段,如下面代码所示:
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1″,
“abc”: “webpack”
}
执行 npm abc 命令看看结果怎样
哎,奇怪了呀,这是什么情况,有一点很明确的是,并没有执行 webpack 打包执行命令。不急不急,我们先来看下提示先:注意到这句话:where <command> is one of: 也就是说我们的命令应该下面那些,也就是说只能使用 npm <command>,这个 command 应该是提示其中之一,我们在提示中可以发现有 test 命令
也就是说只要满足了上面字段的其中之一,就可以使用 npm <command> 但是这些命令是 npm 自带的,并不是所有都可以用来执行 script 脚本的。除此之外,还有一个 start 命令也是可以直接执行的,如图
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1″,
“start”: “webpack”
}

那么问题来了,我们怎么知道哪些命令可以直接执行 script,要一个个尝试岂不是很麻烦吗?此时我们可以使用 npm run <command> 命令来直接执行脚本使用 npm run script 执行脚本的时候都会创建一个 shell,然后在 shell 中执行指定的脚本。所以这次我们不用再为使用什么 script 字段而烦恼了。好,我们再来试一下 abc 字段
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1″,
“abc”: “webpack”
}
哈哈,终于成功了!
⑥、模式设置
在之前我有讲到过,黄色警告是由于没有设置模式而出现,那时候提的方法是每次都要在执行打包的命令的时候加上这么一句 –mode development/production 那这样是不是很麻烦,所以我们可以在配置文件这样定义
mode: ‘development’
那么,此时我们的 webpack.config.js 的文件内容如下:
// 基于 node,遵循 common.js 规范
const path = require(‘path’) // 引入 node.js Path 模块
module.exports = {
entry: ‘./src/index.js’, // 入口
output: {
filename: ‘bundle.js’,
path: path.join(__dirname, ‘./build’)
},
mode: ‘development’ // 模式
}
此时,我们再打包试一下,结果如图:我们可清楚地看到黄色警告已经去掉了
webpack 入门
①、关系依赖
在我们的 package.json 文件里,可以看到这么一个字段 “devDependencies”
除此之外还有一个与之相关的字段叫“dependencies”
*devDependencies 与 dependencies 的区别

devDependencies 里面的模块只用于开发环境(development)而 dependencies 里面的模块是需要发布到生产环境(production)。比如我们有一个项目要用到 jQuery,在线上运行的时候如果没有 jQuery 包的依赖运行就会报错,这时候就应该把这个依赖写入 dependencies 而我们使用的一些构建工具如 webpack 这些只是在开发中使用的包,上线以后就和这些包没关系了,所以将这种依赖写入 devDependencies

在我们使 npm 安装模块的时候,都会使用一个命令
npm install(可以简写为 npm i)
与此对应的还有这两个重要的对应参数:–save (可以简写为 -S)–save-dev (可以简写为 -D)
①、npm install m

将 m 模块安装到 node_modules 目录中
不会修改 package.json
运行 npm install 命令时,不会安装 m 模块

②、npm install m –save:

把 m 模块安装到 node_modules 目录中
会在 package.json 的 dependencies 属性下添加 m 模块
运行 npm install 命令时,自动安装 m 模块到 node_modules 目录中

②、npm install m –save-dev:

把 m 模块安装到 node_modules 目录中
会在 package.json 的 devDependencies 属性下添加 m 模块
运行 npm install 命令时,会自动安装到 node_modules 目录中

②、本地服务器(devServer)
webpack-dev-server 能够用于快速开发应用程序里面包含了很多丰富的功能,其中最为重要的当然是能够监听本地代码的修改,利用热加载自动刷新浏览器,这样大大地方便了我们进行代码的调试
第一步:安装 webpack-dev-server 在前面,我有讲到关系依赖这方面的知识,关于 devDependencies 与 dependencies 的区别,相信大家都能看懂。很明显 webpack-dev-server 只是用来本地调试的,上线之后就用不上了,那么我们可以很明确将 webpack-dev-server 放到 devDependencies 中
执行如下命令:
npm install webpack-dev-server -D
安装好后,我们再来看一下 package.json 文件的变化
第二步: 配置 webpack-dev-server

配置项目
描述
注意

contentBase
告诉服务器从哪个目录中提供内容
推荐使用绝对路径。

compress
一切服务都启用 gzip 压缩
compress: true

host
指定使用一个 host。默认是 localhost
可以外部服务器访问

https
默认情况下,dev-server 通过 HTTP 提供服务
https: true

open
启用 open 后,dev server 会打开浏览器
默认浏览器,可以指定其他

port
指定要监听请求的端口号
默认 8080

其实 webpack-dve-server 的配置项目远远不止这些,这里只是列举了一部分
我们先在 package.json 中添加 script 脚本
“dev”: “webpack-dev-server”
①、contentBase 解析
再回来看下我们的 webpack.json.js 文件,webpack-dve-server 配置的字段为 devServer,我们先不配置先,看看会怎么样?此时 webpack.json.js 的内容
// 基于 node,遵循 common.js 规范
const path = require(‘path’) // 引入 node.js Path 模块
module.exports = {
entry: ‘./src/index.js’, // 入口
output: {
filename: ‘bundle.js’,
path: path.join(__dirname, ‘./build’)
},
mode: ‘development’ // 模式
}
执行命令:
npm run dev
看下结果:
现在可以清楚的看到,我们的项目已经运行在 http://localhost:8080 好的,那么我们在浏览器输入这个 url 看看这个页面会显示什么

如图所示:这里只显示了我们整个文件的目录
默认情况下,contentBase 将使用当前工作目录作为提供内容的目录为了证明这点,我们在 ex1 的目录下新建一个 index.html 现在的目录结构如下:
现在在根目录下的 index.html 写入如下内容:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>index</title>
</head>
<body>
这是根目录的 index.html
</body>
</html>
好,现在在重新执行命令 npm run dev 然后在浏览器打开 http://localhost:8080 页面我们就可以发现结果不同了
那么这就可以证明了默认情况下,contentBase 将使用当前工作目录作为提供内容的目录
好,现在我们要把内容目录设在 build 文件夹下我们现在 build 目录下新建一个 index.html 文件
写入如下内容:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>Document</title>
</head>
<body>
这是 build 文件下的 index.html
</body>
</html>
这时候回到我们的配置文件 (webpack.config.js) 写入如下内容:
devServer: {
contentBase: ‘./build’
}
现在 webpack.config.js 的内容如下:
// 基于 node,遵循 common.js 规范
const path = require(‘path’) // 引入 node.js Path 模块
module.exports = {
entry: ‘./src/index.js’, // 入口
output: {
filename: ‘bundle.js’,
path: path.join(__dirname, ‘./build’)
},
mode: ‘development’, // 模式
devServer: {
contentBase: ‘./build’
}
}
好,现在万事俱备,只欠东风。现在我们再重新执行 npm run dev 命令同样的,在浏览器可以看到结果
②、open 启用 open 后,devServer 会打开浏览器。在 devServer 设置如下:
open: true
注意,这里的 true 是布尔值,不是字符串在启用命令 npm run dev 后,devServer 会打开默认浏览器大家用 window 一般都是 IE 浏览器作为默认浏览器那么此时如果我们想使用谷歌浏览器来启动应该怎么设置呢?
此时,我们可以在 package.json 对 script 脚本进行设置,
// 打开默认浏览器
“dev”: “webpack-dev-server –open”
// 打开谷歌浏览器
“dev”: “webpack-dev-server –open chrome”
// 打开火狐浏览器
“dev”: “webpack-dev-server –open firefox”
* 提示:如果在 script 设置了 –open,那么可以不用在配置文件设置 open 字段了
③、source map
由于使用 webpack 打包后,原来的代码经过压缩,去空格,bable 的编译之后,已经变成我们不认识的代码了,为了方便我们调试调式代码,定位 bug,source map 就出现了
在 webpack.config.js 中,devtool 选项用于控制是否生成,以及如何生成 source map。

loader 入门
css loader 安装
loader 用于对模块的源代码进行转换。loader 可以使你在 import 或 ” 加载 ” 模块时预处理文件。webpack 本身只能处理 javascript 文件,而对于 css 文件需要 loader 来处理对于 css 处理,我们常用的有这两种 loader:css-loader 和 style-loader 使用命令安装这两个 loader
npm i -D style-loader css-loader
接下来在 src 文件下新建名为 style 的文件夹,在 style 下新建名为 index.css 文件为了让效果更加直观,往 index.css 文件写入如下内容
body{background-color: yellowgreen;}
接着在我们 src 目录下的 index.js 文件中使用 ES6 的模块语法 import 将 index.css 文件导入进来
import ‘./style/index.css’
我们先不配置 loader,看看浏览器会提示什么执行 npm run dev 命令,看看会发生什么,如图所示:
提示模块解析失败,需要 loader 进行处理
loader 配置
有三种使用 loader 的方式:

配置(推荐):在 webpack.config.js 文件中指定 loader。
内联:在每个 import 语句中显式指定 loader。
CLI:在 shell 命令中指定它们。

我们选择在 webpack.config.js 中配置 loader 基本写法如下:
module: {
rules: [
{
test: /\.css$/, // 利用正则表达式匹配文件名后缀为 css 的文件
use: [‘style-loader’, ‘css-loader’] // 一组 loader 的执行顺序默认是从右向左
}
]
}
接着,我们再重新执行 npm run dev 命令,页面如图所示:
说明我们 css 文件有效果了,再来看下网页元素效果如图,可以看到是以内联样式插入到 html

插件 (plugins) 入门
插件目的在于解决 loader 无法实现的其他事。
html-webpack-plugin 安装
这个插件用来简化创建服务于 webpack bundle 的 HTML 文件, 由于通常在打包中包含一些含有 hash 值的名字,而这些名字在每次编译的时候都发生变化的时候对我们开发人员很麻烦,利用这个插件,我们可以利用这个插件捆绑式这些文件方便我们的开发。
执行安装命令
npm i -D html-webpack-plugin
使用 html-webpack-plugin
在 webpack.config.js 配置如下:
// 基于 node,遵循 common.js 规范
const path = require(‘path’) // 引入 node.js Path 模块
const HtmlWebpackPlugin = require(‘html-webpack-plugin’) // 引入 HtmlWebpackPlugin

module.exports = {
entry: ‘./src/index.js’, // 入口
output: {
filename: ‘bundle.js’,
path: path.join(__dirname, ‘./build’)
},
mode: ‘development’, // 模式
devServer: {
contentBase: ‘./build’
},
module: {
rules: [
{
test: /\.css$/, // 利用正则表达式匹配文件名后缀为 css 的文件
use: [‘style-loader’, ‘css-loader’] // 一组 loader 的执行顺序默认是从右向左
}
]
},
plugins: [
new HtmlWebpackPlugin()
]
}
在这里,我们这个插件做了两步工作:
const HtmlWebpackPlugin = require(‘html-webpack-plugin’)
plugins: [
new HtmlWebpackPlugin()
]
接下来,我们需要在 src 目录下新建模板文件,名为 template.html,我们打包后的文件都已这个 html 文件为模板在模板 html 写入如下内容:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title> 模板文件 </title>
</head>
<body>
使用模板文件
</body>
</html>
这里我们只是简单的使用两个参数

选项
描述
注意

filename
就是 html 文件的文件名,默认是 index.html

template
生成的文件所依赖文件模板的路径

plugins 的配置如下
plugins: [
new HtmlWebpackPlugin({
filename: ‘index.html’,
template: ‘./src/template.html’,
})
]
好的,现在所有都配置好了,我们来测试一下执行命令 npm run dev

可以发现,运行项目时使用的是模板文件现在,再来测试一下打包文件我们把原来的 build 文件删除(当然可以不删,因为会覆盖)
执行命令 npm run abc 此时,我们可以发现 build 目录下 index.html 是这个样子的
直接就帮我们用 script 标签插入了 bundle.js
总结:入门不易,掌握更难,纸上得来终觉浅,绝知此事要躬行!

正文完
 0