静态资源
js文件(js jax coffee ts)
css文件 (css less scss)
images文件(jpg png gif bmp)
字体文件(svg ttf ect woff)
模板文件(ejs jade vue)
资源多了之后,网页会发起很多二次请求,导致网页加载速度慢。
同时需要处理各种包之前的依赖关系。
可以通过合并,压缩依赖包,把小图片合并成精灵图,小图片转成base64编码;
使用requireJS或者webpack解决复杂的依赖关系;
webpack:前端的项目构建工具,基于node.js开发出来的前端工具,基于node运行;
Gulp,基于task任务;适合小任务点,灵活处理;
安装
npm i webpack -g 全局安装
npm i webpack --save-dev 安装到项目中
npm install webpack-cli -g 还需要安装这个东西,应该是新版本的webpack需要使用
项目结构:
webpack
src 源代码
css
js
images
index.html
main.js:项目的js入口文件
dist 发布的文件
在webpack目录中打开cmd,运行
npm init -y
-y 的含义:yes的意思,在init的时候省去了敲回车的步骤,生成的默认的package.jsonnpm i jquery -S
//安装jquery
其中第一句,在node开发中使用npm init会生成一个pakeage.json文件,这个文件主要是用来记录这个项目的详细信息的,它会将我们在项目开发中所要用到的包,以及项目的详细信息等记录在这个项目中。方便在以后的版本迭代和项目移植的时候会更加的方便。也是防止在后期的项目维护中误删除了一个包导致的项目不能够正常运行。使用npm init初始化项目还有一个好处就是在进行项目传递的时候不需要将项目依赖包一起发送给对方,对方在接受到你的项目之后再执行npm install就可以将项目依赖全部下载到项目里。
package name: 你的项目名字叫啥
version: 版本号
description: 对项目的描述
entry point: 项目的入口文件(一般你要用那个js文件作为node服务,就填写那个文件)
test command: 项目启动的时候要用什么命令来执行脚本文件(默认为node app.js)
git repository: 如果你要将项目上传到git中的话,那么就需要填写git的仓库地址(这里就不写地址了)
keywirds: 项目关键字(我也不知道有啥用,所以我就不写了)
author: 作者的名字(也就是你叫啥名字)
license: 发行项目需要的证书(这里也就自己玩玩,就不写了)
完善main.js脚本
// 项目的js入口文件
// 1.导入Jquery
// import *** from *** es6中导入模块的方式
import $ from 'jquery'
// const $ = require('jquery');
$(function (argument) {
$('li:odd').css('backgroundColor','lightblue')
$('li:even').css('backgroundColor',function(){
return '#' + 'D97634'
})
})
完善index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewpoint" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webpack</title>
<!-- 不可以在这里引用任何包和css文件 -->
</head>
<body>
<ul>
<li>list</li>
<li>list</li>
<li>list</li>
<li>list</li>
<li>list</li>
<li>list</li>
<li>list</li>
<li>list</li>
<li>list</li>
<li>list</li>
</ul>
</body>
</html>
通过webpack工具,把main.js进行处理,生成一个bundle.js文件,如下:
在项目根目录webpack文件夹中执行:
webpack .\src\main.js .\dist\bundle.js(某些终端命令中,注意路径)
webpack ./src/main.js ./dist/bundle.js 在终端窗口中
提示:webpack : 无法加载文件 C:\Users\AppData\Roaming\npm\webpack.ps1,因为在此系统上禁止运行脚本;
解决:管理员身份运行powershell,输入 set-ExecutionPolicy RemoteSigned 接着提示中输入Y,即可
如果出现错误:安装“npm install -g @vue/cli”发生npm WARN deprecated request@2.88.2: request has been deprecated;
可以尝试,配置淘宝镜像:npm config set registry https://registry.npm.taobao.org;配置完成后检验是否成功:npm config get registry;
错误1
大概就是上面这种情况,原因就是当前的webpack是5.65.0版本,需要修改命令,然后修改命令如下:
webpack ./src/main.js -o ./dist/bundle.js
。
错误2
使用以上命令后又出现了下面的提示
大概就是没有设置生产模式还是开发模式的问题。
可以在package.json中增加
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
然后再增加打包配置文件webpack.config.js,就是下面说的,然后增加模式
const path = require('path')
module.exports = {//通过node中的模块操作,向外暴漏了一个配置对象
entry:path.join(__dirname,'./src/main.js'), //webpack打包的文件
output:{//输出文件相关的配置
path:path.join(__dirname,'./dist'),//输出目录
filename:'bundle.js',//指定文件的名字
},
mode: 'development' // 设置mode
}
然后再执行 webpack,解决
然后,运行之前的命令(webpack ./src/main.js ./dist/bundle.js)。
修改引用对应的文件:
<!-- 由于main.js中使用了es6的语法,浏览器不支持 -->
<!-- <script type="text/javascript" src="./main.js"></script> -->
<script type="text/javascript" src="./dist/bundle.js"></script>
webpack的作用:
- 可以处理js文件之前的依赖关系;
- 把js的兼容问题进行处理,高级别不识别的语法可以转换为浏览器可以识别的版本;(webpack 要打包的文件的路径 打包好文件的输出目录)
webpack配置文件
在工程项目根目录中,增加webpack.config.js文件:
webpack指令执行时,不指定入口和出口,则去查找配置文件,解析文件得到配置对象,得到入口和出口,然后打包构建。
const path = require('path')
module.exports = {//通过node中的模块操作,向外暴漏了一个配置对象
entry:path.join(__dirname,'./src/main.js'), //webpack打包的文件
output:{//输出文件相关的配置
path:path.join(__dirname,'./dist'),//输出目录
filename:'bundle.js',//指定文件的名字
}
}
再打包时,可以只运行webpack命令即可。
webpack-dev-server工具
该工具可实现自动打包的功能
安装:npm i webpack-dev-server -D 把工具安装到项目的本地依赖(本地安装时,无法当作脚本任务在powershell中执行,只有安装时-g可以在powershell中安装);用法和webpack的用法一样;
本地安装webpack: npm i webpack -D
(本地安装时提示:Refusing to install package with name “webpack” under a package;可以修改工程package.json的name属性,修改为webpack外的其他名字即可)
需要安装项:
- npm i -D
- npm i webpack -D
- npm i webpack-cli -D
- npm i webpack-dev-server -D
增加启动项在package.json中:
然后运行指令:
npm run dev
运行后发现报错,找不到模块,最后使用以下的版本
"webpack": "^4.32.2",
"webpack-cli": "^3.3.2",
"webpack-dev-server": "^3.5.1"
运行结果:
可以直接在网址中访问,弹出的界面中选择src即可进入界面:
修改main.js发现没有改变,需要修改html中的bundel.js的路径:
<script type="text/javascript" src="/bundle.js"></script>
webpack-dev-server会打包生成bundle.js的文件,没有在物理磁盘中,而是托管到了内存中,以虚拟的形式在项目根目录中,可以认为与dist src等同级;
常用启动参数
运行后打开浏览器 --open
修改端口 --port 3000
修改运行根目录 --contentBase src
浏览器无刷新重载 --hot
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --open --port 3000 --contentBase src"
},
第二种方式为修改配置文件webpack.config.js(不推荐)
添加devServer和plugins属性
const path = require('path')
const webpack = require('webpack')//启用热更新 的第二步
module.exports = {//通过node中的模块操作,向外暴漏了一个配置对象
entry:path.join(__dirname,'./src/main.js'), //webpack打包的文件
output:{//输出文件相关的配置
path:path.join(__dirname,'./dist'),//输出目录
filename:'bundle.js',//指定文件的名字
},
devServer:{//这是配置dev-server参数的第二种方式,相对麻烦
open:true,//自动打开浏览器
port:3000,//设置启动的运行端口
contentBase:'src',//指定托管的根目录
hot:true,//启用热更新 的第一步
},
plugins:[//配置插件的节点
new webpack.HotModuleReplacementPlugin() //新建 一个热更新模块对象,启用热更新 的第三步
]
}
html-webpack-plugin插件
- 在内存中根据指定页面在内存中生成页面
- 自动 把打包好的bundle.js 追加到页面中,不需要手动引用(index中可以省略<< script type=“text/javascript” src="/bundle.js">< /script >)
在本地安装插件:npm i html-webpack-plugin -D
在配置文件中增加插件对象:
const path = require('path')
const webpack = require('webpack')//启用热更新 的第二步
const webpackPlugin = require('html-webpack-plugin'),//导入内存中生成html页面的插件,插件需要放到plugin节点中去
module.exports = {//通过node中的模块操作,向外暴漏了一个配置对象
entry:path.join(__dirname,'./src/main.js'), //webpack打包的文件
output:{//输出文件相关的配置
path:path.join(__dirname,'./dist'),//输出目录
filename:'bundle.js',//指定文件的名字
},
devServer:{//这是配置dev-server参数的第二种方式,相对麻烦
open:true,//自动打开浏览器
port:3100,//设置启动的运行端口
contentBase:'src',//指定托管的根目录
hot:true//启用热更新 的第一步
},
plugins:[//配置插件的节点
new webpack.HotModuleReplacementPlugin(), //新建 一个热更新模块对象,启用热更新 的第三步
new webpackPlugin({//创建一个插件
template:path.join(__dirname,'./src/index.html'),//指定模板页面,将来会根据页面的路径,在内存中创建html
filename:'index.html' //指定生成的html的名字
})
]
}
//webpack指令执行时,不指定入口和出口,则去查找配置文件,解析文件得到配置对象,得到入口和出口,然后打包构建
样式的应用
webpack默认只能打包js类型的文件,不能处理其他类型文件
处理非js文件,需要安装第三方加载器
- 打包处理css文件,需要安装style-loader css-loader
- webpack.config.js里面新增一个配置节点,module对象,里面有个rules属性(数组),存放了所有第三方文件的匹配和处理规则。
- 在main.js中导入css文件的路径
index.css
li{
list-style: none;
}
main.js:
import './css/index.css'
webpack.config.js
添加module节点
const path = require('path')
const webpack = require('webpack')
const webpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:path.join(__dirname,'./src/main.js'),
output:{
path:path.join(__dirname,'./dist'),
filename:'bundle.js',
},
devServer:{
open:true,
port:3100,
contentBase:'src',
hot:true
},
plugins:[
new webpack.HotModuleReplacementPlugin(),
new webpackPlugin({
template:path.join(__dirname,'./src/index.html'),
filename:'index.html'
})
],
module:{//用于配置所有的第三方模块加载器
rules:[//第三方的匹配规则
{test: /\.css$/,use:['style-loader','css-loader']},//匹配css结尾的文件的处理规则(使用style-loader和css-loader)
{test: /\.less$/,use:['style-loader','css-loader','less-loader']},
{test: /\.scss$/,use:['style-loader','css-loader','sass-loader']},
]
}
}
匹配后规则调用的顺序为由右向左,即先调用css-loader,在调用style-loader,最后一个处理后,交给webpack打包,放到bundle.js中。
less文件的处理规则less-loader less;
安装npm i less less-loader -D
scss文件的处理规则sass-loader less;
安装npm i node-sass sass-loader -D
index.less
ul{
padding:0;
margin:0;
}
index.scss
html,body{
margin:0;
padding:0;
li{
font-size:12px;
line-height:30px;
}
}
main.js
import './css/index.less'
import './css/index.scss'
url
图片
默认webpack无法处理url相关地址;
需要添加url-loader插件;
项目根路径安装:npm i url-loader file-loader -D
在webpack.config.js中增加匹配规则:
{test: /\.(jpg|png|gif|bng|jpeg)$/,use:'url-loader?limit=8000&name=[hash:8]-[name].[ext]'},
- 处理图片路径的规则,limit是图片的大小,单位是byte,如果引用的图片大于等于limit的值,则不会转为base64的字符串
- 其中name为保持原图片的名称不变(而不是hash值),ext保持图片后缀不变,同时图片名字前面加上8位哈希值(最长为8位)
同样webpack5又出问题了,图片不显式,屏蔽以上的图片加载配置规则,如下配置:
{
test:/\.(jpg|png|gif)$/,
type:"asset",
//解析
parser: {
//转base64的条件
dataUrlCondition: {
maxSize: 25 * 1024, // 25kb
}
},
generator:{
//与output.assetModuleFilename是相同的,这个写法引入的时候也会添加好这个路径
filename:'img/[name].[hash:6][ext]',
//打包后对资源的引入,文件命名已经有/img了
publicPath:'./'
},
},
图标
安装bootstrap:npm i bootstrap -D
使用内存中的html,可以理解为在项目根目录存在一个index.html和bundle.js,所以配置的托管目录可以不用增加,即可以省略wepack.json中的 --contentBase src;
"dev2": "webpack-dev-server --open --port 3010",
引入bootsrap,在main.js中添加
import 'bootstrap/dist/css/bootstrap.css'
引用node_modules中相关的文件,可以直接省略 路径前的node_modules这一层目录;
还需要处理字体文件,webpack.config.js中增加配置:
{text:/\.(ttf|eot|svg|woff|woff2)&/,use:'url-loader'}
index.css样式文件
.div1{
background-image: url('../image/tr.jpg');
background-size: cover;
width:200px;
height: 200px;
}
index.html文件
<body>
<div class="div1">
</div>
<span class="glyphicon glyphicon-heart" aria-hidden="true"></span>
</body>
运行后发现样式无效,查找问题一直没找到原因,试了下安装bootstrap的方式:
npm i bootstrap@3 -D
安装后出现效果,不知道什么原因
babel的配置
在main.js文件中增加如下脚本:
class Person {
//使用static关键字定义静态属性:可以直接通过类名访问的属性
//实例属性,只能通过类名进行访问的属性
static info = {name:'Tom', age: "13"}
}
class 是es6中的新语法,用来实现es6中面向对象编程的方法;
webpack默认只能处理部分es6语法,需要借助于第三方loader处理;
通过babel,可以将高级语法转换为低级语法
- npm i babel-core babel-loader babel-plugin-transform-runtime -D
- npm i babel-preset-env babel-preset-stage-0 -D
第一条为转换工具,第二个安装的是语法;
babel-preset-env 是新es语法,babel-preset-es2015为之前的语法;
打开webpack文件,在module节点的rules中,添加规则:
{test:/\.js$/,use:'babel-loader',exclude:/node_modules/}
exclude:/node_modules/的意思为不包含node_modules中的文件,打包的话会很消耗cpu,打包速度慢
在项目根目录中新建一个.babelrc的配置文件,必须符合json的规则,其中配置
{
"presets":["env","stage-0"],
"plugins":["transform-runtime"]
}
运行后发现报错,无法找到模块:
Error: Cannot find module ‘@babel/core’;
重新安装指定loader版本:
npm i babel-loader@7 -D
解决问题。
还有个问题,需要注意增加的babelrc文件,文件的名字为.babelrc,没有其他后缀;
webpack5貌似可以直接使用
执行打包命令
删除dist文件夹,
再执行webpack 命令,可重新打包