浅谈webpack配置中output的publicPath属性和devServer的publicPath属性

本文深入解析webpack中publicPath属性的功能,通过对比不同设置下,手动创建html与使用webpack HTML plugin时,资源文件加载路径的变化,阐述其在开发与构建过程中的作用。

长期以来,一直都比较迷惑,不知道publicPath属性的作用,最近抽空,花了点时间研究了下,参考了几篇文档,自己测试了几遍,最后得出了以下几点心得,如有不对,欢迎佐证。

1.当手动创建html时,也就是当我们的工程中,存在一个index.html

工程结构

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>

</head>

<body>

<div id="root">

 

</div>

<script type="text/javascript" src="main.js"></script></body>

</html>

 

此时webpack配置为

 

let config = {

entry: {

main: ['./app/App.js']

},

output: {

path: path.resolve(__dirname, 'dist/assets'),

filename:  '[name].js'

},

module: {

rules: [

{

test: /\.js$/,

exclude: /(node_modules|bower_components)/,

use: {

loader: 'babel-loader',

options: {

presets: ["@babel/preset-env", "@babel/preset-react"]

}

}

}

]

},

plugins: [

new HtmlWebpackPlugin({

template: './src/index.html'

}),

new webpack.NamedModulesPlugin(),

new webpack.HotModuleReplacementPlugin()

],

devServer: {

contentBase: path.join(__dirname, "dist"),//devServer的根目录

hot: true,

port: 9000,

host: 'localhost'

}

}

 

package.json里面的命令如下

"scripts": {

"dev": "node_modules/.bin/webpack-dev-server",

"build": "node_modules/.bin/webpack --config webpack.config.js",

"watch": "webpack --watch"

},

当我们在命令行里面运营npm run dev,在浏览器里面输入http://localhost:9000/ 可以看到我们的index.html里面已经有内容呈现,并且实现了热替换,本次demo是基于react开发的,旨在讲解publicPath的作用,react不作更多解释。

此时假如我们运营npm run build,可以看到在我们的工程目录dist下面的assets里面已经生成了我们想要的main.js,但是通过在浏览器里面访问该html文件,可以看到里面界面是空白的。

原因主要是webpack-dev-server打包生成的文件是写进了内存里面,浏览器控制台中的sources 面板下面可以看到。对应的路径根据根目录(此时的根目录是由devServer的contentBase属性设定的)而定,文件名是按照output定义的filename命名的,这个时候publicPath没有设置,即采用默认值“/”,固打包后在http://localhost:9000/main.js可以看到该文件,但并没有写进磁盘,所以此时通过webpack-dev-server打包可以正常访问内容

2.当我们调整下publicPath的的值,

publicPath: '/dist/assets/' 

我们先执行npm run build ,此时在assets目录下面生成了main.js,这时将index.html引用路径改为src="/dist/assets/main.js"

再运营npm run dev ,发现访问http://localhost:9000还是可以正常访问页面内容,这个时候将index.html的引用路径改为src="/assets/main.js",发现还是可以正常访问,此时如果将assets下面的main.js移除,则无法再正常访问了,再次证明了webpack-dev-server打包生成的文件是写进内存里面的,并且当在内存中找不到相关的依赖文件时,会在磁盘目录下去找,当找到时,则正常引入,找不到时则报错

3.使用webpackHTMLplugin自动创建文件,

plugins里面添加

new HtmlWebpackPlugin({

template: './src/index.html'

}),

运行npm run dev时,可以看到再用原来的路径已经访问不到页面了,改为http://localhost:9000/dist/assets/index.html又能正常访问了,但是磁盘目录下面依旧没有生成该文件,证明使用了webpackHTMLplugin之后还是在内存里面开辟了一片空间去存放打包文件

假设此时再次改变打包之后html文件的存放地址,往assets的上一层目录存放

new HtmlWebpackPlugin({

template: './src/index.html',

filename: '../index.html'

}),

此时再npm run dev ,发现不管怎么样都访问不到index.html了,说明使用HtmlWebpackPlugin时,在devServer模式下,是不能任意指定index.html的存放地址的,要么就手动在对应位置添加一个index.html

 

