最近在学vue,把webpack
的一些相关的一些基本知识记录一下,毕竟自己不是主要用vue的,不记录过几天就忘了。
安装webpack
和webpack-cli
npm i -D webpack
npm i -D webpack-cli
注意:webpack官网并不提倡全局安装,一开始我为了图省事全局安装了,结果运行webpack-dev-server各种报错,最后还是本地安装
安装好这两个之后就需要进行相应的配置,为项目进行配置,使webpack为我们的项目工作
在项目根目录下创建webpack.config.js
文件,webpack是基于node编写的,所以node语法适用
const path = require("path");
module.exports = {
// 入口,表示要使用webpack打包哪个文件
entry: path.join(__dirname, "./src/main.js"),
output: {
// 指定打包好的文件输出到哪个目录中去
path: path.join(__dirname, "./dist"),
// 指定输出文件的名称
filename: "bundle.js"
},
}
配置了之后就可以直接运行webpack命令进行打包了,webpack的打包流程为
- 首先,webpack 发现,我们并没有通过命令的形式,给它指定入口和出口
- webpack 就会去 项目的 根目录中,查找一个叫做
webpack.config.js
的配置文件 - 当找到配置文件后,webpack 会去解析执行这个 配置文件,当解析执行完配置文件后,就得到了 配置文件中,导出的配置对象
- 当 webpack 拿到 配置对象后,就拿到了 配置对象中,指定的 入口 和 出口,然后进行打包构建;
再安装一个自动打包的工具
npm i -D webpack-dev-server
在安装了webpack-dev-server
之后,可以在package.json
中配置脚本,让命令简单点
在script
属性中配置"dev": "webpack-dev-server"
,配置了这个命令之后,以后可以直接这么运行:npm run dev
,webpack-dev-server
有两种配置方式
- 方式1:在
package.json
的scripts
节点配置,见dev
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --open --port 3000 --contentBase src --hot",
"dev2": "webpack-dev-server"
},
- 方式2:同样先在
package.json
的scripts
节点配置,见上面代码块的dev2
先添加devServer
节点并配置
devServer: {
// 自动打开浏览器
open: true,
// 启用端口
port: 3000,
// 指定托管目录
contentBase: "src",
// 启用热更新 第1步
hot: true
},
因为启用了热更新,需要为热更新配置,在webpack.config.js
中导入相应的包
// 启用热更新的第2步
const webpack = require("webpack");
在plugins
中new一个热更新模块
plugins: [
// new一个热更新模块 启用热更新第3步
new webpack.HotModuleReplacementPlugin(),
]
配置完webpack-dev-server
之后运行,它会自动监听我们代码的变化,并实时打包。这里注意的是1:webpack-dev-server
打包的bundle.js
与webpack所打包的bundle.js
不是同一个文件,webpack-dev-server
打包出的bundle.js
是放在内存中的,而webpack打包出的bundle.js
是放在我们物理磁盘上的。2:如果这两种配置方式同时存在,那么webpack-dev-server
优先使用配置方式2
安装html-webpack-plugin
npm i html-webpack-plugin -d
安装这个之后在配置文件里进行相应的配置
- 1 导包
const htmlWebpackPlugin=require("html-webpack-plugin");
- 2 在
plugins
节点new一个htmlWebpackPlugin
模块并配置
// 创建一个在内存中生成HTML页面的插件
new htmlWebpackPlugin({
// 指定模板页面,将来会根据指定的页面路径去生成内存中的页面
template:path.join(__dirname,"./src/index.html"),
// 指定生成得页面的名称
filename:"index.html"
})
处理css
等样式文件
因为webpack无法打包非js模块,所以需要安装相应的load加载器
- 1、安装
style-loader
和css-loader
直接安装这两个的命令npm i style-loader css-loader -d
- 2、进行相应的配置
在配置文件中新增module
节点,这个节点是一个对象,这个对象有一个属性rules
,这个属性是一个数组,它存放所有第三方文件的匹配和处理规则。
// 这个节点用于配置所有第三方模块加载器
module: {
// 所有第三方模块的配置规则在这里写
rules: [
// 配置处理.css文件的第三方loader规则
{ test: /\.css$/, use: ["style-loader", "css-loader"] }
]
}
这么配置之后webpack就可以打包css
文件了,它的打包流程为:
- 1.发现这个要处理的文件不是js文件,webpack会去配置文件中查找有没有对应的第三方loader规则
- 2.如果找到对应的规则,就会调用对应的loader处理这种文件类型
- 3.在调用loader的时候是从后往前调用的
- 4.当最后的一个loader调用完毕,会把处理结果直接交给webpack进行打包合并,最终输出到
bundle.js
中
处理less
文件
- 1 安装相应的loader
先安装less
npm i less-d
再安装less-loader
npm i less-loader -d
- 2 在配置文件中配置
//配置处理 .less 文件的第三方 loader 规则
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
处理scss
文件
与上面的处理步骤一致,不赘述,命令为先安装node-sass:npm i node-sass -d
然后在安装sass-loader:npm i sass-loader -d
,然后进行配置
// 配置处理 .scss 文件的 第三方 loader 规则
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
处理样式中的URL
默认情况下webpack无法处理样式表中的URL
,无论是图片的URL
还是字体库的URL
,故需要安装相应的loader
- 先安装file-loader:
npm i file-loader -d
- 再安装url-loader:
npm i url-loader -d
- 然后进行相应的配置
// 处理 图片路径的 loader
// limit 给定的值,是图片的大小,单位是 byte, 如果我们引用的 图片,大于或等于给定的 limit值,
// 则不会被转为base64格式的字符串, 如果 图片小于给定的 limit 值,则会被转为 base64的字符串
// name是定义图片加载时的名字,这里保留了原名以及在前面加上了8位哈希值,放置重名
{ test: /\.(jpg|png|gif|bmp|jpeg)$/, use: [{ loader: 'url-loader', options: { limit: 5000 ,name:'[hash:8]-[name].[ext]'} }] },
处理字体文件
字体文件是在样式表中使用,通常使用URL
引入,所以使用的url-loader
,只需匹配相应的文件
// 处理 字体文件的 loader
{ test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' },
配置babel
在es6新增了一些高级的语法,比如类的概念,而在webpack中,默认只能处理一部分es6的新语法,一些更高级的语法webpack是无法处理的,因此需要借助第三方loader来帮助webpack处理,第三方loader会把高级语法转为低级语法,然后交给webpack打包到bundle.js
中去。
- babel转换工具:
npm install babel-loader @babel/core -d
在webpack的配置文件中新增匹配规则,注意要将node_modules目录下的文件排除掉
// 配置 Babel 来转换高级的ES语法
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ },
- babel语法转换:
npm install @babel/preset-env -d
在安装了上面这个包之后仍然不能打包高级es6语法,比如类,还需要安装这个包:npm install @babel/plugin-proposal-class-properties -d
安装完这两个包之后,在项目的根目录中新建一个叫.babelrc的babel配置文件,该文件属于json格式,所以配置时要符合json语法
{
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-proposal-class-properties"]
}
这样配置完之后webpack就可以打包含有类的js文件了。配置babel过程让人很烦躁,各种报错,不要太依赖于网上的教程,包括这篇,报的很多错都是因为版本更新的问题,因此要想正确配置,直接去babel官网查看文档,有中文的,但不全。
处理.vue文件
安装相应的loader
npm i vue-loader vue-template-compiler -d
配置文件中进行配置
// 处理.vue文件的loader
{ test: /\.vue$/, use: "vue-loader" }
整个webpack.config.js的配置
const path = require("path");
// 启用热更新的第2步
const webpack = require("webpack");
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"
},
// 这是配置dev-server命令参数的第二种形式,相对麻烦
devServer: {
// 自动打开浏览器
open: false,
// 启用端口
port: 3000,
// 指定托管目录
contentBase: "src",
// 启用热更新 第1步
hot: true
},
// 配置插件节点
plugins: [
// new一个热更新模块 启用热更新第3步
new webpack.HotModuleReplacementPlugin(),
// 创建一个在内存中生成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'] },
// 配置处理 .scss 文件的 第三方 loader 规则
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
// 处理 图片路径的 loader
// limit 给定的值,是图片的大小,单位是 byte, 如果我们引用的 图片,大于或等于给定的 limit值,
// 则不会被转为base64格式的字符串, 如果 图片小于给定的 limit 值,则会被转为 base64的字符串
// name是定义图片加载时的名字,这里保留了原名以及在前面加上了8位哈希值,放置重名
{ test: /\.(jpg|png|gif|bmp|jpeg)$/, use: [{ loader: 'url-loader', options: { limit: 5000 ,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/ },
// 处理.vue文件的loader
{ test: /\.vue$/, use: "vue-loader" }
]
}
}