webpack4.x的使用
安装全局webpack
cnpm install -g webpack
安装全局webpack-cli
cnpm install -g webpack-cli
依赖安装:
cnpm install webpack webpack-cli --save-dev
初始化:生成package.json文件
npm init
新建src文件夹:文件名不能修改
新建dist文件夹,在此文件夹下新建index.html文件,注意src="./bundle.js,
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="./bundle.js"></script>
</body>
</html>
src文件夹下存放一个js文件
index.js,
var a = 600;
alert(a);
执行webpack src/index.js --output dist/bundle.js ,--output不能省略,否则bundle.js不能刷新
webpack src/index.js --output dist/bundle.js
这时有警告提示:这时因为没有设置参数mode
mode:development 开发模式,打包后的bundle.js没有压缩
mode:production 生产模式,打包后的bundle.js压缩
设置mode后该警告就会消失,如执行下面的语句
webpack src/index.js --output dist/bundle.js --mode development
上面的指令有点长,可以设置webpack.config.js文件进行相关的配置
注意两点:module.exports,'/dist'不能写成'./dist'
module.exports={
//入口配置
entry:'./src/index.js',
//mode
mode:'development',
//出口配置
output:{
path:__dirname + '/dist',//path必须是绝对路径
filename:'bundle.js'
}
};
关于路径还可以写成path.resolve(__dirname,'dist'),这样就避免面dist前面加.的错误,但必须要引入path模块
const path = require('path');
module.exports={
//入口配置
entry:'./src/index.js',
//mode
mode:'development',
//出口配置
output:{
path:path.resolve(__dirname,'dist'),//path必须是绝对路径
filename:'bundle.js'
}
};
配置文件名字一定是webpack.config.js吗?不是
如果写成mypack.config.js,则运行的指令是
webpack --config mypack.config.js
写起来比较繁琐,建议不要修改。
在webpack.config.js设置mode参数时只能设置一个,所以一般不在webpack.config.js设置mode参数,
执行时直接设置mode参数,决定是开发环境还是生产环境
webpack --mode development
这条语句可以设置在webpack.json文件中,
{
"name": "webpack4.1.1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.2.0",
"webpack-cli": "^2.0.13",
"webpack-dev-server": "^3.1.1"
}
}
执行npm run dev,就相当执行webpack --mode development
多个入口文件打包成一个入口文件
在src文件加下有两个js文件
这时候entry参数是数组形式,按照顺序依次打包到bundle.js。
const path = require('path');
module.exports={
//入口配置
entry:['./src/index.js','./src/index2.js'],
//出口配置
output:{
path:path.resolve(__dirname,'dist'),//path必须是绝对路径
filename:'bundle.js'
}
};
多个入口文件,多个出口文件:entry参数是json格式,filename参数也要修改,filename:'[name].bundle.js'
const path = require('path');
module.exports={
//入口配置
entry:{
a:'./src/index.js',
b:'./src/index2.js'
},
//出口配置
output:{
path:path.resolve(__dirname,'dist'),//path必须是绝对路径
filename:'[name].bundle.js'
}
};
在dist文件夹下生成a.bundle.js和b.bundle.js两个文件
但是要修改index.html中的script的src属性
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="./a.bundle.js"></script>
<script src="./b.bundle.js"></script>
</body>
</html>
可以使用html-webpack-plugin生成html页面
安装
cnpm install html-webpack-plugin -D
因为html-webpack-plugin插件依赖webpack,webpack的部分功能放到了webpack-cli中,因此还需要安装局部webpack和
webpack-cli,在文章开头已经安装了,这里不用再安装。
引入
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
//入口配置
entry:{
a:'./src/index.js',
b:'./src/index2.js'
},
//出口配置
output:{
path:path.resolve(__dirname,'dist'),//path必须是绝对路径
filename:'[name].bundle.js'
},
plugins:[
new HtmlWebpackPlugin()
]
};
执行npm run dev,生成3个文件
index.html内容
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<script type="text/javascript" src="a.bundle.js"></script><script type="text/javascript" src="b.bundle.js"></script></body>
</html>
关于new HtmlWebpackPlugin()的配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
//入口配置
entry:{
a:'./src/index.js',
b:'./src/index2.js'
},
//出口配置
output:{
path:path.resolve(__dirname,'dist'),//path必须是绝对路径
filename:'[name].bundle.js'
},
plugins:[
new HtmlWebpackPlugin({
minify:{
collapseWhitespace:true //压缩空白
},
hash:true,
title:"Learn Webpack",
template:"./src/index.html"
})
]
};
.src/index.html文件,
注意:htmlWebpackPlugin,W和P大写
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title%></title>
</head>
<body>
</body>
</html>
生成多个html文件:
生成的html文件名默认是index.html,如果不设置filename参数,只会生成一个index.html
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
//入口配置
entry:{
a:'./src/index.js',
b:'./src/index2.js'
},
//出口配置
output:{
path:path.resolve(__dirname,'dist'),//path必须是绝对路径
filename:'[name].bundle.js'
},
plugins:[
new HtmlWebpackPlugin({
filename:'index.html',//默认是index.html
title:"Learn Webpack",
template:"./src/index.html"
}),
new HtmlWebpackPlugin({
filename:'index2.html',
title:"第二个页面",
template:"./src/index2.html"
})
]
};
生成的两个html文件中都有a.bundle.js和b.bundle.js的引用
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Learn Webpack</title>
</head>
<body>
<script type="text/javascript" src="a.bundle.js"></script><script type="text/javascript" src="b.bundle.js"></script></body>
</html>
index2.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第二个页面</title>
</head>
<body>
<div id="aaa"></div>
<script type="text/javascript" src="a.bundle.js"></script><script type="text/javascript" src="b.bundle.js"></script></body>
</html>
如果想要index.html文件只引入a.bundle.js,如果想要index2.html文件只引入b.bundle.js
要设置chunks参数,数组形式,元素是对应js文件的入口名字。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
//入口配置
entry:{
a:'./src/index.js',
b:'./src/index2.js'
},
//出口配置
output:{
path:path.resolve(__dirname,'dist'),//path必须是绝对路径
filename:'[name].bundle.js'
},
plugins:[
new HtmlWebpackPlugin({
chunks:["a"],
filename:'index.html',//默认是index.html
title:"Learn Webpack",
template:"./src/index.html"
}),
new HtmlWebpackPlugin({
chunks:["b"],
filename:'index2.html',
title:"第二个页面",
template:"./src/index2.html"
})
]
};
index.html文件只引用了a.bundle.js
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Learn Webpack</title>
</head>
<body>
<script type="text/javascript" src="a.bundle.js"></script></body>
</html>
index2.html文件只引用了b.bundle.js
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第二个页面</title>
</head>
<body>
<div id="aaa"></div>
<script type="text/javascript" src="b.bundle.js"></script></body>
</html>
还有一个clean-webpack-plugin插件,作用是在webpack打包之前,删除先前生成的打包文件,这样不用手动删除打包文件。
plugins:[
new cleanWebpackPlugin(['dist'])
]
设置服务器devServer:
下载
cnpm install webpack-dev-server -D
设置webpack.config.js
devServer:{
//设置服务器访问的目录,默认值是__dirname,就是webpack.config.js所在的目录
contentBase:path.resolve(__dirname,'dist'),
//服务器ip地址,loacalhost
host:'localhost',
//设置端口
port:8090,
//自动打开浏览器
open:true
}
设置webpack.json
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production",
"start":"webpack-dev-server --mode development"
}
运行:
npm start
此时浏览器网页自动打开,修改网页内容时,网页自动刷新。
本次没有出现错误,但是有时候因为网络原因等,一些依赖模块没有下载成功,有可能出现cant find module...,这时要重新下载webpack-dev-servser,直至成功。
热更新:只更新一部分
第一步:在devServer对象中添加hot:true
devServer:{
//设置服务器访问的目录
contentBase:path.resolve(__dirname,'dist'),
//服务器ip地址,loacalhost
host:'localhost',
//设置端口
port:8090,
//自动打开浏览器
open:true,
hot:true
}
第二步:引入webpack const webpack = require('webpack');
在plugins数组数组中添加new webpack.HotModuleReplacementPlugin()
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports={
//入口配置
entry:{
a:'./src/index.js',
b:'./src/index2.js'
},
//出口配置
output:{
path:path.resolve(__dirname,'dist'),//path必须是绝对路径
filename:'[name].bundle.js'
},
devServer:{
//设置服务器访问的目录
contentBase:path.resolve(__dirname,'dist'),
//服务器ip地址,loacalhost
host:'localhost',
//设置端口
port:8090,
//自动打开浏览器
open:true,
hot:true
},
plugins:[
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
chunks:["a"],
filename:'index.html',//默认是index.html
title:"Learn Webpack",
template:"./src/index.html"
}),
new HtmlWebpackPlugin({
chunks:["b"],
filename:'index2.html',
title:"第二个页面",
template:"./src/index2.html"
})
]
};
运行: npm start
理解devServer
当执行webpack --mode development命令时,在/dist文件夹下产生a.js
当执行webpack-dev-server --mode development时,通过这种方式生成的文件存在内存中,默认路径就是在服务器的根目录下。在内存中产生a.js,看不见,但可以通过localhost:8090/a.js访问,如果在webpack.config.js所在目录下真实存在一个a.js文件,那么localhost:8090/a.js访问的是内存中的a.js。意思就是contentBase对应的目录变成了一个服务器,在contentBase目录下的文件都可以通过http请求访问,包括内存中和真实存在的文件,如果两者文件有重名的,访问的是内存中的文件。
entry: './src/js/index.js', //入口文件
output: {
filename: 'a.js', //出口文件名
path: path.resolve(__dirname, 'dist') //出口文件夹
},
devServer:{
//设置服务器访问的目录
contentBase:__dirname,
//服务器ip地址,loacalhost
host:'localhost',
//设置端口
port:8090,
//自动打开浏览器
open:true,
hot:true
},
也可以修改输出文件在内存中的位置,通过设置publicPath: '/assets/',这样执行webpack-dev-server --mode development,就可以通过localhost:8090/assets/a.js,访问a.js
output: {
filename: 'a.js', //出口文件名
path: path.resolve(__dirname, 'dist') ,//出口文件夹
publicPath: '/assets/'
},
devServer的proxy:服务器代理
module.exports = {
//...
devServer: {
proxy: {
'/api': 'http://localhost:3000'
}
}
};
当访问/api/users时,相当于访问http://localhost:3000/api/users
如果想去掉api可以重写路径
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: {'^/api' : ''}
}
}
}
};
此时访问/api/users,相当于访问http://localhost:3000/users