前言
前面是解析和步骤,可以直接看总结复制文件
webpack是什么
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
简而言之:webpack是基于node构建前端项目的工具
webpack的作用
- 可以减少二次请求,可以处理错综复杂的依赖关系
- 可以将高一级语法(es6)装换成低一级语法
- 可以完美实现资源的合并、打包、压缩、混淆等诸多功能
四个概念
入口、输出、loader、插件
开发环境和生产环境
- 开发环境:程序猿们专门用于开发的服务器,配置可以比较随意。(项目尚且在编码阶段)–package.json的devDependencies向开发环境添加依赖(-D || --save-dev)
- 生产环境:是指正式提供对外服务的,项目上线到真实环境。(客户可以使用,访问,正式上线)–package.json的dependencies项目所要依赖的包(-S || --save)
文档
Basic
- 初始化package.json
cnpm init -y
- 全局安装webpack
cnpm i webpack webpack-cli -g
webpack从第四版开始webpack和webpack-cli是分开来管理的
3. 本地安装webpack
cnpm i webpack webpack-cli -D
- 项目目录
- 下载jQuery
cnpm i jquery -S
我们使用jquery来进行开发
6. webpack.config.js
const path = require('path')
const webpack = require('webpack') //用于访问内置插件
// const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:path.join(__dirname,'/src/main.js'),//入口
output:{//出口
path:path.join(__dirname,'/dist'),
filename:'bundle.js'
}
}
+ path.join() 方法使用平台特定的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。
+ path.resolve() 方法将路径或路径片段的序列解析为绝对路径。
+ __dirname是当前目录,__filename是全路径,包含文件名
+ 我们通过 output.filename 和 output.path 属性,来告诉 webpack bundle 的名称,以及我们想要 bundle 生成(emit)到哪里
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack</title>
</head>
<body>
<ul>
<li>使用jquery实现隔行变色</li>
<li>使用jquery实现隔行变色</li>
<li>使用jquery实现隔行变色</li>
<li>使用jquery实现隔行变色</li>
<li>使用jquery实现隔行变色</li>
<li>使用jquery实现隔行变色</li>
<li>使用jquery实现隔行变色</li>
<li>使用jquery实现隔行变色</li>
</ul>
</body>
<script src="../dist/bundle.js"></script>
</html>
运行webpack到时会在dist文件生成一个bundle.js(是由main.js生成的)
8. main.js
import $ from 'jquery'
$(function(){
$('li:odd').css('background','red')
$('li:even').css('background',function(){
return '#' + 'D97634'
})
})
实现隔行变色
9. 运行webpack
$ webpack
此时在dist会生成一个bundle.js文件,在index.html已经引入了
可以使用git输入webpack,也可以使用vscode…
10. 结果
在浏览器打开index.html
配置本地服务器
- webpack-dev-server
在项目根目录下载
cnpm i webpack-dev-server -D
在package.json配置"script"
"dev": "webpack-dev-server --open --port 3000 --hot"
open : 实现帮我们自动打开浏览器;port :自定义端口号;hot :实现下载热更新,生成的bundle局部刷新(使用–contentBase比较繁琐,需要指定根目录,而且会使用script引入物理磁盘的bundle.js,发送二次请求)
- html-webpack-plugin
cnpm i html-webpack-plugin -D
能够生成一个index.html内存的页面,然后把打包好的bundle.js注入到页面中
- 做一步测试一步
webpack.config.js
const path = require('path')
const webpack = require('webpack') //用于访问内置插件
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:path.join(__dirname,'/src/main.js'),//入口
output:{//出口
path:path.join(__dirname,'/dist'),
filename:'bundle.js'
},
plugins:[
new htmlWebpackPlugin({
template:path.join(__dirname,'/src/index.html'),
filename:'index.html'
})
]
}
package.json
{
"name": "01webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --open --port 3000 --hot"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.1.14"
},
"dependencies": {
"jquery": "^3.3.1"
}
}
把index.html的script注释掉
<!-- <script src="../dist/bundle.js"></script> -->
运行服务器
cnpm run dev
会自动帮我们打开浏览器,此时注释掉引入的bundle.js依旧不影响,因为在内存生成的页面自动帮我们引入了
loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
当我们想要引入css文件时,如果直接使用link就会发起二次请求,而且像scss,less浏览器识别不了,loader可以让webpack进行处理,将其在js文件中引入,转换为webpack能够处理的模块
- loader 能够 import 导入任何类型的模块(例如 .css 文件),这是 webpack 特有的功能
- 上面plugins是放入我们的插件的,module是配置第三方所有的模块加载器
在更高层面,在 webpack 的配置中 loader 有两个目标:
1.test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
2.use 属性,表示进行转换时,应该使用哪个 loader。
.css,.scss,.less文件的处理
cnpm i style-loader css-loader -D
cnpm i less less-loader -D
cnpm i node-sass sass-loader -D
webpack.config.js
module:{
rules:[
{test:/\.css$/,use:['style-loader','css-loader']},//从右向左解析,顺序不能乱
{test:/\.less$/,use:['style-loader','css-loader','less-loader']},
{test:/\.scss$/,use:['style-loader','css-loader','sass-loader']}
]
}
接着在src的目录新建reser.css文件
reset.css
li{
list-style: none;
}
在main.js文件引入
import './css/reset.css'
运行服务器
cnpm run dev
在css文件夹下新街reset.less
*{
margin: 0;
padding: 0;
}
main.js
import $ from 'jquery'
import './css/reset.css'
import './css/reset.less'
$(function(){
$('li:odd').css('background','red')
$('li:even').css('background',function(){
return '#' + 'D97634'
})
})
刷新浏览器
图片和字体文件
默认情况下,webpack无法处理文件中的url地址,不管是图片还是字体库
cnpm i url-loader file-loader -D
webpack.config.js
{ test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=7631&name=[hash:8]-[name].[ext]' },
//?后面的参数,limit(小于7632时会转为base64,大于的话则不会转换)
//name(使用我们原来的名字),如果重名会导致图片替换,所以使用八位哈希值
{test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' } // 处理 字体文件的 loader
- 我们在index.html放入一个div,放一个背景图片
结果给一个八位的哈希值,名字和后缀名没变,如果不加limit限制,全部转为base64编码 - 字体(bootstrap为例子)
cnpm i bootstrap@3 -S
main.js引入
import 'bootstrap/dist/css/bootstrap.css'
// 不加node_modules,默认就会去 node_modules 中查找
index.html使用引入字体
<span class="glyphicon glyphicon-heart"></span>
使用更高级的es6语法
模拟面向对象
在main.js使用class
class Animal {
static mystatic
constructor(name){
this.name = name
}
say(){
console.log('haha')
}
}
let a = new Animal('spike')
console.log(a)
刷新浏览器,结果报错
- webpack只能处理一部分es6语法,一些高级的es6语法和es7语法是无法处理的,这时候需要第三方的loader来处理把高级语法处理成更低级语法,交给webpack打包成bundle.js
- 下载两套成对的包
cnpm i babel-core babel-loader@7 babel-plugin-transform-runtime -D
cnpm i babel-preset-env babel-preset-stage-0 -D
现在babel-loader是版本8,下载的包不一样;我们使用原先的版本7;第一套包是转换,第二套相当于字典,包含所有和es相关的语法
3. 在项目根目录下新建.babelrc,这是一个json文件
{
"presets":["env","stage-0"],
"plugins":["transform-runtime"]
}
- 在webpack.config.js配置
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }, // 配置 Babel 来转换高级的ES语法
- cnpm run dev
- 结果打印n {name: “spike”},解决。
总结
- webpack.config.js(项目根目录)
const path = require('path')
const htmlWepackPlugin = require('html-webpack-plugin')
module.exports = {
entry:path.join(__dirname,'/src/main.js'),//入口
output:{//出口
path:path.join(__dirname,'/dist'),
filename:'bundle.js'
},
plugins:[
new htmlWepackPlugin({
template:path.join(__dirname,'/src/index.html'),
filename:'index.html'
})
],
module:{
rules:[
{test:/\.css$/,use:['style-loader','css-loader']},
{test:/\.less$/,use:['style-loader','css-loader','less-loader']},
{test:/\.scss$/,use:['style-loader','css-loader','sass-loader']},
{ test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=500&name=[hash:8]-[name].[ext]' },
//?后面的参数,limit(小于7632时会转为base64,大于的话则不会转换)
//name(使用我们原来的名字),如果重名会导致图片替换,所以使用八位哈希值
{test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' }, // 处理 字体文件的 loader
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }, // 配置 Babel 来转换高级的ES语法
]
}
}
- package.json(项目根目录)
里面有项目所要依赖的包,一般我们直接可以使用"cnpm i"下载所有的包,初始化使用"cnpm init -y"
{
"name": "01webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --open --port 3000 --hot"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^2.1.0",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"node-sass": "^4.11.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.1.14"
},
"dependencies": {
"bootstrap": "^3.4.0",
"jquery": "^3.3.1"
}
}
- .babelrc(项目根目录)
{
"presets":["env","stage-0"],
"plugins":["transform-runtime"]
}
- 目录
- 其它
node_modules管理项目的包,main.js是入口文件,dist是出口文件夹,src是网站内容 - cnpm run dev