webpack之publicPath
webpack之publicPath
什么是publicPath
publicPath: 通过它来指定所有资源的基础路径
发送到 output.path
目录的每个文件,都将从 output.publicPath
位置引用。这也包括(通过 代码分离 创建的)子 chunk 和作为依赖图一部分的所有其他资源(例如 image, font 等),某些loader有publicPath
选项,可以覆盖此处定义的publicPath
例:
module.exports = {
output: {
path: 'dist',
// 指定public path
publicPath: '/module/sub',
filename: "js/[name].[contenthash:8].js",
chunkFilename: "js/[name].[contenthash:8].js"
}
}
2
3
4
5
6
7
8
9
通过html-webpack-plugin自动生成html如下:
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="/module/sub/favicon.ico">
<title>sub-micro-app</title>
<link href="/module/sub/css/app.59fb9246.css" rel="preload" as="style">
<link href="/module/sub/js/app.6aa9ef33.js" rel="preload" as="script">
<link href="/module/sub/js/chunk-vendors.547e0756.js" rel="preload" as="script">
<link href="/module/sub/css/app.59fb9246.css" rel="stylesheet">
</head>
<body><noscript><strong>We're sorry but sub-micro-app doesn't work properly without JavaScript enabled. Please enable it
to continue.</strong></noscript>
<div id="app"></div>
<script src="/module/sub/js/chunk-vendors.547e0756.js"></script>
<script src="/module/sub/js/app.6aa9ef33.js"></script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
可以看到,所有资源的路径都加上了publicPath
这段基础路径
webpack-dev-server
启动后的访问地址也受publicPath
影响,如果publicPath
是有效的绝对路径或者相对路径,则开发服务启动后访问的地址为[host]:[port]/[publicPath]
在运行时设置publicPath
webpack提供了**__webpack_public_path__**这个公共变量,可以在运行时修改引入资源的publicPath
例如,在vue中通过img引入了一张图片,该图片最终会经过file-loader处理
此时,将webpack配置中的publicPath改为www.baidu.com
webpack.config.js
module.exports = {
output: {
publicPath: "www.baidu.com"
}
}
2
3
4
5
// example.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
</div>
</template>
2
3
4
5
6
7
将此文件打包后输出的代码为:
// 只截取了创造img元素这部分代码
// 可以看到 src 是一个动态值 r('cf05),就是取cf05这个模块输出的值
n('img', { attrs: { alt: 'Vue logo', src: r('cf05') } })
...
// cf05输出
cf05: function(e, t, r) {
e.exports = r.p + 'img/logo.82b9c7a5.png';
}
// r.p其实就是__webpack_require__.p这个变量
// 可以看到__webpack_require__.p被设置为了www.baidu.com
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "www.baidu.com/";
/******/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
可以通过在运行时代码中修改**_webpack_public_path_**这个变量以动态修改这个值:
__webpack_public_path__ = 'www.google.com';
注意**_webpack_public_path_**不是window上的全局变量,而是一个标记值,在打包的时候这段代码会被替换为
__webpack_require__.p = "www.google.com/";
warning
如果entry文件中使用的是es2015 module import,则会在import之后对__webpack_public_path赋值。在这种情况下,你必须将 public path 赋值移至一个专用模块中,然后将它的 import 语句放置到 entry.js 最上面:
// publicPath.js
__webpack_public_path = "/base"
2
entry js:
// main.js
import './publicPath'
import 'others'
...
2
3
4