Webpack中的“ publicPath”有什么作用?


250

Webpack文档指出output.publicPath

output.path与JavaScript的视图。

您能否详细说明这实际上意味着什么?

我使用output.pathoutput.filename来指定Webpack应该在哪里输出结果,但是我不确定要放入什么output.publicPath以及是否需要它。

module.exports = {
  output: {
    path: path.resolve("./examples/dist"),
    filename: "app.js",
    publicPath: "What should I put here?"   
  } 
}

17
我想补充一下这个问题:什么path时候使用publicPath?什么时候使用?
wmock '16



6
开发团队中的某个人应该醒来。这么多人提出这个问题
Royi Namir

Answers:


133

output.path

本地磁盘目录,用于存储所有输出文件(绝对路径)

例: path.join(__dirname, "build/")

Webpack会将所有内容输出到 localdisk/path-to-your-project/build/


output.publicPath

上载捆绑文件的位置。(相对于服务器根目录)

例: /assets/

假设您将应用程序部署在服务器根目录下http://server/

通过使用/assets/,该应用程序将在以下位置找到Webpack资产http://server/assets/。在后台,webpack遇到的每个URL都将被重写为以“ /assets/” 开头。

src="picture.jpg" 改写➡ src="/assets/picture.jpg"

访问者:(http://server/assets/picture.jpg


src="/img/picture.jpg" 改写➡ src="/assets/img/picture.jpg"

访问者:(http://server/assets/img/picture.jpg


65

在浏览器中执行时,webpack需要知道您将在何处托管生成的包。因此,它能够请求其他块(当使用代码拆分时)或分别通过文件加载器url加载器加载的引用文件。

例如:如果您将http服务器配置为托管生成的捆绑软件,/assets/则应输入:publicPath: "/assets/"


3
您能告诉我资产文件夹在哪里吗?我想查看资产文件夹中的文件谢谢。
gauti

53

publicPath仅用于开发目的,我第一次看到这个config属性时感到很困惑,但是现在使用Webpack已有一段时间了,这很有意义

假设您将所有js源文件都放在src文件夹下,并且配置了webpack以将源文件构建到dist文件夹中output.path

但是,您希望将静态资产放到更有意义的位置,例如webroot/public/assets,这次可以使用out.publicPath='/webroot/public/assets',因此在html中,您可以使用引用js <script src="/webroot/public/assets/bundle.js"></script>

当您请求webroot/public/assets/bundle.jswebpack-dev-server会发现dist文件夹下的JS

更新:

感谢查理·马丁(Charlie Martin)纠正我的回答

原始的:publicPath仅用于开发目的,而不仅仅是用于开发目的

不,该选项在开发服务器中很有用,但其目的是在生产环境中异步加载脚本包。假设您有一个非常大的单页应用程序(例如Facebook)。Facebook不想在每次加载主页时都提供其所有JavaScript,因此它仅提供主页上需要的内容。然后,当您转到个人资料时,它将使用ajax为该页面加载更多的javascript。此选项告诉它在服务器上的哪个位置从中加载该捆绑包


1
@jhnns的答案不仅是出于开发目的,还说明了它如何影响加载程序的输出。
温家宝

是一样的,不是吗?该属性告诉您的加载器和中间件在哪里可以找到真实资产,希望您不会在生产环境中使用webpackmiddleware或webpack-dev-server,所以我认为这仅适用于开发环境,请参阅webpack.github .io / docs / webpack-dev-server.html
肖恩

1
从这个webpack.github.io/docs/configuration.html#output-publicpath看来,此选项告诉webpack在生成的文件中填写正确的url或资产的路径,而不仅仅是中间件。在运行开发服务器时,我认为中间件着眼于publichPath劫持请求并返回内存文件。
2015年

确切地说,在您的生产环境中,您将使用它webpack -p来构建资产,并且资产应由您的应用程序服务器或nginx服务器提供服务,而不是由webpack服务器或webpack中间件提供服务,因此此配置在生产环境中不再有用,对吗? ?
肖恩

7
不,该选项在开发服务器中很有用,但其目的是在生产环境中异步加载脚本包。假设您有一个非常大的单页应用程序(例如Facebook)。Facebook不想在每次加载主页时都提供其所有JavaScript,因此它仅提供主页上需要的内容。然后,当您转到个人资料时,它将使用ajax为该页面加载更多的javascript。此选项告诉它在服务器上的哪个位置从
Charlie Martin

19

您可以使用publicPath指向希望webpack-dev-server服务其“虚拟”文件的位置。publicPath选项将与webpack-dev-server的content-build选项位于相同位置。 webpack-dev-server创建启动时将使用的虚拟文件。这些虚拟文件类似于webpack创建的实际捆绑文件。基本上,您将希望--content-base选项指向index.html所在的目录。这是示例设置:

//application directory structure
/app/
/build/
/build/index.html
/webpack.config.js


//webpack.config.js
var path = require("path");
module.exports = {
...
  output: {
    path: path.resolve(__dirname, "build"),
    publicPath: "/assets/",
    filename: "bundle.js"
  }
};  


//index.html
<!DOCTYPE>
<html>
...
<script src="assets/bundle.js"></script>
</html>

//starting a webpack-dev-server from the command line
$ webpack-dev-server --content-base build 

webpack-dev-server已创建一个虚拟资产文件夹以及它引用的虚拟bundle.js文件。您可以通过转到localhost:8080 / assets / bundle.js进行测试,然后在应用程序中检入这些文件。它们仅在您运行webpack-dev-server时生成。


这样的一个很好的解释,但当时如果我移动到生产或进行手工构建/build/bundle.js我将不得不改变src我的index.html文件吗?
ArchNoob

回复晚了非常抱歉。您不必更改src。无论您是生产还是开发,webpack都会在输出路径中创建bundle.js。在上面的示例中,它将是/build/bundle.js。
艾萨克·帕克

谢谢,我想问一下srcindex.html文件中的这一行。现在,它指向"assets/bundle.js"是否要进入生产阶段,因此捆绑包将进入生产环境,"build/bundle.js"因此我将不得不在html src行中将其更改为src="build/bundle.js"。还是有一种更自动化的方式?
ArchNoob

2
我现在明白你的问题。是的,您需要将src更改为build / bundle.js进行生产。至于执行此操作的自动方式,我不确定。我看到其他人创建了2个不同的webpack.config.js文件,一个用于生产,一个用于开发。在语法上可能有一种类似于if(ENV === production)的方法来执行此操作...但是我还没有尝试过。
艾萨克·帕克

@ArchNoob请立即了解我如何在生产中执行此操作。我没有更改src值,而是将publicPath值从更改/assets//build。这样,我不必更改index.html。我还将index.html移出了build文件夹,移到了应用程序的根目录中。
艾萨克·帕克

15

在我的情况下,我有一个CDN,并且我将所有处理过的静态文件(js,imgs,字体...)放入我的CDN中,假设URL为http://my.cdn.com/

因此,如果存在一个js文件,该文件是html中的原始引用网址是“ ./js/my.js”,则在生产环境中应变为http://my.cdn.com/js/my.js

在这种情况下,我需要做的只是将publicpath设置为http://my.cdn.com/, 然后webpack将自动添加该前缀


在我的情况下,似乎没有添加任何前缀。
Param Singh's

14

filename指定在完成构建步骤后所有捆绑代码将累积的文件名

path指定将在其中将app.js(文件名)保存到磁盘的输出目录。如果没有输出目录,则webpack将为您创建该目录。例如:

module.exports = {
  output: {
    path: path.resolve("./examples/dist"),
    filename: "app.js"
  } 
}

这将创建一个目录的myproject /例子/ DIST和该目录下的它创建app.js/myproject/examples/dist/app.js。构建后,您可以浏览到myproject / examples / dist / app.js以查看捆绑的代码

publicPath:“我应该在这里放什么?”

publicPath指定将从中获取捆绑文件app.js的Web服务器中的虚拟目录。请记住,使用publicPath时,服务器一词可以是webpack-dev-server或express服务器,也可以是可与webpack一起使用的其他服务器。

例如

module.exports = {
  output: {
    path: path.resolve("./examples/dist"),
    filename: "app.js",
    publicPath: path.resolve("/public/assets/js")   
  } 
}

此配置告诉webpack将您的所有js文件捆绑到examples / dist / app.js并写入该文件。

publicPath告诉webpack-dev-server或express服务器从该目录中的指定虚拟位置提供此捆绑文件,即examples / dist / app.js服务器中的即/ public / assets / js)因此,在您的html文件中,您必须将此文件引用为

<script src="public/assets/js/app.js"></script>

因此,总而言之,publicPath就像virtual directory服务器之间的映射,output directory并由output.path配置指定。只要请求文件public / assets / js / app.js,就会提供/examples/dist/app.js文件


2
很好的解释!
加内什·潘迪

3

webpack2文档以更简洁的方式对此进行了解释:https ://webpack.js.org/guides/public-path/#use-cases

webpack具有非常有用的配置,可让您指定应用程序上所有资产的基本路径。它称为publicPath。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.