webpack
-
path
默认值:process.cwd()
output.path 目录对应一个绝对路径, 最后 path 会输出到物理硬盘上的。
const path = require('path');
module.exports = {
//...
output: {
path: path.resolve(__dirname, 'dist/assets')
}
};
-
publicPath
默认值:空字符串
此选项指定在浏览器中所引用的「此输出目录对应的公开 URL」。相对 URL(relative URL) 会被相对于 HTML 页面(或 <base>
标签)解析。相对于服务的 URL(Server-relative URL),相对于协议的 URL(protocol-relative URL) 或绝对 URL(absolute URL) 也可是可能用到的,或者有时必须用到,例如:当将资源托管到 CDN 时。
简单规则如下:
webpack.config.js
const path = require('path');
module.exports = {
//...
output: {
publicPath: 'https://cdn.example.com/assets/'
}
};
比如在页面引入了background-image:url(‘/people.png’);最终页面中引入图片的地方路径就会相对publicPath做调整为:
https://cdn.example.com/assets/people.png
浏览器访问的链接 = output.publicPath + 静态资源的地址
output.publicPath 是很重要的选项。如果指定了一个错误的值,则在加载这些资源时会收到 404 错误。
webpack-dev-server
-
publicPath
在开发阶段,我们借用 devServer 启动一个开发服务器进行开发,这里也会配置一个 publicPath
,这里的 publicPath
路径下的打包文件可以在浏览器中访问。而静态资源仍然使用 output.publicPath
。
webpack-dev-server 打包的内容是放在内存中的,这些打包后的资源对外的的根目录就是 publicPath
,换句话说,静态资源在内存中的路径都是以 publicPath 为准的
。
确保 devServer.publicPath
始终以正斜杠开头和结尾
webpack.config.js
module.exports = {
//...
devServer: {
publicPath: 'http://localhost:8080/assets/'
}
};
构建产物 bundle.js 将以 http://localhost:8080/assets/bundle.js
链接提供。
从文档中,我们可以看到 `建议
devServer.publicPath
与output.publicPath
相同`,这是为啥?
因为平时我们项目生成 html 文件都是使用 webpack 插件 html-webpack-plugin 生成,其中涉及到 js、css、img 的静态文件的路径处理,html-webpack-plugin 是基于 output.publicPath 生成最终访问链接的。
如果 webpack-dev-server 的 publicPath
和 output.publicPath
不一致,在使用 html-webpack-plugin 可能会导致引用静态资源失败,因为在 webpack-dev-server 中生成 html 时,html-webpack-plugin 仍然以 output.publicPath
引用静态资源,和 webpack-dev-server 的提供的资源访问路径不一致,从而无法正常访问。
-
contentBase
默认情况下,它将使用当前的工作目录来提供内容。 要禁用 contentBase
,请将其设置为 false
。
用于提供静态资源,只有在你想要提供静态文件时才需要。
注:可以不是本地打包出来的静态资源,比如文件夹中有 /public/mock.json
webpack.config.js
const path = require('path');
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'public')
}
};
访问 http://localhost:8080/mock.json 即可。
还可搭配 contentBasePublicPath 使用,比如上面这个例子把 public 文件夹抹平了,实际生产环境,我们为了区分,需要加上文件前缀用于区分,最终访问的地址 http://localhost:8080/data/mock.json;那么我们就可以搭配 contentBasePublicPath 来实现了:
webpack.config.js
const path = require('path');
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'public'),
contentBasePublicPath: '/data'
}
};
可以理解为拦截 `/data` 的请求,重定向到 /public 目录下。其中内部通过 express.static 使用,感兴趣可以自行了解,不是本文重点,这里不拓展啦。