前言
看到标题很多人会觉得作者是不是语痴了。。。。实际这两个publicPath,分别指output属性里的publicPath和devServer中的publicPath,这篇文章主要是来讨论这两个publicPath到底有什么用,到底有什么区别的,之前作者本人阅读了大量的网上的资料和官网的文档,对于这二者的理解一直处于混沌状态,这次开此文的目的就是要把它们二者到底怎么用说清楚了,同时也是给自己留个备份,万一哪天又搞忘了。。。。好了,言归正传,我用一个简单的webpack案例来演示整个webpack的基本使用,以及publicPath和publicPath的不同之处。
首先看一下整个代码结构:
然后我们分别将各个代码贴上,解释其关系
1.main.js的代码,main.js中引入了test.js的say方法和main.css的内容
import say from './test'
import './css/main.css'
say()
2.test.js的代码,test.js中引入了一张叫login-bg.jpg的图片,同时通过console.log输出了图片的路径信息
import img from './img/login-bg.jpg'
export default function say() {
console.log(img)
console.log('hellow world')
}
3.main.css的代码,main.css的代码中设置背景图片为img.jpg
.app{
color:red;
font-size: 24px;
width:150px;
height:100px;
background-image: url('../img/img.jpg');
background-repeat: no-repeat;
}
4.重点来了...webpack.config.js文件 ....重点在上
,同时需要注意真实文件保存路径和文件引用路径这两者是不同的意思。
const path = require('path')
const webpack = require('webpack')
const htmlWebpackPlugin = require('html-webpack-plugin');
const miniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js',
//output的publicPath决定了异步加载的js,使用htmlWebpackPlugin插入的bundle.js,从css中引入的图片或字体,以及miniCssExtractPlugin分离的css的路径,这个路径是文件引用路径
publicPath: '/custom2/'
},
mode: 'development',
devServer: {
//devServer在没有使用htmlWebpackPlugin时,决定了bundle.js,引入的css,图片的真实保存路径,这时候只有修改output.publicPath为devServer.publicPath一样的值,才可以图片正常显示和js,css正常使用
//devServer在使用htmlWebpackPlugin时,就不光决定了以上那些,还决定了htmlWebpackPlugin根据模板生成的主html的路径(localhost:8080/custom/index123.html)
//总的来说devServer中的publicPath决定了,采用webpack-dev-server启动的网页的所有资源路径,也就是说所有的资源保存路径都是localhost:8080/custom/xxx,
//用webpack-dev-server启动时,因为使用了htmlWebpackPlugin和miniCssExtractPlugin,所以生成的文件引用路径都是http://localhost:8080/custom2/bundle.js和http://localhost:8080/custom2/main.css,但是这两个路径都不是
//真实的资源保存路径,真实的资源保存路径是http://localhost:8080/custom/bundle.js和http://localhost:8080/custom/main.css,只有这两个路径才能访问到css和js文件
publicPath: "/custom/"
},
module: {
rules: [
// {
// //css样式被bundle.js注入到html页面的style里
// test: /\.css$/i,
// exclude: /node_modules/,
// use: ['style-loader', 'css-loader']
// },
{
test: /\.css$/i,
exclude: /node_modules/,
use: [{
loader: miniCssExtractPlugin.loader
}, 'css-loader']
},
{
//file-loader的注意事项(使用webpack-dev-server启动)
//1.如果file-loader的publicPath和outputPath都不设置,
//图片文件引用路径就会和output.publicPath一致(http://localhost:8080/custom2/img.jpg),
//但真正的图片保存路径就会和devServer.publicPath一致(http://localhost:8080/custom/img.jpg)
//2.如果设置了file-loader的publicPath,不设置file-loader的outputPath,
//图片文件引用路径会跟着devServer.publicPath + file-loader的publicPath一致(http://localhost:8080/custom/images/img.jpg),
//但真正图片保存路径却跟devServer.publicPath一致(http://localhost:8080/custom/img.jpg),
//3.如果设置了file-loader的outputPath,不设置file-loader的publicPath,
//则图片文件引用路径会跟着output.publicPath+file-loader的outputPath一致(http://localhost:8080/custom2/images2/img.jpg),
//在使用webpack-dev-server时候,真正的图片保存路径和devServer.publicPath + file-loader的outputPath一致(http://localhost:8080/custom/images2/img.jpg)
//4.如果两个都设置,但设置的值不一样,文件引用路径跟着devServer.publicPath+file-loader的publicPath一致(http://localhost:8080/custom/images/img.jpg),
//但真正的图片保存路径却跟着file-loader的devServer.publicPath + outputPath一致(http://localhost:8080/custom/images2/img.jpg),
//5.file-loader的publicPath其实对应覆盖的是output.publicPath
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './images2/',
publicPath: './images/'
}
},
],
},
]
},
plugins: [
//在custom下以index.html为模板生成index123.html文件,同时将
//bundle.js插入html文件的body底部
new htmlWebpackPlugin({
template: './index.html',
filename: 'index123.html'
}),
// 将css样式抽取到单个css文件中,以link文件的方式插入到index123.html的head中
new miniCssExtractPlugin({
filename: '[name].css'
})
]
}
在webpack中,我使用了两个插件,一个htmlWebpackPlugin,另一个miniCssExtractPlugin,前者用于根据指定的template文件(index.html)生成dist中的html文件(我这里是index123.html),同时将打包的js文件(我这里是bundle.js)插入生成的html中;后者是将css样式抽取成单个的css文件,并将css文件插入到生成的html中。
5.index.html代码也贴上来
Document
app的应用