JS:.js .jsx .coffee .ts(TypeScript 类c#语言)
CSS:.css .less .sass .scss
Images:.jpg .jpeg .png .gif .bmp
字体文件(Fonts): .svg .ttf .eot .woff .woff2
模板文件: .ejs .jade .vue
网页中会引用很多静态资源,当静态资源多了以后,因为要发起很多的二次请求,就会导致网页加载速度慢,同时还要处理各种错综复杂的依赖关系,webpack可以帮助解决这些问题
webpack是前端的一个项目构建工具,是基于node.js开发出来的一个前端工具。
借助于webpack这个前端自动化构建工具,可以完美的实现资源的合并、打包、压缩、混淆等诸多功能
1、运行 npm i webpack -g 全局安装webpack,这样可以全局使用 webpack命令
安装完webpack 需要安装一个webpack-cli
npm install webpack-cli -g
因为在webpack 3中,webpack本身和它的CLI以前都是在同一个包中,但在第4版中,他们已经将两者分开来更好地管理它们。
2、在项目根目录中,运行 npm i webpack --save-dev 安装到项目依赖中,本地也需要安装webpack-cli
1、建一个文件夹(webpack-study)来存放我们的项目。(已全局安装webpack)
2、webpack-study文件夹 下创建dist文件夹和src文件夹。
3、src文件夹 下创建css、js、images文件夹,index.html(项目入口文件)、 main.js(项目js入口文件)
4、依赖jQuery实现列表隔行变色功能,需要安装一下jQuery,打开终端,运行以下命令:
npm init -y
npm i jquery -s
运行完以后会在webpack-study文件夹下,有一个node_modules文件夹,里面装了jquery包。
且在webpack-study文件夹下,多了一个package-lock.json文件
5、导入jQuery
注意:以前我们都是直接在index.html文件中直接用script标签引入要用的js文件,但是在应用webpack的时候,不推荐在index.html中直接引入任何包和css文件。
而是在main.js文件中利用import导入要用的任何包和CSS文件,然后在index.js中只引入main.js就行。
main.js
// main.js 是项目的JS入口文件
// 导入jquery
// import *** from *** 是ES6中导入模块的方式
// 由于ES6代码太高级,浏览器解析不了,所以执行这一行的时候会报错
import $ from 'jquery'
// 相当于node.js中的 const $ = require('jquery')
$(function () {
// odd奇数 但li标签索引从0开始
$('li:odd').css('backgroundColor', '#F0F');
// even偶数
$('li:even').css('backgroundColor', function () {
return '#0FF';
})
})
index.js
Document
- 这是第1个li
- 这是第2个li
- 这是第3个li
- 这是第4个li
- 这是第5个li
- 这是第6个li
- 这是第7个li
- 这是第8个li
- 这是第9个li
- 这是第10个li
此时还没有bundle.js文件
6、webpack-最基本的配置文件的使用:在webpack-study文件夹下,创建一个webpack.config.js文件
(1)webpack能够处理JS文件的相互依赖关系
(2)webpack能够处理JS的兼容问题,把高级的、浏览器不识别的语法,转为低级的,浏览器能正常识别的语法
(3)这个配置文件,其实就是一个JS文件,通过node中的模块操作,向外暴露了一个配置对象
(4)在配置文件中需要指定 入口 和 出口
// webpack.config.js
const path = require('path')
module.exports = {
// 入口:表示要使用webpack打包哪个文件
entry: path.join(__dirname, './src/main.js'),
// 出口:输出文件的相关配置
output: {
// 指定打包好的文件,输出到哪个目录中去
path: path.join(__dirname, './dist'),
// 指定输出的文件名称
filename: 'bundle.js'
}
}
在终端运行webpack命令,这样在dist文件下就生成了一个bundle.js文件
此时用浏览器打开index.js文件就可以看见页面渲染效果了。
但是有一个问题是:我们每改变一次main.js文件,就要重新运行一次webpack命令
运行npm i webpack-dev-server -D 把这个工具安装到项目的本地开发依赖
这个工具要想正常运行,需要先在本地安装webpack和webpack-cli
将webpack-dev-server命令配置到package.json文件中:配置dev这个命令,这样就可以在终端直接npm run dev 就可以运行webpack-dev-server了
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server" //在package.json文件中配置这一行命令
},
红框中说明项目本地运行地址,在浏览器中输入 http://localhost:8080/ 就可以打开项目
绿框中说明webpack打包输出的文件在该项目根路径下,下面绿字说明打包生成的文件为bundle.js
所以:在index.html中要将换成
这个bundle.js文件是托管在项目的根路径下,所以我们看不见这个文件,但是这个文件存在,可以在浏览器中输入地址http://localhost:8080/bundle.js打开文件。
运行完npm run dev以后,我们改动main.js文件中的内容,保存以后,项目就会自动运行,重新打包生成新的bundle.js文件替换原来的
但是,运行npm run dev以后,需要我们手动点击http://localhost:8080/ 才可以打开项目。
在package.json文件中配置:
"dev": "webpack-dev-server --open" 运行npm run dev 会自动打开浏览器
"dev": "webpack-dev-server --open --port 3000" 运行npm run dev 会自动打开浏览器,此时的端口号为3000
"dev": "webpack-dev-server --open --port 3000 --contentBase src" --contentBase src指定运行的根路径,这样打开http://localhost:3000/就直接是我们的项目主页面了,因为src文件夹下有index.html
"dev": "webpack-dev-server --open --contentBase src --hot" --hot 添加这个命令以后,更新main.js中的代码,自动运行不会重新生成bundle.js文件替换之前的bundle.js文件,而是以补丁的形式更新
9、webpack-dev-server配置命令的第2种方式(了解即可)
package.json中:
"dev": "webpack-dev-server"
在webpack.config.js中配置
index.html是物理磁盘上的HTML页面,但bundle.js是托管到内存中的文件,那么,如何把HTML页面也导入到内存中呢?
(1)安装插件 npm i html-webpack-plugin -D
(2)在webpack.config.js中配置
// webpack.config.js
const path = require('path')
// 导入在内存中生成HTML页面的插件
// 只要是插件,都一定要放到plugins节点中去
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// 入口:表示要使用webpack打包哪个文件
entry: path.join(__dirname, './src/main.js'),
// 出口:输出文件的相关配置
output: {
// 指定打包好的文件,输出到哪个目录中去
path: path.join(__dirname, './dist'),
// 指定输出的文件名称
filename: 'bundle.js'
},
// 配置插件的节点,是一个数组
plugins: [
// 创建一个在内存中生成HTML页面的插件
new htmlWebpackPlugin({
// 指定模板页面,将来会根据指定的模板路径,去生成内存中的页面
template: path.join(__dirname, './src/index.html'),
// 指定生成的页面的名称
filename: 'index.html'
})
]
}
当使用了这个插件以后,我们就不需要手动处理bundle.js的引用路径了,因为这个插件,已经自动帮我们创建了一个合适的script,并引用了正确的bundle.js的路径。因此就可以把物理磁盘中的index.html中注释掉了。
运行npm run dev,打开页面以后,可以查看页面源代码,我们就会发现:
内存中的index.html比我们磁盘中的index.html,在body底部多了一行
下面为内存中的index.html
Document
- 这是第1个li
- 这是第2个li
- 这是第3个li
- 这是第4个li
- 这是第5个li
- 这是第6个li
- 这是第7个li
- 这是第8个li
- 这是第9个li
- 这是第10个li
html-webpack-plugin插件的两个基本作用是:
(1)自动在内存中根据指定页面生成一个内存中的页面
(2)自动把打包好的bundle.js追加到页面中去
在css文件夹下,建一个index.css文件,以前我们是在index.html中直接用link引入CSS文件,但是这样会发起二次请求,所以不建议这样做。
在mian.js中,使用import导入index.css
// 使用import语法,导入CSS样式表
import './css/index.css'
注意:webpack,默认只能打包处理JS类型的文件,无法处理其他的非JS类型的文件;
如果要处理非JS类型的文件,需要手动安装一些合适的第三方loader加载器;
(1)如果想要打包处理 CSS 文件,需要安装 npm i style-loader css-loader -D
(2)打开 webpack.config.js 这个配置文件,在里面新增一个配置节点,叫做module,是一个对象;在这个module对象身上,有个rules属性,是个数组,在这个数组中,存放了所有第三方文件的匹配和处理规则
在webpack.config.js文件的exports中增加module:
// 这个节点,用于配置 所有第三方模块加载器
module: {
// 所有第三方模块的 匹配规则
rules: [
// 配置处理.css文件的第三方loader规则
{ test: /\.css$/, use: ['style-loader', 'css-loader']}
]
}
例如,在处理CSS文件,找到对应规则后,会先调用'css-loader',然后把处理结果给'style-loader',调用'style-loader'处理完以后,直接交给webpack进行打包合并,输出到bundle.js中去。
(1)在css文件夹下建一个文件index.less,写一些样式,然后,在mian.js中,使用import导入index.less
// 使用import语法,导入less样式表
import './css/index.less'
(2)装包
npm i less-loader -D
npm i less -D
(3)配置规则
// 配置处理.less文件的第三方loader规则
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},
(1)在css文件夹下建一个文件index.scss,写一些样式,然后,在mian.js中,使用import导入index.scss
// 使用import语法,导入SCSS样式表
import './css/index.scss'
(2)装包
npm i sass-loader -D
cnpm i node-sass -D (一般这一步用npm会装不成功,用cnpm比较好)
(3)配置规则
// 配置处理.sass/.scss文件的第三方loader规则
{ test: /\.s[a|c]ss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
默认情况下,webpack无法处理CSS文件中的URL地址,不管是图片还是字体库,只要是URL地址,都处理不了
(1)npm i url-loader file-loader -D
file-loader是url-loader的内部依赖
// 配置处理图片路径的loader
{ test: /\.(jpg|jpeg|png|gif|bmp)$/, use: 'url-loader' }
这个时候审查发现,图片路径转码成base64格式了
(2)限制图片转码
可以给url-loader传参,限制图片转码为base64格式的字符串
// 配置处理图片路径的loader
{ test: /\.(jpg|jpeg|png|gif|bmp)$/, use: 'url-loader?limit=15735' }
limit给定的值,是图片的大小,单位是byte,如果引用的图片大小,大于等于给定的limit值,则不会被转码为base64格式的字符串,如果图片小于给定的limit值,则会被转码为base64格式的字符串
但是我们发现,此时URL中图片名称不是我们引入的图片名称,这是webpack打包的时候,为了防止图片的重名,自动为每一个图片生成一个hash值作为图片名
(3)设置打包时,图片名称不变
// 配置处理图片路径的loader
{ test: /\.(jpg|jpeg|png|gif|bmp)$/, use: 'url-loader?limit=15735&name=[name].[ext]' }
传递另一个参数name,[name]表示引入的图片名称是啥,打包后就是啥,[ext]表示引入的图片后缀是啥,打包后还是啥。
但是这种情况下存在一个问题就是:如果存在不同路径下的重名的图片,打包后,后面的图片会把前面的同名图片覆盖掉
(4)设置打包后的图片名称
// 配置处理图片路径的loader
{ test: /\.(jpg|jpeg|png|gif|bmp)$/, use: 'url-loader?limit=15735&name=[hash:8]-[name].[ext]' }
[hash:8]-[name]表示打包后在每个图片名称不变,但在前面用短横线链接一个8位的hash值,防止图片名称。hash值最长32位
(1)安装bootstrap3 npm install bootstrap@3
(2)在index.html中应用bootstrap中的图标
(3)bootstrap中的图标依赖bootstrap.css,所以在main.js文件中引入bootstrap.css
// 如果通过路径形式引入node_modules中的相关文件,
// 可以直接省略路径前面的node_modules这一层目录,直接写包的名称,然后后面跟上具体的文件路径
// 不写node_modules ,会默认去node_modules下去找
import 'bootstrap/dist/css/bootstrap.css'
(4)bootstrap中的图标依赖bootstrap的字体文件,所以需要配置处理这些字体文件的
// 配置处理字体文件的loader
{ test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' }
注意:.json文件里面不能写注释
之前安装过包,会在package.json里面有记录,但不一定代表项目node_modules下就有这个包,如果运行报错,找不到相应的包,注意查看是否包不在了
在main.js中写以下几行代码
class Person {
static info = {name: 'zs', age: 20 }
}
// 访问Person类身上的info静态属性
console.log(Person.info);
class关键字,是ES6中提供的新语法,是用来实现ES6中面向对象编程的方式
使用static关键字,可以定义静态属性,所谓静态属性,就是可以通过类名,直接访问的属性
实例属性:只能通过类的实例,来访问的属性,叫做实例属性
在webpack中,默认只能处理一部分ES6的新语法,一些更高级的ES6或者ES7语法,webpack是处理不了的,例如class定义的类;
这时候需要借助第三方的loader,帮助webpack处理这些高级的语法,当第三方loader把高级语法转为低级的语法之后,会把结果交给webpack去打包到bundle.js中。
1.在webpack中,可以运行如下两套命令,安装两套包,去安装Babel相关的loader功能:
1.1 第一套包(Babel的转换工具): cnpm i babel-core babel-loader babel-plugin-transform-runtime -D
1.2 第二套包(Babel语法插件):cnpm i babel-preset-env babel-preset-stage-0 -D
2.打开webpack的配置文件,在module节点下的rules数组中,添加一个新的匹配规则:
2.1 { test:/\.js$/, use: 'babel-loader', exclude:/node_modules/ }
// 配置Babel来转换高级的ES语法
{ test:/\.js$/, use: 'babel-loader', exclude:/node_modules/ }
2.2 注意:在配置babel的loader 规则的时候,必须把node_modules目录,通过exclude选项排除掉,原因有二:
2.2.1 如果不排除掉node_modules,Babel会把node_modules中所有的第三方JS文件,都打包编译,这样,会非常消耗CPU,同时打包速度非常慢;
2.2.2 就算Babel把所有node_modules中的JS转换完毕,项目也无法正常运行。
3. 在项目根目录中,新建一个叫做.babelrc的Babel配置文件,这个配置文件属于JSON格式,所以在写Babel配置文件的时候,必须符合JSON语法规范:不能写注释,字符串必须用双引号
3.1 在.babelrc配置文件中,写如下配置:
{
"presets": [ "env", "stage-0" ],
"plugins": [ "transform-runtime" ]
}
// webpack.config.js
const path = require('path')
// 导入在内存中生成HTML页面的插件
// 只要是插件,都一定要放到plugins节点中去
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// 入口:表示要使用webpack打包哪个文件
entry: path.join(__dirname, './src/main.js'),
// 出口:输出文件的相关配置
output: {
// 指定打包好的文件,输出到哪个目录中去
path: path.join(__dirname, './dist'),
// 指定输出的文件名称
filename: 'bundle.js'
},
// 配置插件的节点,是一个数组
plugins: [
// 创建一个在内存中生成HTML页面的插件
new htmlWebpackPlugin({
// 指定模板页面,将来会根据指定的模板路径,去生成内存中的页面
template: path.join(__dirname, './src/index.html'),
// 指定生成的页面的名称
filename: 'index.html'
})
],
// 这个节点,用于配置 所有第三方模块加载器
module: {
// 所有第三方模块的 匹配规则
rules: [
// 配置处理.css文件的第三方loader规则
{ test: /\.css$/, use: ['style-loader', 'css-loader']},
// 配置处理.less文件的第三方loader规则
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},
// 配置处理.sass/.scss文件的第三方loader规则
{ test: /\.s[a|c]ss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
// 配置处理图片路径的loader
{ test: /\.(jpg|jpeg|png|gif|bmp)$/, use: 'url-loader?limit=15735&name=[hash:8]-[name].[ext]' },
// 配置处理字体文件的loader
{ test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' },
// 配置Babel来转换高级的ES语法
{ test:/\.js$/, use: 'babel-loader', exclude:/node_modules/ }
]
}
}