Webpack学习笔记
文章目录
第一章 Webpack简介
1.1 Webpack是什么
Webpack是一种前端资源构建工具,一种静态模块打包器(module bundler)
在webpack看来,前端的所有资源(js/json/css/img/less…)都会作为模块处理。
它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。
1.2 Webpack的五个核心概念
1.2.1 enter
入口(entry)提示Webpack以哪个文件作为入口起点开始打包,分析构建内部的依赖图。
1.2.2 output
输出(output)提示webpack打包后的资源bundles输出到哪去,以及如何命名。
1.2.3 loader
loader让Webpack能够去处理那些非JavaScript文件(css,img)(webpack自身只理解JavaScript)
1.2.4 plugins
插件(plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化到压缩,一直到重新定义环境中的变量等。
1.2.5 mode
模式(mode)提示Webpack使用相应的模式的配置。
选项 | Value | 特点 |
---|---|---|
development(开发模式) | 会将process.env.NODE_ENV的值设置为development。 启用NameChunksPlugin和NameModulesPlugin。 | 能让本地代码调试运行的环境 |
production(生产模式) | 会将process.evn.NODE+ENV的值设为production。 启用FlagDependencyUsagePlugin, FagIncludeChunksPlugin, ModuleConcationPlugin, NoEmitOnErrorsPlugin,OccurrenceOrderPlugin, SideEffectsPlugin,UglifyJsPlugin。 | 能让代码优化上线运行环境 |
第二章:Webpack的初体验
新建一个 webpack初体验 的文件夹
执行一下命令 个设置都为默认设置
npm init
npm i webpack webpack-cli -g
npm i webpack webpack-cli -D
等待命令执行完毕后新建src和build文件夹,并在src文件夹中添加index.js文件,作为webpack打包的入口文件。
2.1 查看在不同的模式下webpack打包的区别
在index.js文件中写入一下代码,然后我们分别用开发模式和生产模式打包下看看打包后的文件的区别。
// index.js :webpack 入口的起始文件
// 1、运行指令:
// 开发环境 : webpack ./src/index.js -o ./build/built --mode=development
// webpack会以./src/index.js为入口文件开始打包,打包后会输出到 ./build/built.js
// 整体的打包环境为开发环境
// 生产环境:webpack ./src/index.js -o ./build/built --mode=production
// webpack会以./src/index.js为入口文件开始打包,打包后会输出到 ./build/built.js
// 整体的打包环境为生产环境
function add(x, y) {
return x + y;
}
console.log(add(12,11))
写完后我们打开终端测试
2.1.1 在终端输入一下开发环境打包的命令
webpack ./src/index.js -o ./build/built --mode=development
打包完成后我们打开打包形成的文件./build/built/main.js查看在开发模式下打包后的效果。
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/***/ (() => {
eval("// index.js :webpack 入口的起始文件\r\n// 1、运行指令:\r\n// 开发环境 : webpack ./src/index.js -o ./build/built --mode=development\r\n// webpack会以./src/index.js为入口文件开始打包,打包后会输出到 ./build/built.js\r\n// 整体的打包环境为开发环境\r\n// 生产环境:webpack ./src/index.js -o ./build/built --mode=production\r\n// webpack会以./src/index.js为入口文件开始打包,打包后会输出到 ./build/built.js\r\n// 整体的打包环境为生产环境\r\nfunction add(x, y) {\r\n return x + y;\r\n}\r\n\r\nconsole.log(add(12,11))\r\n\n\n//# sourceURL=webpack://webpack_test/./src/index.js?");
/***/ })
/******/ });
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/ var __webpack_exports__ = {};
/******/ __webpack_modules__["./src/index.js"]();
/******/
/******/ })()
;
2.1.2 在终端输入一下生产环境打包的命令
webpack ./src/index.js -o ./build/built --mode=production
打包完成后我们打开打包形成的文件./build/built.js查看在开发模式下打包后的效果。
console.log(23);
可以看出生产环境下的打包会压缩代码,使项目的空间更小。
2.2 引入打包后的资源
在build文件夹下新建 index.html文件,并引入打包后的built.js文件。用浏览器运行下该HTML文件可以看到我们使用webpack打包后的js文件是可以正常使用的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--引入的是打包后的资源-->
<script src="./built/main.js"></script>
</body>
</html>
2.3 测试json文件的打包
在scr文件夹下新建data.json文件,输入一下内容
{
"name": "jack",
"age": 18
}
然后再index.js文件中引入data.json并重新打包(使用开发模式打包)
// index.js :webpack 入口的起始文件
// 1、运行指令:
// 开发环境 : webpack ./src/index.js -o ./build/built --mode=development
// webpack会以./src/index.js为入口文件开始打包,打包后会输出到 ./build/built.js
// 整体的打包环境为开发环境
// 生产环境:webpack ./src/index.js -o ./build/built --mode=production
// webpack会以./src/index.js为入口文件开始打包,打包后会输出到 ./build/built.js
// 整体的打包环境为生产环境
import data from './data.json'
console.log(data)
function add(x, y) {
return x + y;
}
console.log(add(12,11))
等待打包完成后,查看index.html文件可以看出再浏览器的控制台可以打印出data说明webpack可以打包json文件。
2.4 测试css文件的打包
在src文件夹中添加一个index.css文件,输入以下代码
html,
body{
height: 100%;
background-color: pink;
}
然后我们在index.js文件中引入css文件
import data from './data.json'
import './index.css'
console.log(data)
function add(x, y) {
return x + y;
}
console.log(add(12,11))
引入后重新打包,可以看到报出打包错的提示
asset main.js 5.74 KiB [emitted] (name: main)
runtime modules 937 bytes 4 modules
cacheable modules 798 bytes
./src/index.js 699 bytes [built] [code generated]
./src/data.json 34 bytes [built] [code generated]
./src/index.css 65 bytes [built] [code generated] [1 error]
ERROR in ./src/index.css 2:4
Module parse failed: Unexpected token (2:4)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| html,
> body{
| height: 100%;
| background-color: pink;
@ ./src/index.js 11:0-20
webpack 5.60.0 compiled with 1 error in 117 ms
2.5 结论
1、webpack能够处理js/json资源,不能处理css/img等其他资源
2、生产环境和开发环境的区别就多了一个压缩js代码
4、生产环境和开发环境将ES6模块化编译成浏览器能够识别的模块化
第三章 Webpack打包css文件
由2.4可知,webpack本身是不能 用来打包css文件,需要借助loader打包一些非JavaScript的资源。
新建如下文件:
index.css文件内容跟如下
html,body{
height: 100%;
background-color: pink;
margin: 0;
padding: 0;
}
index.js文件中引入css文档内容如下
// 引入样式资源
import './index.css'
3.1 webpack.config.js文件配置
这里我们为了实现webpack可以打包css文件,我们需要新建一个webpack.config.js文件用来配置webpack。
webpack.config.js文件的具体写法以及解释如下:
// webpack.config.js
// 作用:指示webpack干那些活,(当你运行webpack指令的时候会加载里面的配置)
// 所有的构建工具都是基于node.js平台运行的~模块化默认采用common.js。
// 根据nodejs的一个模块叫做path,来获得绝对路径
// resolve是用来拼接绝对路径的方法
const { resolve } = require('path')
module.exports = {
// 暴露一个对象,在对象中写webpack配置
// 文件起点
entry:'./src/index.js',
// 输出
output:{
// 输出文件名
filename:'built.js',
// 输出路径
// __dirname是nodejs的一个变量代表当前文件的目录绝对路径
path: resolve(__dirname, 'build')
},
// loader的配置
module:{
rules:[
// 详细的loader配置
{
//配置那些文件 下面这句话代表配置以.css结尾的文件
test: /\.css$/,
// 使用哪些loader进行处理
use: [
//use中数组中loader执行顺序:从右到左,从下到上依次生效
// 创建style标签,将js中的js样式资源插入进去,添加到页面中的head中生效
'style-loader',
// css-loader会将css文件变成common.js模块加载js中,里面的内容是样式的字符串
'css-loader'
]
}
]
},
// plugins的配置
plugins:[
// 详细plugins的配置
],
//模式
mode: 'development' //开发模式
// mode: 'production'
}
3.2 下载css依赖包
打开终端一次进行一下命令
1、首先初始化一个包描述文件
npm init
2、下载webpack-cli
npm i webpack webpack-cli -D
3 、下载css-loader style-loader
npm i css-loader style-loader -D
这个时候我们就已经下载好所有的配置了
然后我们在终端输入如下命令打包下
webpack
等待打包完成我们就可以在build文件下看到打包好的built.js文件
3.3 css文件打包
我们在build文件夹下新建index.html文件并引入刚刚打包好的built.js文件看看我们写的样式生效没。
index.html内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack</title>
</head>
<body>
<script src="./built.js"></script>
</body>
</html>
用浏览器打开html文件可以看到整个界面的颜色都变成了粉红色 !!样式打包成功。
3.4 less文件打包
首先在src文件夹下新建一个index.less文件,如下
#title {
color: aquamarine;
}
和css文件配置相同,我们需要在webpack.config.js中配置下处理.less文件的loader。
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
// 将less文件编译成css文件
// 需要下载less-loader和less
'less-loader'
]
}
然后下载less-loader和less
npm i less-loader -D
npm i less -D
下载完成后我们在html文件下使用下我们在less文件中写的样式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack</title>
</head>
<body>
<h1 id="title">hello world</h1>
<script src="./built.js"></script>
</body>
</html>
用浏览器打开html文件可以看到我们在less文件中写的样式已经生效了。
3.5 总结
我们可以总结下webpack.config.js文件的打包流程
首先webpack会根据entry找到打包的起点,这里我们写的是./src/index.js这个文件,webpack就会根据这个文件的资源依赖进行打包。在./src/index.js中我们写了import ‘./index.css’,这个webpack就会找到index.css文件进行打包,但是webpack本身是处理不了css类型的文件,这时它会根据loader的配置,发现在loader中正好有与之匹配的.css文件类型的处理方式。这时他就会根据css-loader——>style-loader去处理.css类型的文件。处理处理完毕后,会根据output中写得将打包好的资源放到build文件夹下built.js文件。
第四章 webpack打包Html文件
webpack打包Html文件需要借助 html-webpack-plugin插件 。
插件 (html-webpack-plugin) 和 资源加载器(loader)的使用不同
资源加载器(loader): 1下载——>2使用(配置loader)
插件(plugin):1下载——>2引入——>3使用
4.1 配置html-webpack-plugin插件
新建如下文件
html文件内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack</title>
</head>
<body>
<h1 id="title">hello html</h1>
</body>
</html>
我们想要打包的就是这里我们新建的HTML文件,因为webpack本身不能对Html文件进行打包。所以这里需要引用html-webpack-plugin插件对HTML进行打包。
1、webpack.config,js文件中配置html-webpack-plugin 如下
// loader : 1、下载 2、使用(配置loader)
// plugin: 1、下载 (npm i html-webpack-plugin -D) 2、引入 3、使用
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: "built.js",
path: resolve(__dirname,'build')
},
module: {
rules: [
// loader的配置
]
},
plugins: [
// plugins的配置
// Html-webpack-plugin
// 功能:默认会创建一个空的HTML文件,自动引入打包输出的所有的资源(js/css)
// 需求:需要有结构的HTML文件
new HtmlWebpackPlugin({
// 复制"./src/index.html"文件,并自动引入打包输出的所有的资源(js/css)
template: "./src/index.html"
})
],
mode: "development"
}
2、下载html-webpack-plugin插件
打开终端运行如下命令
npm i html-webpack-plugin -D
3、打包文件终端输入 webpack 命令。等待打包完成
4.2 总结
html-webpack-plugin这个插件是专门对Html文件进行打包的插件。
html-webpack-plugin的使用流程为
下载 | 引入 | 使用 |
---|---|---|
npm i html-webpack-plugin -D | const HtmlWebpackPlugin = require(‘html-webpack-plugin’) | 在plugins属性中配置 |
html-webpack-plugin打包的机制流程:
template:模板当配置此属性时,html-webpack-plugin(默认会创建一个空的HTML文件)会以此文件为模板在打包文件中形成一个Html文件,并自动引入打包输出的所有资源。
第五章 打包图片资源
打包图片类资源和打包CSS文件同理,需要用到相应的资源加载器(loader),需要使用url-loader和html-loader两类资源加载器。
新建如下文件
1、webpack.config.js配置如下
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: "built.js",
path: resolve(__dirname,'build')
},
module: {
rules: [
{
test: /\.less$/,
// 使用多个loader处理用use
use: [
'style-loader',
'css-loader',
'less-loader'
]
},
{
test: /\.(jpg|png|gif)$/,
// 使用一个loader
// 需要下载两个包: url-loader file-loader
loader: 'url-loader',
// loader的一些配置
options: {
// 图片大小小于8kb,就会被base64处理
// (当发现图片的大小时会将图片转化成base64编码的方式,转化成base64的字符串
// 当浏览器发现base64的符串时就会当成图片的形式去解析)
// 优点:减少请求数量(减轻服务器压力)
// 缺点:图片的体积会更大(文件请求速度更慢)
limit: 8 * 1024,
// 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
// 解析时会出问题:[object Module]
// 解决:关闭 url-loader的es6模块化,使用commonjs解析
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash值的前10位
// [ext]代表取文件的原来的扩展名
name:'[hash:10].[ext]'
},
type: "javascript/auto"
},
{
test: /\.html$/,
// 处理html文件中的img图片(负责引入img,从而能够被url-loader进行处理)
loader: 'html-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
}
)
],
mode: "development"
}
index.less文件内容如下
#box1{
width: 100px;
height: 100px;
background-image: url("./cc.gif");
background-repeat: no-repeat;
background-size: 100%;
}
#box2{
width: 100px;
height: 100px;
background-image: url("./3333.jpg");
background-repeat: no-repeat;
background-size: 100%;
}
#box3{
width: 100px;
height: 100px;
background-image: url("./AJAX.png");
background-repeat: no-repeat;
background-size: 100%;
}
index.html文件内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack打包图片资源</title>
</head>
<body>
<div id="box1"></div>
<!--url-loader 进行处理-->
<div id="box2"></div>
<div id="box3"></div>
<img src="./3333.jpg" alt="3333">
<!--html-loader 进行处理-->
</body>
</html>
打包后的结果
第五章 打包其他资源
这里我们在iconfont官网下载了三个图标在html中引入,然后尝试打包它。
这里的iconfont.css和iconfont.ttf下载下来的图标代码
1、index.html内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack打包其他资源</title>
</head>
<body>
<sapn class="iconfont icon-feichuan02"></sapn>
<sapn class="iconfont icon-huojian"></sapn>
<sapn class="iconfont icon-xingqiu"></sapn>
</body>
</html>
2、打包入口文件中引入css文件,内容如下
// 引入iconfont样式文件
import './iconfont.css'
3、webpack.config.js配置文件内容如下
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: "built.js",
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其他资源(除了html,css,js资源以外的资源)
{
// 排除css|html|js这三类类型的文件
exclude: /\.(css|html|js)/,
loader: 'file-loader',
options: {
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash值的前10位
// [ext]代表取文件的原来的扩展名
name:'[hash:10].[ext]'
},
type: "javascript/auto"
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
})
],
mode: "development"
}
这里我们想要打包的是除了css/js/html文件之外的所有的文件
需要用到的loader是file-loader
在配置该loader时使用exclude,它代表的意思时排除里面包含类型的文件
配置完毕 我们打开终端 输入 webpack 命令打包
打包后的效果
打开打包的HTML文件可以看到我们引用的三个图标都可以完美展现。
第六章 devServer
6.1 devserver简介
webpack的devServer,给我们提供了一个本地的node服务器,用于开发模式下调试我们的应用.
webpack-dev-server模块启动之后把我们的代码打包到node服务器,提供了热更新,后端代理,自动启动浏览器等实用功能。
6.2 安装devserver
打开终端,输入一下指令即可再项目中安装devserver
npm i webpack-dev-server -D
6.3 devserver配置
我们可以再webpack.config.js文件中配置devserver的各项配置 ,具体配置和意义我写在了代码中
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: "built.js",
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其他资源(除了html,css,js资源以外的资源)
{
// 排除css|html|js这三类类型的文件
exclude: /\.(css|html|js)/,
loader: 'file-loader',
options: {
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash值的前10位
// [ext]代表取文件的原来的扩展名
name:'[hash:10].[ext]'
},
type: "javascript/auto"
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
})
],
mode: "development",
// 开发服务器devServer 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
// 特点只会在内存中编译打包,不会有任何输出
// 启动devServer的指令为:npx webpack-dev-server
devServer: {
//项目构建后的路径
// contentBase: resolve(__dirname,'build'),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
//自动打开浏览器
open:true
}
}
第七章 开发环境配置总结
让我们来总结下再开发环境中我们该如何进行webpack的配置。再这些配置中需要设置对css文件、less文件、图片资源(jpg、png、gif)、html中的图片资源、html文件、以及除了以上的其他资源的处理配置。设置devserver。
7.1 配置需要打包的资源
我们新建一个webpack开发环境配置的文件夹。再文件夹中添加src的文件夹和webpack.config.js文件。
src文件中存放用于打包的资源。
webpack.config.js文件用来设置webpack的各项配置。
首先在js文件夹中新建一个index.js的文件夹用于webpack打包的入口文件。
index.js文件内容如下
// 引入
import '../css/iconfont.css'
import '../css/index.less'
function add(x,y) {
return x + y
}
console.log(add(4, 7))
css文件夹中用于存放样式文件
iconfont.css文件内容:
@font-face {
font-family: "iconfont"; /* Project id */
src: url('../media/iconfont.ttf?t=1635409390443') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-feichuan02:before {
content: "\e647";
}
.icon-huojian:before {
content: "\e648";
}
.icon-xingqiu:before {
content: "\e649";
}
index.less文件内容:
#box{
width: 100px;
height: 100px;
background-image: url("../imgs/cc.gif");
background-repeat: no-repeat;
background-size: 100% 100%;
}
imgs文件夹中用于存放我们需要打包的三种类型的图片。
media文件夹中用于存放其他资源
index.html文件夹内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>开发环境配置</title>
</head>
<body>
<h1>开发环境配置</h1>
<sapn class="iconfont icon-feichuan02"></sapn>
<sapn class="iconfont icon-huojian"></sapn>
<sapn class="iconfont icon-xingqiu"></sapn>
<div id="box"></div>
<img src="./imgs/22.jpg" width="300px" height="300px" alt="22">
<img src="./imgs/AJAX.png" alt="AJAX">
<img src="./imgs/cc.gif" alt="cc">
</body>
</html>
7.2 webpack配置文件
webpack.config.js文件内容如下
// 开发环境整体配置
// 运行项目指令:
// webpack 会将打包结果输出出去
// npx webpack-dev-server 只会在内存中编译打包没有输出
//
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/js/index.js',
output: {
filename: "js/built.js",
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
{
//处理less资源
//打包样式后会输出到js文件中
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
},
{
// 处理css资源
//打包样式后会输出到js文件中
test: /\.css$/,
use: [
'style-loader',
'css-loader',
]
},
{
// 处理图片资源
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64处理
// (当发现图片的大小时会将图片转化成base64编码的方式,转化成base64的字符串
// 当浏览器发现base64的符串时就会当成图片的形式去解析)
// 优点:减少请求数量(减轻服务器压力)
// 缺点:图片的体积会更大(文件请求速度更慢)
limit: 8 * 1024,
// 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
// 解析时会出问题:[object Module]
// 解决:关闭 url-loader的es6模块化,使用commonjs解析
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash值的前10位
// [ext]代表取文件的原来的扩展名
name:'[hash:10].[ext]',
// 将打包的资源输出到imgs下的文件夹
outputPath:'imgs'
},
type: "javascript/auto"
},
{
// 处理html中的图片资源
test: /\.html$/,
loader: 'html-loader'
},
{
// 处理其他资源
exclude: /\.(html|js|css|less|jpg|png|gif)/,
loader: 'file-loader',
options: {
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash值的前10位
// [ext]代表取文件的原来的扩展名
name:'[hash:10].[ext]',
// 将其他资源打包输出到media文件夹下
outputPath:'media'
},
type: "javascript/auto"
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
})
],
devServer: {
// static: {
// directory: path.join(__dirname, 'build')
// },
//项目构建后的路径
// contentBase: resolve(__dirname,'build'),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
//自动打开浏览器
open:true
// target: 'web',
},
mode: "development"
}
最后我们启用下devserver查看下效果
在终端中输入如下指令
npx webpack-dev-server
效果如下个,文件资源打包成功:
第八章 提取css成单独文件
在开发环境中我们一般的打包,都会将css的样式文件通过css-loader打包进js文件中。这样会让文件变得冗余复杂。
这里我们就可以通过以写插件,在webpack打包的时候将css的样式单独提取成一个文件。
mini-css-extract-plugin就可以帮助我们实现以上功能。
新建如下文件,用于测试mini-css-extract-plugin 将css文件提取成单独文件的功能。
a.css文件内容如下:
#box1 {
width: 100px;
height: 100px;
background-color: pink;
}
b.css文件内容如下
#box2{
width: 200px;
height: 200px;
background-color: deeppink;
}
index.html文件中使用在a.css和b.css文件的样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack</title>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>
在打包入口文件index.js文件中引入样式
import '../css/a.css';
import '../css/b.css';
8.1 安装mini-css-extract-plugin
在我们的项目中通过如下命令安装mini-css-extract-plugin
npm i mini-css-extract-plugin
8.2 配置mini-css-extract-plugin
我们在安装完mini-css-extract-plugin后在webpack.config.js文件中使用。
mini-css-extract-plugin配置的各配置含义已在注释中详写。
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MinCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
entry: './src/js/index.js',
output: {
filename: "js/built.js",
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
//创建style将样式放进去
// 'style-loader',
// 用这个MinCssExtractPlugin loader 取代style-loader
// 作用提取js中的css成单独的文件
MinCssExtractPlugin.loader,
// 将css文件整合到js文件中
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
}),
// npm i mini-css-extract-plugin
new MinCssExtractPlugin({
// 对输出的css文件进行重命名
filename: 'css/built.css'
})
],
mode: "development"
}
第九章 css文件兼容性和压缩处理
9.1 css文件兼容性处理
有些css样式需要考虑到浏览器的兼容问题,在开发工程我们可以将处理CSS样式兼容性的问题交给webpack的插件来处理,这个插件可以自动识别那些需要考虑浏览器兼容问题的样式,并对其进行处理。
这里我需要用到两个插件:
postcss-loader
postcss-preset-env
9.1.1 安装postcss-loader和postcss-preset-env
打开终端,输入如下命令进行安装:
npm i postcss-loader postcss-preset-env
9.1.2 配置postcss-loader和postcss-preset-env
我们在webpack.config.js文件中对这个两个postcss-loader和postcss-preset-env进行配置。其具体的用法和含义请看代码注释
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MinCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
// 设置nodejs环境变量
process.env.Node_ENV = 'development';
//optimize-css-assets-webpack-plugin 作用:压缩css文件
// 下载: npm i optimize-css-assets-webpack-plugin -D
module.exports = {
entry: './src/js/index.js',
output: {
filename: "js/built.js",
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
//创建style将样式放进去
// 'style-loader',
// 用这个MinCssExtractPlugin loader 取代style-loader
// 作用提取js中的css成单独的文件
MinCssExtractPlugin.loader,
// 将css文件整合到js文件中
'css-loader',
// css兼容性处理:postcss ---> postcss-loader和postcss-preset-env
// 下载 npm i postcss-loader postcss-preset-env
//这个插件可以帮助postcss 识别某些环境 从而加载指定的配置能够让我们的css文件的兼容性精确到某一个浏览器的版本
// postcss-preset-env帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式
// " browserslist ": {
// 代表开发环境 --> 设置node环境变量:process.env.Node_ENV = 'development'
// "development": [
// 兼容最近的chrome的版本
// "last 1 chrome version",
// "last 1 firefox version",
// "last 1 safari version"
// ],
// 生产环境
// "production": [
// ">0.2%", 基本上兼容所有浏览器
// "not dead", 不要已经死了的浏览器
// "not op_mini all" 不要 op_mini
// ]
// }
// 使用loader的默认配置
// 'postcss-loader'
// 修改loader的配置
{
loader: "postcss-loader",
options: {
ident: 'postcss',
plugin:() => [
// postcss的插件
require('postcss-preset-env')
]
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
}),
// npm i mini-css-extract-plugin
new MinCssExtractPlugin({
// 对输出的css文件进行重命名
filename: 'css/built.css'
}),
// 压缩css
new OptimizeCssAssetsWebpackPlugin()
],
mode: "development"
}
9.1.3 package.json文件配置
在package.json文件中输入如下配置
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
9.2 压缩css文件
我们在上面将css文件单独提取出来形成一个文件
如下是形成文件的样子,可以看到这个文件中的css样式手空格换行的,因此该样式文件是占用空间比较大的。
因此这里我们需要将css文件进行压缩处理。
压缩css文件我们用到了 optimize-css-assets-webpack-plugin 插件
9.2.1 安装optimize-css-assets-webpack-plugin
打开终端输入如下命令:
npm i optimize-css-assets-webpack-plugin -D
对于 optimize-css-assets-webpack-plugin的使用,我们只需要在webpack.config.js文件中引入并new一些就可以了(可以参考9.1.2中的配置)。
第十章 生产环境的所有配置
再webpack.config.js中配置所有的生产环境所需的配置:
具体包括
1、入口文件
2、输出配置
3、css文件和less文件处理(包括提取出来单独成一个文件,压缩css文件,css文件兼容性处理)
4、js文件处理(包括js语法检查配置(eslint),js兼容性处理,js压缩)
5、图片处理(包括常规jpg、png、gif图片处理(输出路径、文件名长短)、html文件中的图片处理)
6、html文件处理(打包、压缩、去除注释)
7、其他资源处理
const {resolve} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //将css文件从js文件中提取出来单独成一个文件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'); //对css文件进行压缩
const HtmlWebpackPlugin = require('html-webpack-plugin')
//定义nodejs的环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = 'production'
//复用loader 定义一个变量,然后在下面即可以展开它实现复用
const commonCssLoader = [
MiniCssExtractPlugin-loader,
'css-loader',
{
// 还需要再package.json中定义browserslist
loader: "postcss-loader",
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')
]
}
}
];
module.exports = {
entry: './src/js/index.js',
output: {
filename: "js/built.js",
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [...commonCssLoader]
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
// 正常来讲,一个文件只能被一个loader处理。
// 当一个文件被多个loader处理,那么一定要指定loader执行的先后顺序
// 先执行eslint 再 执行babel
{
test: /\.js$/,
exclude: /node_modules/,
// 优先执行
enforce: "pre",
//在package.json中eslintConfig--airbnb
loader: 'eslint-loader',
options: {
fix: true,
}
},
{
test: /\.js$/,
exclude: /node_modules/,
// js兼容性处理
loader: 'babel-loader',
options: {
preset:[
'@babel/preset-env'
[
{
useBuiltIns:'usage',
corejs: {version: 3},
targets:{chrome:'60',firefox:'50'}
}
]
]
}
},
{
test: /\.(jpg|png|gif)$/,
// 使用一个loader
// 需要下载两个包: url-loader file-loader
loader: 'url-loader',
// loader的一些配置
options: {
// 图片大小小于8kb,就会被base64处理
// (当发现图片的大小时会将图片转化成base64编码的方式,转化成base64的字符串
// 当浏览器发现base64的符串时就会当成图片的形式去解析)
// 优点:减少请求数量(减轻服务器压力)
// 缺点:图片的体积会更大(文件请求速度更慢)
limit: 8 * 1024,
// 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
// 解析时会出问题:[object Module]
// 解决:关闭 url-loader的es6模块化,使用commonjs解析
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash值的前10位
// [ext]代表取文件的原来的扩展名
name:'[hash:10].[ext]',
outputPath: 'img',
},
type: "javascript/auto"
},
{
test: /\.html$/,
// 处理html文件中的img图片(负责引入img,从而能够被url-loader进行处理)
loader: 'html-loader'
},
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath:'media'
}
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
//压缩css文件
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: ".src/index.html",
minify: {
//压缩html文件
collapseWhitespace:true,
//删除HTML文件中的注释
removeComments:true
}
})
],
//将mode调为production js就会自动压缩
mode: "production"
}
第十一章 webpack配置详解
在这对webpack所有配置进行了详细的解释
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const TerserWebpackPlugin = require('terser-webpack-plugin')
// entry: 入口起点
// 1、string ----> './src/index.js',
// 打包形成一个chunk. 输出一个bundle文件。
// 此时chunk的名称默认是main
// 2、array ----> ['./src/index.js', './src/add.js'],
// 多入口
// 所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle
// 只有在HMR功能中让HTML热更新生效
// 3、object
// 对入口
// 有几个入口文件就形成几个chunk,输出几个bundle文件
// 此时chunk的名称就是key
// 特殊用法
module.exports = {
entry: './src/js/index.js', // string 单入口
// entry: ['./src/index.js', './src/add.js'], // array 多入口
// entry: {
// index: './src/index.js',
// add: './src/add.js',
// }, // object
// entry: {
// // 所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle。
// index: ['./src/index.js', './src/count.js'],
// // 形成一个chunk,输出一个。输出出去只有一个bundle。
// add: './src/add.js',
// }, // 特殊用法
output: {
// 文件名称(制定名称加目录)
filename: 'js/[name].[contenthash:10].js',
// 输出文件目录(将来所有资源输出的公共目录)
path: resolve(__dirname, 'bu4ild'),
// 所有资源引入公共路径前缀--> 'img/a.jpg'(当前路径下去找img) --->'/img/a.jpg'(会以当前服务器地址去补充)
publicPath: '/',
// 非入口chunk的名称
chunkFilename: 'js/[name]_chunk.js',
// 整个库向外暴露的变量名
library: ['name'],
// 变量名暴露在哪个上面
// libraryTarget: 'window', // 将变量名添加上browser
// libraryTarget: 'global', // 将变量名添加上global
libraryTarget: 'commonjs', // 将变量名添加上commonjs
},
module: {
rules: [
// loader的配置
{
// 表示一下配置只会生效一个
oneOf: []
},
{
test: /\.css$/,
// 多个loader用use
use: ['style-loader','css-loader']
},
// {
// test: /\.js$/,
// // 排除node_modules下的js文件
// exclude: /node_modules/,
// // 只检查src下的js文件2
// include: resolve(__dirname, 'src'),
// // 优先执行
// enforce: 'pre',
// // 延后执行
// // enforce: 'post',
// // 单个loader用loader写
// loader: 'eslint-loader'
// },
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: "production",
// 解析模块的规则
resolve: {
// 配置解析模块的路径别名: 可以简写路径 缺点是 写路径的时候没有提示
alias: {
$css:resolve(__dirname, 'src/css')
},
// 配置省略文件路径的后缀名
extensions: ['.js', '.json', 'jsx', 'css'],
// 告诉webpack解析模块是去哪个目录找
modules: ['node_modules']
},
// 用于开发环境
devServer: {
// 运行代码的目录
contentBase:resolve(__dirname,'build'),
// 启动gzip压缩
compress: true,
// 端口号
port: 5000,
// 域名
host: 'localhost',
// 自动打开浏览器
open: true,
// 开启HMR功能
hot: true,
// 监视contentBase目录下的所有文件,一旦发生变化就会reload
watchContentBase: true,
watchOptions: {
// 忽略不需要监视的文件
ignored: /node_modules/
},
// 不要显示启动服务器的日志信息
clientLoglevel: 'none',
// 除了一些基本启动的信息以外其他信息内容都不要显示
quiet: true,
// 如果出错了, 不要全屏提示
overlay: false,
// 服务器代理 解决开发环境的跨域问题
proxy: {
// 一旦devserver(5000)服务器接收到/api/*** 的请求,就会把请求转发到另一个服务器(3000)
'/api': {
target: 'http://localhost:3000',
// 发送请求时,请求路径重写:将/api/*** ----> *** (去掉/api)
pathRewrite: {
'^/api':''
}
}
}
},
optimization: {
splitChunks: {
chunks: "all",
// // 一下是默认值不需要修改 除非有特殊需求
// minSize: 30 * 1024, // 分割的chunk最小的为30kb
// maxSize: 0, // 最大没有限制
// minChunks: 1,
// // 要提取的chunks最少被引用一次
// maxAsyncRequests: 5,
// // 按需加载时并行加载的文件最大数量为5
// maxInitialRequests: 3,
// // 入口js文件最大并行请求的数量
// automaticNameDelimiter: '~',
// // 名称连接符
// name: true,
// // 可使用命名规则
// cacheGroups: { // 分割chunk的组
// // node_modules文件会被打包到vendors组中的chunk中---->vendors~***.js
// // 满足上面的公共规则,如大小要是超过30kb至少被引用一次
// vendor: {
// test: /[\\/]node_modules[\\/]/,
// // 优先级
// priority: -10
// },
// default: {
// minChunks: 2,
// // 优先级
// priority: -20,
// // 如果当前要打包的模块和之前已经被提取的模块是同一个就会复用 而不是重新打包模块
// reuseExistingChunk: true
// }
// }
},
// 解决:修改a文件导致b文件的contenthash变化
runtimeChunk: {
// 将当前模块的记录其他模块的hash单独打包为一个文件 runtime
name: entrypoint => `runtime-${entrypoint.name}`
},
minimizer: [
// 配置生产环境的压缩方案:js和css
new TerserWebpackPlugin({
// 开启缓存
cache: true,
// 开启多进程
parallel: true,
// 启动source-map
sourceMap: true,
})
]
}
}