最近在学习webpack打包原理及过程,在配置出口output时遇到了个难题,就是publicPath配置项,一直没搞明白他有什么作用,官网上就解释它是用来按需加载或者加载外部资源时要用到,当我们打包的时候webpack会在静态文件路径前面添加publicPath的值,当我们把资源放到CDN上的时候,把publicPath的值设为CDN的值就可以了,对于我这种小白来说肯迪是一脸懵逼,所以还是决定自己去一探究竟。
首先我想要说一下publicPath的作用是分环境的,在开发环境中,也就是启动webpack-dev-server时,webpack会将打包好的静态文件放在publicPath中,如果需要访问其中的资源直接加上pubilcPath路径就行,而在生产环境中,当时用webpack进行打包时,webpack会在静态文件前面加上publicPath的值,在这里你可能有个疑问,webpack-dev-server不是启动服务器吗,怎么会进行打包呢?????,实际上是会的,只是我们看不到,他会实时监听你的代码,只要你的代码一变动,他就会打包,同时在默认情况下会将打包后的文件放入更目录下,如果你加上publicPath他就会帮你打包到指定的路径下。下面我们分两种情况来验证一下一个是手动创建的index.html,一个是webpack打包生成的index.html,通过这两种情况我们来分析下publicPath的作用。
首先我们自己搭建一个项目。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200722151955379.png)

这是我的目录结构,首先通过npm init初始化项目,通过npm install webpack webpack-dev-server css-loader style-loader url-loader file-loader -D来安装依赖,
在package.json中加入如下代码

 "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server"
  },

我的webpack.config.js文件

const path = require('path');
// const webpack = require('webpack');
// const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: path.join(__dirname, 'src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename:'bundle.js'
        // publicPath:'/dist/images/'
    },
    mode:'development',
    devtool:'cheap-module-eval-source-map',
    module: {
        rules:[
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.(png|jpg)$/,
                loader: 'url-loader',
                options: {
                    limit: 5000,
                    name: '[name].[hash:8].[ext]',
                    outputPath:'images/'
                }
            }
        ]
    },
    plugins: [
        // new htmlWebpackPlugin() 
    ]
}

style.css如下

.small {
    width: 200px;
    height: 200px;
    background: url(../img/small.jpg) no-repeat;
}
.big {
    width: 500px;
    height: 350px;
    background: url(../img/big.jpg) no-repeat;
}

index.js 如下

import './css/style.css';
import img from './img/big.jpg';

var img1 = document.createElement('img');
img1.src = img;
document.body.appendChild(img1);

自己创建的index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div class="small"></div>
    <div class="big"></div>
    <script src="./bundle.js"></script>
</body>
</html>

因为上面我们讲了,webpack-dev-server将打包好的文件放入根目录下,里面包含bundle.js,所以我们这里才能引用,然后我们通过npm run dev启动我们的项目,我们看看结果
在这里插入图片描述

我们看到可以正确显示,现在我们执行npm run build进行打包,打包完成之后我们直接用浏览器打开我们手动创建的index.html文件,同时我们将index.html中img的src改成./dist/bundle.js因为我们打包后的文件会在根目录下的dist目录中,浏览器打开我们的indedx.html后我们发现没有图片显示,我们来看下控制台在这里插入图片描述
我们可以看到图片的地址是images/…可是我们更目录下更本没有images文件夹,所以我们当然找不到,这时我们的publicPath登场了,我们在webpack.config.js中将output改为

 output: {
        path: path.join(__dirname, 'dist'),
        filename:'bundle.js',
        publicPath:'./dist/'
    },

这是什么意思呢,在生产环境我们打包的时候会在静态资源地址前面加上我们publicPath的值现在图片的地址就会变为./dist/images/…,我们上删掉ist目录重新打包一下,图片就会显示出来,结果就不看了,我们看下控制台
在这里插入图片描述
这就和我哦们所说的一样了,这时浏览器就会去寻找当前目录也就是根目录下的dist目录中的images这就找到了我们的照片。
然后我们再试试通过localhost:8080打开试试,我们先将dist目录删掉,方便我们进行试验,这时我们的publicPath就要改一下,不能继续写成./dist/了,为什么呢??,因为生产环境中打包出来的静态资源地址是根目录下images/…,所以我们要加上./dist,而我们这是开发环境,我们加上我们的publicPath的话会将我们的资源打包放入该位置,同时也会在静态资源地址前面加上我们的值,这时我们的地址就会变成/dist/images/…,我们启动项目时会将我们打包好的文件放入根目录下的dist文件夹中,这时我们就能找到我们的图片,所以我们改成/dist/,我们通过npm run dev启动我们的项目
在这里插入图片描述
在这里插入图片描述

从这里我们可看到,却是生成了dist目录
在这里插入图片描述
我们的项目正常运行,我们来分析下怎么运行的,整个项目运行在localhost:8080下面,也就是服务器地址是localhost:8080 , 当我们在浏览器中输入服务器地址,服务器会寻找它下面的index.html文件,并返回给浏览器,因为我们的项目在自己创建的目录下启动的,它下面有index.html,这没有问题,浏览器在接受到index.html 就开始解析,它碰到script标签就会向服务器请求js 文件,js的地址是./dist/bundle.js,服务器就会在dist目录下找bundle.js. 根据我们所知道的,当有publicPath 配置时,webpack-dev-server 会把打包后的资源放到publicPath 指定的目录,也就是dist 目录下,所以服务器是在dist 目录下可以找到。

下面我们看看自动生成的index.html有什么区别,删掉index.html,通过npm安装html-webpack-plugin,webpack.config.js 修改如下

const path = require('path');
const webpack = require('webpack');
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: path.join(__dirname, 'src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename:'bundle.js',
        publicPath:'/dist/'
    },
    mode:'development',
    devtool:'cheap-module-eval-source-map',
    module: {
        rules:[
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.(png|jpg)$/,
                loader: 'url-loader',
                options: {
                    limit: 5000,
                    name: '[name].[hash:8].[ext]',
                    outputPath:'images/'
                }
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin() 
    ]
}

npm run dev 启动服务器,浏览器,输入localhost:8080,可以看到服务器下面,都没有index.html 这个文件
在这里插入图片描述
这和上面我讲的是一样的,配置文件被打包到了dist目录下面,但是我们看不见,我们在8080后面加上我们的dist,我们会发现页面上会出现一张图片,这是通过我们js加载出来的图片,这也充分证明了,webpack-dev-server 会把所有的文件打包到publicPath指定的目录。这样访问有点不太方便了,最简单的办法,就是把publicPath配置去掉,这样webpack-dev-server就会把文件打包到根目录下,localhost:8080就会访问。

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