30分钟掌握 Webpack
为什么使用 Webpack
在我们进行传统网页开发中,会在 index.html
中引入大量的 js
和 css
文件,不仅可能会导致命名冲突,还会使页面体积变大,因为如果引用了第三方库,需要加载所有的代码。而在 node.js
出现后,javascript
项目支持通过 require
支持模块化开发了,并且支出 npm
方便地管理依赖。
借着 node.js
和浏览器js 的一致性,前端项目开始在 node.js
下开发,完成之后把代码构建成浏览器支持的形式。对于 react
或 vue
这种组件化的开发方式,因为有很多分散的文件,那么久特别需要这样的构建操作。
Webpack
就是进行这一步构建操作的,把 node.js
模块化的代码转化为浏览器可执行的代码。它提供了 import
和 export
ES6模块化语法的支持,然后通过分析代码中 import
导入的依赖,把需要的代码加载进来。在 Webpack
中,任何文件都可以通过 import
导入,只要有对应的 loader
就可以了。在打包过程中,还可以通过插件来干预打包过程,例如剔除不必要的代码,形成体积更小的项目。
创建项目
打开命令行工具,我们在这里创建一个名为
blog
的博客项目:mkdir blog
cd blog
yarn init -y
(或者npm init)
添加
webpack
依赖:yarn add webpack webpack-cli --dev
使用
VSCode
打开项目:code .
初出茅庐
在
blog
项目下新建src
文件下,创建index.js
:console.log("Hello World");
我们先只做一个简单的输出.
在
blog
项目下新建index.html
:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Hello World</h1>
<script src="./dist/index.js"></script>
</body>
</html>
使用
LiveServer
查看刚刚所编写的 html页面:
可以看到浏览器成功显示了 "Hello World",并且控制台也能够成功输出.
尝试使用
webpack
打包打开控制台,输入
npx webpack
npx 能够直接运行
node_modules
下面安装的库的自带的命令行,而不用写node_modules
下一串的绝对路径。
打包完成后可以看到项目里面生成了一个 dist
目录,里面有一个 main.js
文件,其内部的内容和我们刚刚所编写的 index.js
的文件一模一样,这是因为我们并没有使用任何 import
来导入其他的依赖。
使用 import 导入依赖
在
src
下新建一个data.js
文件:export function getBlogPosts() {
return ["博客1", "博客2", "博客3"];
}
在
index.js
中导入data.js
中的函数并调用:import { getBlogPosts } from "./data"; console.log(getBlogPosts());
重新使用
webpack
打包以下,查看结果:npx webpack
现在进入
/dist/main.js
中看一下,代码被简化成了直接输出刚才我们所编写的数组的语句,说明webpack
自动判断了我们所编写代码的逻辑,并通过import
语句得到了我们所引入的代码,分析后生成新的js
文件.在网页中查看下结果:
成功地输出了数组.
Webpack 配置文件
webpack
的配置文件可以说是 webpack
最核心的部分了,我们可以在配置文件中修改入口和出口文件、通过 loader
加载不同类型的文件和使用 plugins
对代码做其他的操作。
尝试修改打包后生成文件的名称
在项目中新建
webpack.config.js
文件:const path = require("path"); module.export = {
mode: "development",
// 设置为开发模式,方便调试
entry: "./src/index.js",
output: {
filename: "dist.js",
path: path.resolve(__dirname, "dist"),
// 设置文件名和目录
}
}
执行
npx webpack
命令打包可以看到
dist
文件夹下多了个dist.js
文件.
使用模块化语法
修改
/index.html
的script
标签:<script src="./dist/dist.js"></script>
将
main.js
修改成为我们刚刚使用webpack
打包生成的dist.js
修改
/src/index.js
文件,将之前编写的数组变成ul
元素插入页面中:const blogs = getBlogPosts(); const ul = document.createElement("ul");
blogs.forEach(blog => {
const li = document.createElement("li");
li.innerText = blog;
ul.appendChild(li);
}) document.body.appendChild(ul);
npx webpack
:列表成功插入到了页面.
引入 css
在
src
下新建style.css
文件:h1 {
color: blueviolet;
}
这里只是简单地改变
h1
标签的颜色.在
/src/index.js
中引入css
文件:import "./style.css";
安装
loader
:打开控制台,输入:
yarn add --dev style-loader css-loader
在
webpack.config.js
中配置loader
module.exports = {
mode: "development",
output: {...},
... module: {
rules: [{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
}]
}
}
module -> rules -> test 内是一个正则表达式,表示以 .css 结尾的文件.
use 属性下是所使用的loader
再次使用
npx webpack
打包:可以看到,刚才写的样式生效了.
加载图片
webpack
原生支持图片等静态文件,但是需要在webpack.config.js
中编写配置:module.exports = {
...
module: {
rules: [
...
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: "assets/resource",
}]
}
}
在
src
下载新建assets/
文件夹,放入一张图片:在
index.js
中引入图片:import AbcImage from "./assets/abc.png" ... const image = document.createElement("img");
image.src = AbcImage; document.body.prepend(image);
npx webpack
:
自动生成 HTML
上述的例子中,我们只是使用 webpack
来打包 js
和 css
文件,并手动的导入编写好的 html
中,使用下面的插件,就可以自动为我们生成 HTML 文件。
安装插件:
yarn add html-webpack-plugin --dev
使用插件:
const HtmlWebpackPlugin = require("html-webpack-plugin");
... plugins: [new HtmlWebpackPlugin({
title: "博客列表",
// 这里可以自定义网页的标题
})],
npx webpack
:可以看到生成了和刚才相同的页面
使用
webpack
打包出来的网页没有显示<h1>Hello World</h1>
的原因是 这个标签是我们自己写的
定义打包好 html 文件的网页标题
我们使用
html-webpack-plugins
打包生成的文件名默认是 Webpack App,其实网页标题是可以在插件内传递参数来更改的:plugins: [new HtmlWebpackPlugin({
title: "博客列表",
})],
Babel
有时我们的代码可能需要运行在更低版本的浏览器上,这些浏览器可能并不支持我们所写的更高级的代码,这时就需要用到 babel
转译工具来使我们的代码变成浏览器能够识别的代码。
安装
babel-loader
相关依赖:yarn add --dev babel-loader @babel/core @babel/preset-env
在
webpack.config.js
中添加配置:rules: [
...
{
test: /\.js$/, // 识别js为结尾的文件
exclude: /node_modules/, //不解释node_modules/下的文件
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"]
}
}
}]
这里可以在
module.exports
下配置devtool="inline-source-map"
方便查看打包后的源码使用
npx webpack
重新打包下,进入dist/dist.js
查看相关代码:/* 打包前的 */
blogs.forEach(blog => {
const li = document.createElement("li");
li.innerText = blog;
ul.appendChild(li);
})
blogs.forEach(function (blog) {
var li = document.createElement("li");
li.innerText = blog;
ul.appendChild(li);
});
可以看到 箭头函数已经被转换成了
.forEach
的形式,增强了对浏览器的兼容性。
使用 Terser 插件压缩打包后的代码
安装插件:
yarn add --dev terser-webpack-plugin
配置:
// webpack.config.js
const TerserPlugin = require("terser-webpack-plugin"); module.exports = {
...
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
}
打包:
npx webpack
可以看到我们打包生成的 js 文件都被紧密地写在了一起,右键属性查看文件大小也要比之前的小一些。
使用 DevServer 插件自动打包
安装:
yarn add -dev webpack-dev-server
配置:
module.exports = {
...
devServer: {
static: "./dist",
},
}
为了我们以后方便运行开发服务器,还需要在
package.json
里添加一个script
:{
...
"scripts": {
"start": "webpack serve --open"
},
}
启动服务器:
yarn start
// 或
npm run start
尝试一下 "热更新?"
在
index.js
下添加如下代码:const header1 = document.createElement("h1");
header1.innerText = "Hello";
document.body.appendChild(header1);
保存,查看网页
这里不在使用 VsCode 的
Live Server
插件了,而是在浏览器地址栏输入命令行中输出的地址:成功!
那么 webpack 是如何实现热更新的呢?其实是在我们每次保存时,插件自动生成新的
dist.js
并把之前的dist.js
写入缓存,这或多或少会增加我们电脑的开销。但 webpack 贴心的为我们想到了这一点。每次打包生成新的
/dist.js
配置
webpack.config.js
output: {
filename: "[name].[contenthash].js",
// name 默认为 main
path: path.resolve(__dirname, "dist"),
},
更改下
index.js
代码,运行npx webpack
可以看到生成了文件后缀名不同的文件,这样可以避免由于浏览器缓存机制而导致更新不及时的问题。
配置目录别名:
和之前写的 https://www.cnblogs.com/hhsk/p/16460701.html 大同小异
- 配置:
// webpack.config.js
module.exports = {
...
resolve: {
alias: {
assets: path.resolve(__dirname, "src/assets")
}
}
}
30分钟掌握 Webpack的更多相关文章
- 30分钟学webpack实战
阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解babel-loader加载器的含义 六:了 ...
- 30分钟手把手教你学webpack实战
30分钟手把手教你学webpack实战 阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解ba ...
- 每天记录一点:NetCore获得配置文件 appsettings.json vue-router页面传值及接收值 详解webpack + vue + node 打造单页面(入门篇) 30分钟手把手教你学webpack实战 vue.js+webpack模块管理及组件开发
每天记录一点:NetCore获得配置文件 appsettings.json 用NetCore做项目如果用EF ORM在网上有很多的配置连接字符串,读取以及使用方法 由于很多朋友用的其他ORM如S ...
- 30分钟掌握ES6/ES2015核心内容(下)
在 30分钟掌握ES6/ES2015核心内容(上)我们讲解了es6最常用的一些语法:let, const, class, extends, super, arrow functions, templa ...
- 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理
[微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...
- 30分钟学会XAML
1.狂妄的WPF 相对传统的Windows图形编程,需要做很多复杂的工作,引用许多不同的API.例如:WinForm(带控件表单).GDI+(2D图形).DirectX API(3D图形)以及流媒体和 ...
- Shell脚本编程30分钟入门
Shell脚本编程30分钟入门 转载地址: Shell脚本编程30分钟入门 什么是Shell脚本 示例 看个例子吧: #!/bin/sh cd ~ mkdir shell_tut cd shell_t ...
- JS组件系列——又一款MVVM组件:Vue(一:30分钟搞定前端增删改查)
前言:关于Vue框架,好几个月之前就听说过,了解一项新技术之后,总是处于观望状态,一直在犹豫要不要系统学习下.正好最近有点空,就去官网了解了下,看上去还不错的一个组件,就抽空研究了下.最近园子里vue ...
- 2016windows(10) wamp 最简单30分钟thrift入门使用讲解,实现php作为服务器和客户端的hello world
2016最简单windows(10) wamp 30分钟thrift入门使用讲解,实现php作为服务器和客户端的hello world thrift是什么 最简单解释 thrift是用来帮助各个编程语 ...
随机推荐
- 市面上的工业ERP系统如何区别?存在什么样的不同?
工业发展当中所要涉及到的管理是繁琐而复杂的,在ERP系统的拓展开发中,市面上出现了很多的工业ERP系统来让企业选择.这是近年来非常受欢迎的一种管理手段,依靠计算机系统的强大功能,来实现数据化的管理,企 ...
- 年中盘点 | 2022年,PaaS 再升级
作者丨刘世民(Sammy Liu)全文共7741个字,预计阅读需要15分钟 过去十五年,是云计算从无到有突飞猛进的十五年.PaaS作为云计算的重要组成部分,在伴随着云计算高速发展的同时,在云计算产业链 ...
- NOI / 2.1基本算法之枚举 1749:数字方格
描述: 如上图,有3个方格,每个方格里面都有一个整数a1,a2,a3.已知0 <= a1, a2, a3 <= n,而且a1 + a2是2的倍数,a2 + a3是3的倍数, a1 + a2 ...
- [极客大挑战 2019]BabySQL-1|SQL注入
1.打开题目之后,查看源代码信息,发现check.php文件,结果如下: 2.那就只能尝试登录,经测试当输入or.by.select.from.and.where等关键字时会被过滤且会被过滤为空(过滤 ...
- Windows环境中Hadoop配置
我们之前已经在Windows中安装好了Hadoop,并且配置了环境变量.如果要在本地上运行的,还需要这两个文件,可以去找一下,放到Hadoop的bin目录下面.这样我们写好的mr程序就可以直接在Win ...
- Regular采样类定义和测试
这个算法是均匀采样算法,继承于Sampler类. 类声明: #pragma once #ifndef __REGULAR_HEADER__ #define __REGULAR_HEADER__ #in ...
- WPF主窗体调用 User32的SetWindowPos 设置窗体置顶会导致与其他窗体抢夺焦点的问题
最近发现:自己开发的窗体应用,在二级弹窗或者提示框弹出的时候,交替点击窗体和窗体外(相当于窗体交替的获取焦点和失去焦点),都会导致其他的应用一闪一闪的. 经过排查,是由于该窗体由于部分因素考虑,用了 ...
- Luogu2915 [USACO08NOV]奶牛混合起来Mixed Up Cows (状压DP)
枚举末位状态 #include <iostream> #include <cstdio> #include <cstring> #include <algor ...
- Redis入门到实战
一.Redis基础 Redis所有的命令都可以去官方网站查看 1.基本命令 keys * 查找所有符合给定模式pattern(正则表达式)的 key .可以进行模糊匹配 del key1,key2,. ...
- 管理 MongoDB 用户和权限
创建用户 创建用户的函数是:db.createUser(). 创建用户时,需要为该用户添加权限.可添加的权限以及说明: 权限 作用 read 允许用户读取指定数据库. readWrite 允许用户读写 ...