<think> 我们正在讨论Webpack中的两个配置项:`output.path` `output.publicPath`。根据引用[1]引用[4],我们可以总结如下: 1. **`output.path`**: - 指定Webpack打包后文件输出的**物理路径**(在本地文件系统上的目录)。 - 例如,配置为`path: path.resolve(__dirname, "dist")`,那么所有打包生成的文件(如JS、CSS、图片等)都会输出到项目根目录下的`dist`文件夹中。 - 这个路径是用于构建过程,与最终资源在服务器上的位置无关。 2. **`output.publicPath`**: - 指定构建生成的资源在浏览器中访问时的**基础URL路径**(公共路径)。 - 例如,配置为`publicPath: "/assets/"`,那么浏览器中加载资源的路径会是`http://example.com/assets/bundle.js`。 - 这个路径是运行时路径,影响的是资源被加载时的URL前缀。 ### 本质区别 | 配置项 | 作用对象 | 影响范围 | 示例 | 本质 | |----------------|----------------|------------------|------------------------------|------------------------| | `output.path` | **构建过程** | 文件输出位置 | 本地磁盘目录:`./dist` | 文件系统的物理路径 | | `output.publicPath` | **运行时** | 资源访问路径 | 线上URL前缀:`/assets/` 或 `https://cdn.example.com/` | 资源在浏览器中的公共基础路径 | ### 具体说明 - **`path`是构建时的概念**:它决定了打包后的文件放在哪里。比如,如果你运行`webpack`命令,生成的文件会写入到`path`指定的目录中。 - **`publicPath`是运行时的概念**:它决定了当你的网页在浏览器中运行时,从哪里加载这些打包好的资源。例如: - 如果`publicPath`是相对路径`./`,则资源会从当前HTML文件所在的目录加载。 - 如果`publicPath`是绝对路径`/assets/`,则资源会从服务器的根目录下的`assets`目录加载。 - 如果`publicPath`是完整的URL(如`https://cdn.example.com/`),则资源会从CDN加载。 ### 举例说明 假设项目目录结构如下: ``` my-project/ src/ index.js dist/ index.html main.js ``` - **Webpack配置**: ```javascript module.exports = { output: { path: path.resolve(__dirname, 'dist'), // 文件输出到dist目录 filename: 'main.js', publicPath: '/assets/', // 浏览器访问路径为 /assets/main.js } }; ``` - **结果**: - 打包后,`main.js`文件会被输出到`my-project/dist/main.js`(物理路径)。 - 但在HTML中引用该JS时,路径会是`<script src="/assets/main.js"></script>`(由`publicPath`决定)。 ### 动态publicPath的特殊性 根据之前的讨论,`publicPath`也可以动态设置(通过`__webpack_public_path__`),但`path`是静态的,只能在构建时确定。 ### 相关问题 1. Webpack中的`publicPath`默认值是什么? 2. 如何为不同资源(如图片、字体)设置不同的`publicPath`? 3. 使用`webpack-dev-server`时,`publicPath`的作用有何不同? </think> ### Webpack 中 `publicPath` `path` 配置的本质区别 在 Webpack 配置中,`output.path` `output.publicPath` 是两个核心但作用完全不同的配置项,它们的本质区别如下: #### 1. **`output.path`:文件输出位置** - **本质**:指定**打包后文件的物理存储路径**(本地文件系统)。 - **作用对象**:Webpack 构建过程。 - **示例**: ```javascript output: { path: path.resolve(__dirname, "dist"), filename: "bundle.js" } ``` - **结果**:所有打包文件(JS/CSS/图片等)将输出到项目根目录的 `dist` 文件夹中。 - **特点**: - 与服务器无关,仅决定文件在本地磁盘的位置。 - 必须使用绝对路径(通常通过 `path.resolve()` 生成)[^1][^3]。 #### 2. **`output.publicPath`:资源访问路径** - **本质**:指定**浏览器加载资源的基础 URL 路径**(运行时路径)。 - **作用对象**:客户端浏览器。 - **示例**: ```javascript output: { publicPath: "/assets/", filename: "bundle.js" } ``` - **结果**:浏览器会从 `http://example.com/assets/bundle.js` 加载资源。 - **特点**: - 影响 HTML 中资源引用的前缀(如 `<script src="/assets/bundle.js">`)[^1][^4]。 - 支持动态配置(通过 `__webpack_public_path__` 运行时覆盖)[^1]。 - 可为相对路径 (`./`)、绝对路径 (`/assets/`) 或完整 URL (`https://cdn.com/`) [^4]。 --- ### 关键区别总结 | **特性** | `output.path` | `output.publicPath` | |-------------------|--------------------------------|-----------------------------------| | **作用目标** | 构建过程(文件输出位置) | 运行时(资源加载路径) | | **配置类型** | 本地文件系统路径(绝对路径) | URL 路径(相对/绝对/完整 URL) | | **影响范围** | 决定文件在磁盘的存储位置 | 决定浏览器如何拼接资源 URL | | **动态性** | 构建时确定,静态不可变 | 支持运行时动态修改 | | **典型值示例** | `path.resolve(__dirname,dist)` | `"/assets/"`, `"https://cdn.com/"` | | **必要性** | 必须配置 | 可选(默认值:空字符串 `""`) | --- ### 场景对比说明 1. **开发环境 (webpack-dev-server)** - `publicPath`: 通常为 `/`(本地服务器根路径) → 资源通过 `http://localhost:8080/bundle.js` 访问[^1]。 - `path`: 仅用于模拟输出(文件不实际写入磁盘)[^1]。 2. **生产环境 (CDN 部署)** ```javascript output: { path: path.resolve(__dirname, "dist"), // 文件输出到本地 dist 目录 publicPath: "https://cdn.example.com/app/", // 浏览器从 CDN 加载资源 } ``` - 构建结果:文件写入 `./dist/bundle.js` - 实际访问:`https://cdn.example.com/app/bundle.js`[^4]。 --- ### 解析常见误区 - **误区**:`publicPath` 影响文件输出位置 **正解**:文件始终输出到 `path` 指定目录;`publicPath` 只改变 HTML 中的引用路径。 - **误区**:两者必须相同 **正解**:可完全独立(如 `path` 指向本地目录,`publicPath` 指向 CDN)[^1][^4]。 > **示例**:若配置 `path: "./dist"` + `publicPath: "/assets/"`: > - 文件实际位置:`项目根目录/dist/bundle.js` > - 浏览器加载路径:`http://example.com/assets/bundle.js` --- ### 总结 - **`path` 是构建概念**:定义 **“文件存到哪”**(物理路径)。 - **`publicPath` 是运行时概念**:定义 **“浏览器从哪加载”**(逻辑路径)。 两者协作实现一次构建、多环境部署的灵活性[^1][^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值