webpack
webpack定义:是一个现代 JavaScript 应用程序的模块打包器(module bundler),分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript,vue等),并将其转换和打包为合适的格式供浏览器使用。
效果图
流行的三个SPA的框架,都于webpack紧密相连
- React.js + webpack
- Vue.js + webpack
- Angular.js + webpack
-学习webpack有4个重要的内容
1.入口(entry)
2.输出 (entry)
3.加载器(loader)
4.插件(pluings)
安装webpack
npm install 包名称 --save-dev -D
devDependencies 开发环境需要的依赖包。真正发布的时候是不需要的。这样在打包上线的时候不会将这些模块打包到项目中,可以有效的减少项目的大小
npm install 包名称 --save -S
会自动记录在dependenceies 位置,发布项目的时候,也需要依赖的包
注意:webpack只是一个中间用于处理而文件的工具,只是炫耀哦在开发的时候使用,打包部署后就不需要的,所以这个工具的包基本都是--save-dev方式下载。
下载安装
nmp init -y 项目初始化
npm install --save-dev webpack webpack-cli 下载包
如果运行应用程序运行报错,就这样处理下载一个全局安装包
npm install webpack webpack-cli -g
01-webpack基本使用
基本的目录结构
代码细节
// getsum.js
function getsum(a,b){
return a + b
}
module.exports = getsum//暴露函数
-----------------------------------------
// app.js
const getsum = require('./getsum')
let sum = getsum(1,2)
// 在页面中输出结果
document.write(sum)
-----------------------------------------
// index.html
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
// 引入app.js
<script src="./src/app.js"></script>
</head>
结果报错
// 报错信息
app.js:1 Uncaught ReferenceError: require is not defined
at app.js:1
//使用importn导入模块的错误
Cannot use import statement outside a module
原因:
1.浏览器只认识基本的js css html
2.在引入的文件中使用了node方式的代码(require),而这种代码浏览器并不能识别
解决:
1.使用webpack打包,将浏览器不能识别的代码转换为浏览器可识别的代码
2下载webpack :npm i webpack
3.在终端(cmd,powershell)中输入命令:webpack ./src/app.js,会自动将指定的app.js打包转换为./dist/main.js
44.在页面中引入打包转换后的main.js
// index.html
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
// 引入main.js
<script src="./dist/main.js"></script>
</head>
补充细节:
1.默认打包转换的代码是经过压缩的代码
2.如果不想要压缩过后的代码可以在命令后面添加–mode=development的配置
WARNING in configuration(配置警告)
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.('mode' 选项还未设置。将 'mode' 选项设置为 'development' 或 'production',来启用环境默认值。)
----------------------------------------------------------------------
webpack ./src/app.js --mode=development
-- 这个警告不会对功能产生影响,也可以忽略
02-webpack.config.js
使用webpack.config.js实现webpack的配置
在项目的根目录下添加一个webpack.config.js文件,注意文件的名称绝不能修改
后期打包的时候会根据webpack.config.js的配置进行打包
主要写四个部分:入口+输出+loader+插件
entry:设置你的入口文件,说白了就是你想打包转换的文件路径
**output:**设置目标文件的全路径
path:设置目标文件的目录
**filename:**设置目标文件的文件名称
var path = require('path')
module.exports = {
// 设置文件的入口:一开始就解析这个文件
entry:'./src/app.js',
// 将入口文件解析为目标文件的配置
output:{
// 目标文件的输出路径文件夹名称
path:path.join(__dirname,"dist",),
// 目标文件的文件名称
filename:'main.js'
}
}
输入命令:webpack
也可以进行脚本的配置
// package.json 主要是处4行
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
//'start'可以自己设置名字但输入命令时要和你自己设置的一样 所有默认为start即可
"start":"webpack --config webpack.config.js"
}
// 输入命令:运行脚本中所配置的start命令
npm run start
说明
scripts:指可运行的脚本配置,后期可以通过npm run来执行指定的脚本,相当于将比较复杂的命令封装为一个简单的命令
–config是指运行这个start命令的时候,使用的配置文件是后面所指定的webpack.config.js
03-webpack解析css
默认情况下,webpack不能打包转换css文件,在进行配置前会报如下错误
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. See https://webpack.js.org/concepts#loaders
当前配置不足以支持Css文件的解析,webpack现在还搞不定
- 这种错误信息一般就告诉我们你现在项目中的文件没有合适的解析器进行处理,所以你得去 查找loader + 下载 + 配置
- 解决过程:
-
下载:npm install css-loader style-loader --save-dev
- css-loader:css解析器,将css解析为浏览器可以识别的类型
- style-loader:自动的在指定文件中添加style标签,同时添加指定的样式代码
- 在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底层调用这些包的顺序是从右到左
}
]
}
04-webpack解析less和scss
在开发的时候,我们一般会根据需要使用less或者scss来创建样式,默认情况下,webpack并不能解析这两种预处理器,所以需要进行单独的下载和配置
下载+引入
安装less解析loader
npm i less less-loader --save-dev
安装scss解析loader
npm i sass-loader node-sass --save-dev
添加配置
// webpack.config.js文件中
// 配置less解析
{
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'
}]
}
06-webpack-图标+图片
在项目中导入图片或者图标的时候,默认情况下也不能被正确的解析,需要我们对webpack进行单独的配置
在项目根目录下添加images文件夹,并拷贝一张图片进来进行测试
// a.css
body {
background-color: #ff0;
background-image: url(../images/bug6.jpg);
background-repeat: no-repeat;
}
-----------------------------------------------
//app.js
import logo from '../images/border.jpg'
let element =document.creataElement('div')
//添加显示图片
element.innerHTMl=`<img src='${logo}'/>`
document.body.appendChild(element)
下载:npm install file-loader --save-dev
添加配置:
{
test: /\.(png|jpg|gif|eot|svg|ttf|woff)/,//图片格式
use: [{
// file-loader处理文件后会返回一个链接
loader: 'file-loader',
options: {
publicPath: "./dist/images/", // 引入图片时会在路径前面加上该选项
outputPath: "images" // 输出到dist下的images目录
}
}]
}
细节:在body中在引入main.js,否则body找不到
07-webpack-babel
一些老版的浏览器可能不支持ES6,这个babel的作用就是能够将ES6转换ES5,达到兼容的目的
下载:npm install babel-loader @babel/core @babel/preset-env --save-dev
配置
{
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']
}
}
}
8-webpack-dev-server
作用:自动打开了浏览器,同时在修改源代码的时候页面实现自动刷新
实现:1,将入口文件解析转换之后放在这个服务器托管,我们所请求其实就是在这个服务器上面的资源
1每次修改代码,会自动的解析转换并托管,重新发起新的请求–所以可以实现自动刷新
2如果调用webpack-dev-server的时候能够添加–open,他会自动打开浏览器
下载包:npm i webpack-dev-server --save-dev
在webpack.config.js中进行服务器开发的配置
module.exports = {
// 设置文件的入口:一开始就解析这个文件
entry:'./src/app.js',
// 将入口文件解析为目标文件的配置
output:{
// 目标文件的输出路径文件夹名称
path:path.join(__dirname,"dist"),
// publicPath: '/dist',
// 目标文件的文件名称
filename:'main.js'
},
// 建议使用这个配置,新版本建议这样配置,默认会生成main.js
// 端口如果不设置,默认为8080
devServer:{
publicPath: '/dist',
port:8080,
openPage:'./dist/'
}
}
运行 webpack-dev-server --open
目前我们都是在 index.html 中手动引入打包后的资源,这种引入方式有很多缺点,比如文件名依赖问题,假如 webpack 配置中的输出文件名修改了,需要及时在 index.html 中同步修改,再者每次新增文件都要引入一遍很繁琐
我们可以使用 HtmlWebpackPlugin插件 自动引入打包后的资源文件到html文件,该插件需要指定一个html模板文件,并且会生成一个 index.html 文件到 dist 目录中
如果没有指定默认的模板文件,这个插件可以帮助我们自动的生成一个模板文件,并实现资源的自动的引入
下载安装
npm i --save-dev html-webpack-plugin
添加配置
//引入
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 其他配置 ....
// plugins是一个单独的结构
plugins: [
// + 新增配置
new HtmlWebpackPlugin({
template: "/index.html", // template指定默认html模板
filename:'index.html', // 指定生成的目标文件
inject:'body' // 指定js文件的注入位置
})
]
};
细节:
由于会自动的生成页面文件,且这个页面会放置到dist文件夹中,所以之前图片的publicPath需要修改为:"./images/"||’/dist/images’
10-vue-loader
作用:可以让webpackl来解析vue单文件
下载
npm install -D vue-loader vue-template-compiler
添加配置
// 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实现将单文件组件渲染到页面
// 1.引入vue,只有vue才能帮助我们渲染vue单文件组件
import Vue from 'vue'
import Hello from './hello.vue'
new Vue({
// render:是vue自己提供的,这个render有一个参数,这个参数才是真正的渲染函数,它可以渲染指定的组件,并将渲染的结果返回
render: (h) => {return h(Hello)}
}).$mount('#app')
// $mount:挂载,将渲染的内容填充到指定的dom元素中
// index.html
<div id="app" style='width:400px;height:200px;border:solid red 1px'></div>