什么是Webpack
简而言之webpack 是一个Js 应用程序的模块打包器,分析项目结构找到Js模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript,vue等),并将其转换和打包为合适的格式供浏览器使用。
如果html文件引入的js文件中有浏览器不能识别的代码,将会报以下错误:
Uncaught ReferenceError: require is not defined
解决方式:使用webpack打包,将浏览器不能识别的代码转换为浏览器可识别的,同时引出下面的话题–为什么要使用webpack
为什么要用Webpack
SPA流行之后程序往往依赖很多浏览器不能直接运行的模块,需要依赖Webpack来解决
Webpack的使用
- 基本使用
下载webpack: npm i webpack
目录结构:
src文件夹中:
app.js – 入口文件,页面中需要引入的js文件
index.html – 打开的静态页面
在终端(cmd,powershell)输入命令:webpack /src/app.js
(页面引入的js文件)
运行后在dist文件夹中会得到转换并压缩后的js文件(如果不想要压缩文件,需要在命令后面添加 --mode==development
)
webpack.config.js
在根目录下创建webpack.config.js,以此来配置webpack的文件
配置文件的主要部分:
- entry:设置入口文件,即需要打包转换的文件路径
- output:设置目标文件的全路径
2.1 path:设置目标文件的目录
2.2 filename:设置目标文件的文件名称 - module:{rules:[]} 配置文件分析的模型和规则
- plugins:插件
loader的使用与配置
webpack常见报错:
Module parse failed: Unexpected token (1:5)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
出现以下代码证明webpack没有配置相关的加载器来处理响应的文件格式
- 常用loader
1.webpack解析css
-
1.1 下载css-loader 以及 style-loader
css-loader:css解析器 style-loader:自动在指定文件中添加style标签以及指定样式代码
-
1.2 在webpack.config.js中添加配置
module: {
rules: [
// 配置的是用来解析.css文件的loader(style-loader和css-loader)
{
// 用正则匹配当前可被处理的文件的后缀名是 .css
test: /\.css$/,
// css-loader:读取css代码并解析为浏览器可以识别的代码
// style-loader:把css代码添加到网页中
use: ['style-loader', 'css-loader'] //webpack底层调用这些包的顺序是从右到左
}
]
}
2.webpack解析less/scss
-
2.1 下载+引入
less:npm i less less-loader --save-dev
;
scss:npm i sass-loader node-sass --save-dev
; -
2.2 配置
{
test: /\.less$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'less-loader'
}]
},
// 配置scss解析
{
test: /\.scss$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'sass-loader'
}]
}
3.webpack解析图片
- 3.1 下载 file-loader
- 3.2 配置
{
test: /\.(png|jpg|gif|eot|svg|ttf|woff)/,
use: [{
// file-loader处理文件后会返回一个链接
loader: 'file-loader',
options: {
publicPath: "绝对路径", // 引入图片时会在路径前面加上该选项
outputPath: "基于js文件输出的相对路径" // 输出到指定目录
}
}]
}
4.webpack-babel
一些老版本的浏览器不支持CS6语法,需要用babel来把CS6转为CS5
- 4.1 下载 babel-loader
- 4.2 配置
{
test: /\.js$/,
// Webpack2建议尽量避免exclude,更倾向于使用include
// exclude: /(node_modules)/, // node_modules下面的.js文件会被排除
include: [path.resolve(__dirname, 'src')],
use: {
loader: 'babel-loader',
// options里面的东西可以放到.babelrc文件中去
options: {
presets: ['@babel/preset-env']
}
}
}
5.webpack-dev-server
每次数据修改,都需要进行一次打包来更新打包文件,使用webpack-dev-serve来实现数据文件自动刷新
- 5.1 实现原理
- 将入口文件解析转换后,在dev-serve服务器中进行托管,浏览器请求的其实是这个服务器的资源
- 每次修改代码都会自动解析转换并托管,重新发送请求刷新浏览器
- 5.2 下载并配置
下载包:npm i webpack-dev-server --save-dev
配置:
module.exports = {
// 新版本建议这样配置,默认会生成main.js
// 端口如果不设置,默认为8080
devServer:{
publicPath: '/dist',
port:8080,
openPage:'./dist/'
}
}
6.html-webpack-plugin
因为打包后的资源都要手动引入,但这种引入方式缺点很多,例如对文件名的依赖,如果引入配置的文件名改了,需要在引入文件中手动修改.
可以安装HtmlWebpackPlugin插件来实现自动引入
- 下载
npm i --save-dev html-webpack-plugin
- 添加配置
// 1. 引入
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 其他配置 ....
// plugins是一个单独的结构
plugins: [
// + 新增配置
new HtmlWebpackPlugin({
template: "public/index.html", // template指定默认html模板
filename:'index.html', // 指定生成的目标文件
inject:'head' // 指定js文件的注入位置,考虑到代码是从上往下来解析,如果在头部注入js,js中涉及到dom元素的操作或许会无法获取该元素,所以建议在body注入而不是head
})
]
};
由于该插件会在服务器的dist文件在中自动生成html模板,所以原来图片配置的路径需要一并修改
module: {
rules: [
//配置图片
test: /\.(png|jpg|gif|eot|svg|ttf|woff)/,
use: [{
// file-loader处理文件后会返回一个链接
loader: 'file-loader',
options: {
publicPath: "./images/", // 引入图片时会在路径前面加上该选项
outputPath: "/dist/images" //dev服务器的输出访问路径
}
}]
}
]
7.vue-loader插件
vue能在脚手架中实现动态更新的原理:vue-loader解析vue单文件组件,把单文件组件解析并在dev-serve中托管,实现修改自动刷新
- 配置
// webpack.config.js
//使用插件
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
module: {
rules: [
// ... 其它规则
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
//注入插件,请确保引入这个插件!
new VueLoaderPlugin()
]
}
- 在app.js中实现渲染
// 引入vue,只有vue才能渲染vue单文件组件
import Vue from 'vue'
import Hello from './单文件组件路径'
new Vue({
// render:是vue自己提供的,这个render有一个参数,这个参数才是真正的渲染函数,它可以渲染指定的组件,并将渲染的结果返回
render: (h) => {return h(Hello)}
}).$mount('#app')
// $mount:挂载,将渲染的内容填充到指定的dom元素中
- 在主页html中创建#app标签来创建挂载位置标签
// index.html
<div id="app"></div>
额外的查漏补缺:
css中声明自定义参数用@,使用的时候也需要用@,而且声明时结尾要记得加’;’
@mywidth:1200px;
body{
width:@mywidth;
height:100vh;
}