devServer.contentBase 和devServer.publicPath的作用
先说结论
-
devServer.contentBase就是提供给服务器的访问目录,比如服务端口是8080,那么当你直接访问localhost:8080时,访问的目录就是contentBase设置的目录 -
devServer.publicPath就是启动本地服务时,代码打包后的输出路径(用本地调试时,代码也会先被打包,只不过打包后的代码是存在内存中的,不是存于本地硬盘)
为了更好叙述devServer.contentBase和devServer.publicPath的作用,先把项目中的相关配置内容附上
const context = path.join(__dirname, '..')
// 打包输出的目录
const outDir = path.join(context, 'dist') // 相当于 const outDir = path.resolve(__dirname, '../dist')
const webConfig ={
entry: {
app: [
'@babel/polyfill', // async await 要这个
path.join(context, 'src/main')
]
},
output: {
filename: 'static/js/[name].js',
path: outDir,
publicPath: '/client' //打包出来后,引入静态资源的地址中添加的前缀
},
}
webConfig.devServer = {
stats: {
colors: true,
children: false,
modules: false,
entrypoints: false
},
hot: true,
host: host,
port: port,
inline: true,
open: false,
contentBase: outDir, // 提供给服务器的访问目录
quiet: true,
publicPath: '/client/', // 项目被打包后的输出路径
}
下面结合本地启动的项目及图片的形式,来更通俗易懂得说明上面配置的作用
从上面的第一张图片中可以看到,当在浏览器中输入http://localhost:8088/client/时, 加载回来的是一个html页面,这个默认生成的html页面,是因为项目中使用了html-webpack-plugin插件,所以打包后,会输出一个html文件。
那么假如路径上不带/client/,也就是 http://localhost:8088/ 这样去请求,会出现什么情况呢?
访问的其实就是上面devServer.contentBase设置的路径(也就是提供给服务器访问的目录),由于devServer.contentBase和output.path值是一样的,所以访问的就相当于是运行npm run build打包出来的dist目录,如下图所示
需要注意的是,如果我们配置了devServer.publicPath,那么output.publicPath也要改成对应的值才行,就像下面图示一样
假如output.publicPath不是/client的话,那么打包出来的代码中,资源的加载路径就是/static/js/vendor.js,那么就会出现404资源找不到的报错
还有一个需要注意的地方是路由配置文件的base值也要设置一下
export default new Router({
mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
base: '/client/',//如果这里不给路由加上对应的前缀的话,会导致路由映射错误,加载不出我们的页面
routes: routes
})
其他
如果在调试页面时出现 Cannot GET /xxxx 的错误提示,证明资源找不到,这时候可以在地址栏中输入http://localhost:8088/webpack-dev-server (具体端口换成自己的项目中的即可),然后会看到被打包出来的资源,直接点击所需访问的资源,即可看到正确的访问路径了。