1.HTML 中img标签的图片资源处理
html-withimg-loader
只要在html中正常引用图片即可,webpack会找到对应的资源打包,html里的img标签的路径资源打包,并且把资源重新命名,使用的是url的图片配置、
- live-server 在当前文件夹起服务
2.多页面应用的打包:
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
// 1.修改为多入口
entry:{
index:'./src/index.js',
other:'./src/other.js'
},
output:{
path:path.resolve('/dist'),
// 2.多入口无法对应一个固定的出口,所以修改filename为[name]变量
filename:[name].js //[name] output 这里可以根据传入的name 来输出对应的文件名,index.js和other.js
},
plugin:[ // 根目录下面的index.html是根据html-webpack-plugin 插件生成的。
//根据index.html templare 生成的filename index.html
// 3.如果用了html插件,需要手动配置多入口对应的html文件,将制定其对应的输出文件
new HtmlWebpackPlugin({
filename:'index.html',
template:'./src/index.html',
chunks:['index','main'] // 只引入要添加的chunks
}),
new HtmlWebpackPlugin({
filename:'other.html',
template:'./src/other.html',
chunks:['other']
})
]
}
3. 第三方库的两种引入方式
// 可以挂载多个全局变量
可以通过 expose-loader 进行全局变量的注入,同时也可以使用内置插件webpack.ProvidePlugin 对每个模块的闭包空间,注入一个变量,制动加载模块,而不用导出import 或 require
expose-loader 全局变量 // 通常和第三方库结合使用时会用到,因为第三方库回去寻找全局jquery变量
npm i expose-loader -D
webpack.ProvidePlugin
4.development和production不同配置文件的打包
webpack-merge
npm i webpack-merge -D
webpack.base.js
webapck.prod.js // 优化配置,代码拆分,代码压缩,加密
webpack.dev.js
步骤如下:
- 将开发环境和生产环境公用的配置放入base中,不同的配置各自放入prod和dev中
- 然后在dev和prod中使用webpack-merge 把自己的配置与base的配置进行合并并导出
- 将 package.json中的脚本参数进行修改,通过--config手动指定特定的配置文件
webpack.dev.js
const merge = require('webpack-merge');
const baseConfig = require('./webpack.base.js')
module.exports = merge(baseConfig,{
mode:'developlment'
devServer:{
open:true,
hot: true,
compress: true,
port: 3000,
proxy:{
'/api': {
target: "http://localhost:9999",
pathRewrite: {
// 转发请求时不会携带 '/api'
// 实际请求的是http://localhost:9999/getUserInfo
'^/api': ''
}
}
}
}
})
package.json
{
"script":{
"test": 'echo',
"buildcustom":"webpack --config webpack.custom.config.js",
"build":"webpack --config ./build/webapck.prod.js",
"dev":"webpack-dev-server --config ./build/webpack.dev.js",
"server": "node server.js",
"start": "live-server ./dist" //用live-server 打开dist文件夹,启动小型服务器
}
}
定义build文件夹,将 webpack.base.js, webpack.prod.js, webpack.dev.js 放入build文件夹
此时在output路径拼接需要使用:
output:{
//相对路径都是相对的项目根目录,绝对路径是当前文件所在的的绝对路径记得往上翻一层
path:path.resolve(__dirname,'..','./dist/')
},
plugins:[
new CopyWebpackPlugin({
from: path.join(__dirname,'..','assets'),
to: 'assets'
})
]
5. 定义环境变量
webpack 内置插件 webpack.DefinePlugin({})
DefinePlugin 会解析定义的环境变量表达式,这里的值会当成变量来处理
此环境变量都可以在src打包的文件夹下面使用
let host = 'http://192.168.1.22:8080'
if(is_dev){
host = 'www.newbaker.cn:9999'
}
6. 使用devServer 解决跨越问题
- 由于开发时会用到webpack-dev-server ,所以一定会产生跨域问题
- jsonp (淘汰)
- cors 跨域资源共享
- http proxy
- 其原理就是将所有请求发给devServer,再由devServer服务器做一次转发,发送给数据接口服务器;
- 由于ajax是发送给devServer服务器的,所以不存在跨域,而devServer是用node平台发送的http请求,自然也不涉及跨域问题
node中使用CORS:
npm i cors --save-dev
app.js
const express = require('express')
const app = express()
const cors = require('cors') //加上了响应头 responese Headersd Access-Control-Allow-Origin: *
app.use(cors())
app.get('/api/getUserInfo',(req,res) => {
res.send({
name:'wjx',
age: 18
})
})
app.listen(9999, () => {
console.log('http://localhost:9999')
})
7 HMR 热更新
hot module reload // 不适用于生产环境,只是在开发环境
module.hot.accept('./hotModule.js',()=>{
// import 和 export 必须在顶级作用域使用
var str = require('./hotModule.js)
})
以上用到的配置webpack.config.js
const CleanWebpackPlugin = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const webpack = require('webpack')
const path = require('path')
module.exports={
entry: './src/main.js',
output:{
//必须为绝对路径
//path.resolve() 解析当前路径的绝对路径
// path.join(__dirname,'./dist/')
path: path.resolve("./dist/"),
filename: 'bundle.js'
},
mode:'development' //不设置默认为production ,
// watch: true, //开启监视模式,自动编译,生成输出文件
devServer:{
open: true,
port: 5000,
hot: ture,
compress: true,
contentBase: '/src',
},
plugins:[
//插件一般引入进来是个构造函数
//根据模板'/src/indtx.html'生成文件'index.html'
new HtmlWebpackPlugin({
filename:'index',
template:'./src/index.html'
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin([{
from: path.join(__dirname,'assets'),
to:'assets'
},
{
from: path.join(__dirname,'image'),
to:'image'
}
]),
new webpack.BannerPlugin('可以为每个chunk文件头部添加banner'),
new webpack.ProvidePlugin({ // 内置插件,在每个模块内部挂载一个jQuery
$:'jquery',
jQuery:'jquery'
}),
new webpack.DefinePlugin({
IS_DEV: 'true',
test1: '"1+1"' //这里的值会当成变量来处理,所以里面要用“” 拼接
})
],
module:{
rules:[
{
test:/\.css$/,
// webapck 读取loader时 是从左到右读取,会将css文件先交给最右侧的loader
// loader的执行顺序是从右到左以管道的方式链式调用
// css-loader:解析css,使其支持css语法格式
// style-loader: 将解析出来的结果放到 html中,使其生效
use:['style-loader','css-loader']
},
{
test:/\.less$/,
//less-loader 只是将less文件转成css语法
use:['style-loader','css-loader','less-loader']
},
{
test:/\.s(a|c)ss$/,
use:['style-loader','css-loader','sass-loader']
},
{
test:/\.jpg|jpeg|png|gif|bmp$/,
use:['file-loader']
},
{
test:/\.(woff|woff2|eot|svg|ttf)$/,
use:['file-loader']
},
{
test:/\.(jpg|jpeg|png|gif|bmp)$/,
use:{
loader:'url-loader',
options:{
/* url-loader功能*/ limit:5*1024, //5kb 如果图片大小 小于5kb直接转成base64
/* file-loader功能*/ outputPath:'images',
/* file-loader功能*/ name:[name]-aaa[hash:4].[ext] //ext扩展名 -中间可以加常量,hash:4 保留4位hash值
}
}
},
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:[
presets:['@babel/env'],
plugins:[
'@babel/plugin-proposal-class-properties',
'@babel/plugin-transform-runtime'
]
]
},
exclude:/node_modules/
},
{
test:/\.(html|htm)$/i,
user{
loader:'html-withimg-loader'
}
},
{
// 用于解析JQuery模块的绝对路径
test:require.resolve('jquery'), // node_modules/jquery/pacakge.json > main
use:{
loader:'expose-loader',
options: '$' // 将引入的jquery挂载到了全局$
}
}
]
},
devtools:'cheap-module-eval-source-map'
}