写在前头:对于B站上尚硅谷的webpack课程的学习笔记,推荐大家去看。
vscode的使用
- 注释 ctrl + /
- 安装live-server
- 代码格式化,使用alt+shift+f格式化。安装beautify
- 设置中打开自动保存
01 webpack简介
- 通过link标签引入.less样式文件,但是无法识别,需要将.less转为.css
- 使用npm init初始化环境,有可能出现
Sorry, name can no longer contain capital letters.
的提示,是因为命名不能有大写。 - 安装jquery:npm install jquery --save-dev
- 此时使用script标签引入.js文件报错,说不能从非模块外引入其他文件,也就是import错误,这就是es6语法,浏览器不认识的原因。所以就需要有一些工具,让浏览器不能识别的语法变成浏览器能够识别的语法。
- 因此,前端提供一个概念,构建工具,使用大工具将这些小工具都集合起来,这样只需要知道这个大工具如何使用就行了。而webpack就是这个大工具。
- js资源,样式资源,引入图片等资源,都需要用webpack来打包。
这就是入口文件,形成依赖关系树,形成chunk (代码块)。
也就是需要将依赖文件变成chunk,然后将chunk中的比如.less文件,.ts文件变成浏览器能够识别的css和js文件,这个过程叫打包,将打包文件输出,这个过程叫bundle
02 webpack五个核心概念
Entry
入口(Entry)指示webpack以哪个文件为入口起点开始打包,分析构建内部依赖图。
比如说有很多文件,但是以index.js为起点开始打包
Output
输出(Output)指示webpack打包后的资源bundles输出到哪里去,以及如何命名。
Loader
Loader(翻译官)让webpack能够去处理哪些非js文件(webpack只能理解js)
Plugins
插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩等等。也就是做其他更多的事情。
也就是说有很多文件,比如说js文件中有es6的语法,有ts文件等等。我们要告诉它一个入口文件,从那个文件开始打包。
遇到less文件,图片文件怎么办呢?使用Loader来处理这些文件。
需要压缩怎么办呢?使用插件来做。
Mode
模式分为
development(开发环境模式):让代码在本地能够进行调试。
production(生产环境模式): 能让代码优化上线运行的环境。
03 webpack初体验
-
npm init初始化包描述文件.json
-
npm i webpack@4 webpack-cli@3 -g
全局安装后面可以作为指令直接调用这两个包 -
npm i webpack webpack-cli -D
本地安装一次 -D是–save-dev的缩写 -
创建文件夹src,代表项目的源代码
-
创建文件夹build,webpack打包处理后输出的目录
-
打包需要有一个入口文件,起点文件,所以在src中建立一个index.js,作为入口起点文件。
-
书写完基本的index.js后,想要看看能不能正常运行怎么做呢?需要添加运行指令。
运行指令
开发环境: webpack ./src/index.js -o ./build/built.js --mode=development
解释:webpack会以 ./src/index.js 为入口开始打包,打包后输出到 ./build/built.js,整体打包环境是开发环境
遇到的问题:webpack : 无法加载文件 D:\nodejs\node_global\webpack.ps1,因为在此系统上禁止运行脚本。
解决:https://blog.youkuaiyun.com/weixin_43190355/article/details/100552569
至此打包成功。
关于安装:这里选择了安装4版本的webpack和3版本的webpack-cli,首先是它们版本匹配,另一个是4版本的webpack打包后会有详细的信息显示,而5里面没有。
打包信息:
重要信息:
Hash值:每次打包后会生成的唯一id。作用,用来作为文件命名的方式。
Asset:built.js 表示输出的资源
Chunks: main
这里面打包后的文件比打包前的文件大了。
看打包后的built.js代码。这里面有eval函数,表示我们之前的代码。
生产环境: webpack ./src/index.js -o ./build/built.js --mode=production
可以看到,对比开发环境,生产环境的js文件被压缩了
运行结果:
最后,想运行js文件看看,在build中写一个index.html文件,并且引入打包后的js文件,也就是built.js。
右键vscode,live-server,运行,没问题。
写一个.json文件,并使用es6语法引入。
{
"name": "jack",
"age": 18
}
注意这里引入json文件,import data,这个data就是json文件全部,这个名字可以任意取
/*
index.js: webpack入口起点文件
*/
import data from './data.json';
console.log(data);
function add(x, y) {
return x + y;
}
console.log(add(1, 2));
写完以后,需要再次打包。
这个斜杆/
\
无所谓,因为现在在windows下开发
命令: webpack .\src\index.js -o .\build\built.js --mode=development
可以看到,data.json文件也引入进来了。
在浏览器的Console中查看,可以看到,data也正确打印了。
最后试试引入样式文件 .css文件
html,body{
height: 100%;
background-color: pink;
}
import './index.css'
import data from './data.json';
console.log(data);
function add(x, y) {
return x + y;
}
console.log(add(1, 2));
执行打包命令:
发现报错了,到built.js中查看,发现抛出异常的语句。
结论:
1.webpack
只能处理js/json
资源,不能处理css/img
等其他资源。
2. 生产环境和开发环境可以将ES6模块化编译成浏览器能识别的module
。
3. 生产环境比开发环境的差别,现在看来是生产环境的js压缩了。
下面讲解如何处理打包资源。
04 打包样式资源
书写.css文件和.js文件
css文件
html, body{
margin: 0;
padding: 0;
background-color: pink;
height: 100%;
}
js文件
// 引入样式资源
import './index.css';
之前已经知道,这样是无法打包的。所以webpack如何做呢?Loader
。
Loader
能帮助webpack
识别一些无法识别的模块。
所以这里写一个webpack.config.js
文件。
webpack.config.js
注意事项:
- 他是在根目录下的文件,和所有的其他比如说存放代码的src文件夹都是同级的。
- 他就是
webpack
的配置文件。作用就是指示webpack
干哪些或(当你运行webpack
指令时,会加载里面的配置)。 - 所有的构建工具都是基于
nodejs
平台运行的。所以模块化默认采用commonjs
。 - 需要区分项目和配置的语法。项目src使用的是
ES6
语法,而配置我们使用的是commonjs
。
commonjs来写webpack的配置
书写webpack.config.js
- entry,作为入口的起点,就是说,打包从哪个文件开始,然后构成依赖关系树,然后继续打包
- output,需要指定输出的文件名和输出的路径,注意这里的输出路径要是绝对路径。因此,声明一个
resolve
变量来保存nodejs
中的require
方法。其中__dirname
是nodej
s的变量,代表当前文件的目录的绝对路径。 - module,就是loader的配置。
- plugins,插件的配置,让
webpack
更强大。 - mode,环境的选择,有生产和开发环境,开发情况下都用开发模式,因为代码可以读得懂,可以看他打包成什么样子,而生产环境就不行了,因为代码被压缩。
完整代码:
//resolve用来拼接绝对路径的方法
const {
resolve
} = require('path');
module.exports = {
// webpack配置
// 入口起点
entry: './src/index.js',
// 输出,需要输出的文件名和输出的路径
output: {
// 输出文件名
filename: 'built.js',
// 输出路径,写绝对路径,需要引入nodejs模块
//__dirname 是nodejs的变量,代表当前文件的目录绝对路径
path: resolve(__dirname, 'build')
},
//loader的配置
module:{
rules:[
//详细的loader配置
]
},
//plugins的配置
plugins:[
//详细的pulgins配置
],
//模式,二选一
//开发情况下都用开发模式,因为代码可以读得懂,可以看他打包成什么样子,而生产环境就不行了,代码被压缩
mode: 'development',
//mode: 'production'
}
大体框架搭建出来了,现在来书写loader
module: {
rules: [
//详细的loader配置
{
//1.test使用正则表达式,表示匹配哪些文件
test: /\.css$/,
//使用哪些loader
use: [
//use数组中loader执行顺序,从右到左,从下到上,依次执行。
// 3.创建style标签,然后将js中的样式资源插入进去,然后添加到head中生效。
'style-loader',
// 2.将css文件变成commonjs模块,加载到js中,里面内容是样式字符串
'css-loader'
]
}
]
},
- 第一个键值对test,表示使用的正则表达式,匹配哪些文件
- 第二个use,表示需要使用哪些loader。其中注意顺序是从右到左,从下到上依次执行。
- 各种loader需要下载。
loader下载:
由于webpack会向上找包,也就是会从当前目录,一直找到你这个项目的根目录,所以,利用这个特性,我们避免重复下载包,所以就干脆,在根目录下载包。
下载过程:
- 切换到根目录
- 在根目录初始化包描述文件。
npm init
- 下载
webpack
和webpack-cli
npm install webpack webpack-cli -D
- 下载
css-loader
和style-loader
npm install css-loader@3 style-loader@1 -D
- 切换到项目文件输入webpack 运行指令。
刚刚上面代码是exports,少写了一个s导致报错。现在,打包成功。
最后,看看样式是否生效,写一个html文件。以后会统一处理html资源的。
生效:
效果就是和前面说的一样,在head中添加了style标签。
最后的最后,梳理一下流程。
- 首先是通过
entry
将index.js
引入进来,然后entry会查看内部依赖图,也就是看看你这个js
文件import
了哪些文件。发现引入了css
资源。 - 资源通过
module
中的loader
,每一个资源都会进行处理。rules
中有test
(test
是个规则)。首先,js
资源来匹配这个正则表达式,发现js
的后缀是js
形式的,不是test中写的.css
格式的,所以js
资源不能通过loader
,接下来是css资源,发现匹配上了,就使用下面两个loader进行处理。 - 由于loader的执行顺序是下往上,右往左,所以先执行css-loader,css-loader将css文件变成commonjs模块加载到js中,里面内容是样式字符串。
- 再执行style-loader,创建style标签,将js中的样式资源插入进去,添加到head中生效。
- 然后到输出路径由output来执行。
- 所以对于webpack来说,处理资源用相应的loader就可以了。
对于less文件的处理:
less:
#title{
color:#fff;
}
js中引入
import './index.css';
import './index.less';
执行打包,发现报错。
这就是因为webpack只能识别js资源,不能识别样式资源。而这个资源是less,因此得出结论不同资源需要配置不同的loader。
所以我们需要再写一个loader配置。同时,需要下载less-loader
和less
,注意包在最外层下。npm i less-loader@5 less@3 -D
注意这里less
需要写三个loader
,因为这里需要将less
文件编译成css
文件。
module: {
rules: [
//详细的loader配置
{
//1.test使用正则表达式,表示匹配哪些文件
test: /\.css$/,
//使用哪些loader
use: [
//use数组中loader执行顺序,从右到左,从下到上,依次执行。
// 3.创建style标签,然后将js中的样式资源插入进去,然后添加到head中生效。
'style-loader',
// 2.将css文件变成commonjs模块,加载到js中,里面内容是样式字符串
'css-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
//将less文件编译成css文件
//需要下载less-loader 和less
'less-loader'
]
}
]
},
包下载好以后,执行webpack
没有问题:
一样,less文件也是创建了style标签,说明打包成功。
05 打包html资源
webpack.json.js
/*
loader: 1. 下载 2. 使用(配置loader)。
plugins:1. 下载 2. 引入 3. 使用
*/
const {
resolve
} = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
]
},
plugins: [
],
mode: 'development'
}
我们使用plugins来打包html资源。
- 首先下载
npm i html-webpack-plugin@3 -D
。 - 注意命名,它是一个类或者说是构造函数,所以用大头,引入。
const HtmlWebpackPlugin = require('html-webpack-plugin');
- 调用在plugins中 new HtmlWebpackPlugin()
这里不小心安装外部(也就是根目录)的时候,安装了webpack5,所以导致和plugin有不兼容的报错,如果以后用的话可以看这篇文章,为了方便使用,这里先安装回4版本的webpack:
https://blog.youkuaiyun.com/vv_bug/article/details/103571985
这个插件做了什么事情呢?我们webpack一下看看
重新安装了webpack4后,成功webpack。
这里显示,在buid目录下多了一个index.html资源。
而且看到,这里已经引入了built.js
因此,这个插件的功能:
- 创建一个空的html文件。
- 自动引入打包输出的所有资源(js/css)。
问题来了:我们的需求是要有结构的html文件。因此,可以加入配置选项。
plugins: [
new HtmlWebpackPlugin({
//作用复制下面的html文件, 并会自动引入打包输出的所有资源,注意,是自动。
template: './src/index.html'
})
],
再去查看build目录下的index.html,发现,他就引入了我们之前写的html文件中的内容了,这很重要,会大大方便以后的代码书写,我只需要在一个地方写个大概模板,我直接打包出来的html就会包含我所有的模板和我所有需要的js/css等资源!
成功。
最后总结它做了什么事情:
- 这个插件会自己去找我们指定的html文件。
- 找到后将内容复制下来,并且将我们需要的资源引入进来;如果是js资源就添加一个script标签引入,如果是样式就添加一个link标签引入进来,总之会自动引入。之后输出出去。
- 需要注意的点就是,我们不需要自己引入了,如果自己再引入就会引入两次,会出现问题。
- 对比loader,插件不同在于它需要引入进来,其他步骤差不多。
06 打包图片资源
已知的写法:
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$/,
use: [
'style-loader',
'css-loader',
'less-loader',
]
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
}
现在css里面呢是包含图片资源的,让我们webpack看看能不能打包成功。
看到图片报错了。
那如何做呢?webpack不能识别的资源我们首先想到的是添加loader。
因此需要添加loader:
module: {
rules: [{
test: /\.less$/,
// 使用多个loader处理用use
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 处理图片资源
test: /.\(jpg|png|gif)$/,
//处理一个loader用loader
loder: 'url-loader',
options: {
// 表示图片大小小于8kb,就会被base64处理。
limit: 8 * 1024
}
]
},
多个loader使用use,单个loader就直接用loader
base64处理:
-
优点:减少请求数量(减轻服务器压力)
-
缺点:图片体积会更大(文件请求速度慢)。
因此,选择base64图片处理通常是对比较小的图片,因为对大图片处理会使得它的大小变得更大。通常是8-12kb以下的图片使用base64处理。
对于loader需要安装的包:
-
url-loader
- file-loader
- 去最外层的根目录上 npm i url-loader@3 file-loader@5 -D
此时再打包出现一个错误:
出现错误别着急百度,先看看,上面明确提示了,在rules[1]中有一个未知的属性option,再看他下面的提示,就明白了,原来是options而不是option。
令人舒适的绿色和黄色。
但是你看:
为什么只输出了一张图片呢?哦原来是其他两张图片的大小 小于8kb导致了他们变成了base64的字符串了,就直接放在built.js中了。
可以看到,在console中看到的是这样的:
打开index.js查看,对了。
除此之外还不够,因为我们除了在css或者less中引入文件以外,我们还会在html中使用img标签来引入图片。
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>webpack</title>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
<img src="./angular.jpg" alt="angular">
</body>
</html>
我们来webpack看看。
不报错。
那就真的没有错了吗??
我们查看生成的index.html文件会发现,他的src居然还是./angular.jpg。那就不对了。因为:
我使用template来将src下的index.html复制到build下的index.html中,文件路径明显改变了,那么图片的引入路径也要改变,可是这里却没有变,所以图片无法引入。
此时页面:
因此,这样的话就会出现一个问题,它默认是处理不了html中的图片,因为它无法解析到。那怎么办呢?再加一个loader。
加一个html-loader。下载npm i html-loader@0 -D
这里有个问题,前面我们使用过html-loadr,以为它只是处理html文件的。但是不是这样的,它主要处理的其实是html文件的img图片(负责引入img,从而能被url-loader进行处理)。
module: {
rules: [{
test: /\.less$/,
// 使用多个loader处理用use
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 处理图片资源
test: /\.(jpg|png|gif)$/,
//处理一个loader用loader
loader: 'url-loader',
options: {
// 表示图片大小小于8kb,就会被base64处理。
limit: 8 * 1024
}
},
{
test: /\.html$/,
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
loader: 'html-loader'
}
]
},
再次webpack看看,看build下的index.html
会发现他变成了object Module,这是为啥呢?
**问题:**因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs语法,所以解析时会出问题[object Module]
因为默认情况下url-loader会使用es6的module来处理这个模块,而html-loader引入img的语法是commonjs的语法引入,因此,url-loader以es6的语法来解析会导致无法解析。所以url-loader中需要在options里进行处理。
**解决:**关闭url-loader的es6模块化,使用commonjs解析。
esModule: false
此时module的设置:
module: {
rules: [{
test: /\.less$/,
// 使用多个loader处理用use
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 处理图片资源
test: /\.(jpg|png|gif)$/,
//处理一个loader用loader
loader: 'url-loader',
options: {
// 表示图片大小小于8kb,就会被base64处理。
limit: 8 * 1024,
// 问题,因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs语法,所以解析时会出问题[object Module]
// 解决,关闭url-loader的es6模块化,使用commonjs解析
esModule: false
}
},
{
test: /\.html$/,
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
loader: 'html-loader'
}
]
},
此时我们再webpack
ok,完整的图片路径(根据图片内容生成的唯一hash值):
网页上看:
但是还有个需求,这个图片名字也太长了,我想要短一点的图片名字。可以,在url-loader里的options中设置name字段。
//给图片进行重命名
//[hash:10]取图片的hash值的前10位
//[ext]取文件原来扩展名
name: '[hash:10].[ext]'
再次webpack:
注意这里,webpack的优势:不会重复打包同一张图片
完整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用loader
loader: 'url-loader',
options: {
// 表示图片大小小于8kb,就会被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]'
}
},
{
test: /\.html$/,
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
loader: 'html-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
}
总结:
- 默认情况下是使用url-loader(依赖于file-loader,所以需要下载两个包)来处理图片的。
- 同时url-loader可以通过limit对图片进行限制(base64处理,有好有坏)。
- url-loader问题是无法处理html中的img图片,因此引入了html-loader来处理。
- 做法就是放在url-loader之前,将图片引入进来(url-loader无法改变图片所指的路径值)。
- 但是引进来的时候呢,html-loader使用的是commonjs语法模块化,而url-loader是es6语法,因此我们需要统一,因此需要将url-loader中的esModule关闭(设置为false)。
- 但是如果不想要图片名字那么长的话,可以重命名,可以设置哈希值取多少位。
07 打包其他资源
其他资源:比如说字体其他等,我们不需要进行其他处理,我们只需要引入就行了。
iconfont
去inconfont下载字体,下载完后,打开html文件查看如何使用。
一般来说,单色的话还是使用Font Class,如果是多色考虑Symbol,都可以。各有各的优劣,html文件中都写了。
在html文件中写class类名的时候,要用下面的,也就是点号后面的名字才行。
显示图标需要的文件放入src文件中。
开始打包
老规矩,写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: [{
//写之前考虑需要哪几个loader
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
//打包其他资源(除了html/js/css资源以外的其他资源)
{
//反向思考,我们排除css/jf/html资源
exclude: /\.(css|js|html)$/,
loader: 'file-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
}
我们webpack一下,成功地,在build目录下就会发现svg,woff等文件。
打开浏览器查看:
总结:
- 打包资源,我们就用file-loader处理
- 然后排除css、js、html、less等资源后,剩下的就是其他资源了打包即可
- 同样的,觉得名字太长就加上options。
08 devServer
我们如果想要增加新的代码,每次增加一点,就要重新webpack,加一点就要webpack。这未免也太烦人了。
因此,webpack就有一个东西,devServer,自动打包。让我们配置方便。
开发服务器 devServer:
- 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
- 特点:只会在内存中编译打包,不会有任何输出。
- 启动devServer指令为:npx webpack-dev-server,所以需要下包。
npm i webpack-dev-server@3 -D
npx webpack-dev-server运行看看:
终端在这卡住
我们现在来改一下代码,在src(打包前的)下的index.html中增加代码保存看看
就会重新执行编译,并告诉你它做了什么,编译是否成功。
js文件也一样。
但是还是有一个问题:
每次我们输入指令打开devServer后,都要自己手动打开浏览器,可不可以自动打开呢?可以,加一个open:true。现在就可以自动打开浏览器了。
最后的最后,我们把之前用webpack打包的build文件夹删除掉,再输入命令 npx webpack-dev-server,会发现,网页依然能打开,但是却没有创建build文件夹。这就是webpack-dev-server的特点,只会在内存中编译打包,不会有任何输出。
完整代码:
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
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
//打包其他资源(除了html/js/css资源以外的其他资源)
{
//反向思考,我们排除css/jf/html资源
exclude: /\.(css|js|html)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
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
}
}
09开发环境基本配置
综合前面所学。
完整配置代码:
/*
开发环境配置:能让代码运行即可。
运行项目指令:
webpack 会将打包的结果输出。
npx webpack-dev-server 只会在内存中编译打包,没有输出。
*/
//引入path中的resolve方法
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
resolve
} = require('path');
module.exports = {
// 更改
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader配置
{
// 处理less资源
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 处理css资源
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
// 处理样式中(css)的图片资源
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
// 关闭es6模块化
esModule: false,
outputPath: 'imgs'
}
},
{
// 处理html中img资源
test: /\.html$/,
// 之中又有模块化语法的冲突
loader: 'html-loader',
},
{
//处理其他资源
// 其实url-loader就是file-loader过来的,只是说url-loader专门处理图片,且可以将图片转为base64来处理。
exclude: /\.(html|js|css|less|jpg|png|gif)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'others'
}
}
]
},
//处理html资源
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 3000,
open: true
}
}
环境配置的目的:
将所有需要处理的资源写好,并使用devServer优化,让我们写代码的时候只关注代码,其他的不用关心。
写完以后需要记住,都需要在入口js文件中引入。
但是看src目录下的情况:
杂乱无章。所以划分一下目录。
然后,如何合理的更改目录呢?从index.js开始,慢慢更改就行。因为他会根据你在js文件,html文件,css文件中引入的目录去创建目录。除了js需要在webpack.config.json中特殊修改外,其他都是在那些文件中修改。
打包,看似完美,实际上还有问题。
build的内容都输出到一块了。我希望它的结构和src的目录结构是一样的。所以现在一个个调。
js文件:
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
webpack,成功
在filename中加入js目录就行。但是output只是决定js文件的输出。其他文件的话需要另外配置。
图片文件:在url-loader配置中的options中加入outputPath字段。
注意,这里的imgs我们是在css中引用的,那在html中引用的img呢?html就是另外了,他是把图片路径变成唯一的hash值去定位图片。而不是生成图片。所以html中img标签引入的图片没有输出图片,所以也就不需要指定路径。而且html-loader是生成html文件的,也不会生成图片。不要混淆了。
{
// 处理样式中(css)的图片资源
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
// 关闭es6模块化
esModule: false,
outputPath: 'imgs'
}
},
webpack:
处理其他资源也一样:
{
//处理其他资源
// 其实url-loader就是file-loader过来的,只是说url-loader专门处理图片,且可以将图片转为base64来处理。
exclude: /\.(html|js|css|less|jpg|png|gif)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'others'
}
}
webpack
ok。
但是发现没有,没有css文件结构,为啥呢?因为css文件都被打包到js文件中了,然后通过js输出一个link标签到head中,从而实现css样式的功能。
总结:
- 以entry作为入口,然后所有的路由都会输出到output指定的文件中。
- 其中图片资源会经过url-loader的处理,会单独输出出去,输出到哪里去呢?输出到output指定的目录下(上面例子是build中)。但是文件名会采用自己的hash值。如果想要输出到output目录下(build目录下)的指定文件夹中呢?就要在options中添加outputPath,指定自己想要输出的文件夹。
- 同样的,其他资源同理。
- 只有js文件输出到指定目录的方式不同,需要在output中修改,在output下的filename中添加目录名即可。
10构建环境介绍
生产环境介绍,由于现阶段只是使用开发环境,因此这部分以后的内容,后面需要用到再进行学习。
附录
基本的包:
{
"name": "three_writing",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack serve --open chrome.exe"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.13.15",
"@babel/preset-env": "^7.13.15",
"@types/stats.js": "^0.17.0",
"@types/three": "^0.127.1",
"@types/typescript": "^2.0.0",
"babel-loader": "^8.2.2",
"copy-webpack-plugin": "^6.4.1",
"core-js": "^3.10.1",
"css-loader": "^3.6.0",
"file-loader": "^5.1.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"less": "^3.13.1",
"less-loader": "^5.0.0",
"stats.js": "^0.17.0",
"style-loader": "^1.3.0",
"three": "^0.127.0",
"ts-loader": "^6.2.2",
"typescript": "^3.9.9",
"url-loader": "^3.0.0",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.2"
},
"dependencies": {
"-": "0.0.1",
"@types/clean-webpack-plugin": "^0.1.3",
"D": "^1.0.0",
"clean-webpack-plugin": "^4.0.0-alpha.0"
}
}