vue-cli3访问不到public目录下的json数据

发布时间:

写在前面:通过vue快速入门,虽然入门了,但是后续的一些配置确实很麻烦。查阅了很多资料博客,发现许多要么不全,要么就是自己也没解决。所以在此详细记录解决问题的过程。

1.项目分析解决办法

项目背景

使用vue-cli3创建vue项目后,在src下访问不到public中存放的json静态数据。

错误提示

vue-cli3访问不到public目录下的json数据

 解决办法

vue-cli3访问不到public目录下的json数据

在项目中找到vue.config.js修改配置 (全部替换即可)

module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080', //路径指向本地主机地址及端口号
ws: true,
changeOrigin: true,
pathRewrite:{
'^/api': '/mock' //路径转发代理
}
}
}
}
}

这里的 /api 相当于映射的是 /mock,所以在组件中引用,也需要写成/api/home.json。

 this.axios.get('/api/home.json').then(function (sucess) {
// console.log(this);
console.log(sucess);
}, function (err) {
console.log(err);
})

访问测试

vue-cli3访问不到public目录下的json数据

错误解决,可以拿到数据了。

以下是对配置文件的分析,属于拓展内容!

2. vue.config.js 全局配置

配置参数:

2.1.两种配置方式

module.exports = {
// 选项……
}
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
// 选项……
})

2.2.baseUrl / publicPath

静态资源地址。

module.exports = {
	// baseURL:'./'// vue-cli版本是3.2.0以前的
	publicPath:'./' // publicPath属性适用于vue-cli 高于3.2.0的项目
}

不同开发环境的切换模式:

module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/生产环境路径/' : '/'
}

publicPath

原来的baseUrl,从Vue CLI 3.3 起已弃用baseUrl改用publicPath

部署应用包时的基本 URL。用法和 webpack 本身的 output.publicPath 一致,但是 Vue CLI 在一些其他地方也需要用到这个值,所以始终使用 publicPath 而不要直接修改 webpack 的 output.publicPath。

默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上,例如 https://www.my-app.com/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.my-app.com/my-app/,则设置 publicPath 为 /my-app/

这个值也可以被设置为空字符串 ('') 或是相对路径 ('./'),这样所有的资源都会被链接为相对路径,这样打出来的包可以被部署在任意路径,也可以用在类似 Cordova hybrid 应用的文件系统中。

相对 publicPath 的限制 相对路径的 publicPath 有一些使用上的限制。在以下情况下,应当避免使用相对 publicPath:

  • 使用基于 HTML5 history.pushState 的路由时;
  • 使用 pages 选项构建多页面应用时。

2.3.outputDir

生产环境构建文件的目录地址。

module.exports = {
outputDir:'newBuild'
}

当运行 vue-cli-service build 时生成的生产环境构建文件的目录注意目标目录的内容在构建之前会被清除 (构建时传入 --no-clean 可关闭该行为)。

提示: 请始终使用 outputDir 而不要修改 webpack 的 output.path。

2.4.assetsDir

放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。

module.exports = {
assetsDir:'staticDir'
}

2.5.indexPath

指定生成的 index.html 的输出路径 (相对于 outputDir)。

module.exports = {
indexPath:'indexHtmlPath'
}

2.6.filenameHashing

生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存,通过将这个选项设为 false 来关闭文件名哈希。

module.exports= {
	filenameHashing:false,
}

文件名hash加密设置。

参考:VUE 打包删除文件、图片的HASH码_清风细雨_林木木的博客-CSDN博客_vue 去除hash

2.7.pages

在 multi-page 模式下构建应用。每个“page”应该有一个对应的 JavaScript 入口文件。其值应该是一个对象,对象的 key 是入口的名字,value 是:

  1. 指定 entry, template, filename, title 和 chunks 的对象 (除了 entry 之外都是可选的)
  2. 指定其 entry 的字符串
module.exports = {
pages: {
index: {
// page 的入口
entry: 'src/index/main.js',
// 模板来源
template: 'public/index.html',
// 在 dist/index.html 的输出
filename: 'index.html',
// 当使用 title 选项时,
// template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
title: 'Index Page',
// 在这个页面中包含的块,默认情况下会包含
// 提取出来的通用 chunk 和 vendor chunk。
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
// 当使用只有入口的字符串格式时,
// 模板会被推导为 `public/subpage.html`
// 并且如果找不到的话,就回退到 `public/index.html`。
// 输出文件名会被推导为 `subpage.html`。
subpage: 'src/subpage/main.js'
}
}

2.8.lintOnSave

开发环境下通过 eslint-loader 在每次保存时 lint 代码

设置为 true 或 warning 时,eslint-loader 会将 lint 错误输出为编译警告。默认情况下,警告仅仅会被输出到命令行,且不会使得编译失败。

如果你希望让 lint 错误在开发时直接显示在浏览器中,你可以使用 lintOnSave: ‘default’。这会强制 eslint-loader 将 lint 错误输出为编译错误,同时也意味着 lint 错误将会导致编译失败。

设置为 error 将会使得 eslint-loader 把 lint 警告也输出为编译错误,这意味着 lint 警告将会导致编译失败。

或者,你也可以通过设置让浏览器 overlay 同时显示警告和错误:

// vue.config.js
module.exports = {
devServer: {
overlay: {
warnings: true,
errors: true
}
}
}

当 lintOnSave 是一个 truthy 的值时,eslint-loader 在开发和生产构建下都会被启用。如果你想要在生产构建时禁用 eslint-loader,你可以用如下配置:

// vue.config.js
module.exports = {
lintOnSave: process.env.NODE_ENV !== 'production'
}

2.9.devServer

让浏览器 overlay 同时显示警告和错误

module.exports = {
devServer: {
overlay: {
warnings: true,
errors: true
}
}
}

文件初始值:

/**
 * @type {import('@vue/cli-service').ProjectOptions}
 */
module.exports = {
// 选项...
}

或者,也可以使用 @vue/cli-service 提供的 defineConfig 帮手函数,以获得更好的类型提示:

// vue.config.js
const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({
// 选项
})

2.10.runtimeCompiler

对比:vue中runtimecompiler和runtimeonly的区别

如果在之后的开发中,你依然使用template,就需要选择runtimecompiler 如果你之后的开发中,使用的是.vue文件夹开发,那么可以选择runtimeonly

runtimecompiler

vue-cli3访问不到public目录下的json数据

runtimeonly

vue-cli3访问不到public目录下的json数据

transpileDependencies

默认情况下 babel-loader 会忽略所有 node_modules 中的文件。你可以启用本选项,以避免构建后的代码中出现未转译的第三方依赖。

不过,对所有的依赖都进行转译可能会降低构建速度。如果对构建性能有所顾虑,你可以只转译部分特定的依赖:给本选项传一个数组,列出需要转译的第三方包包名或正则表达式即可。

productionSourceMap

不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建

configureWebpack

这个值是一个对象,会通过 webpack-merge 合并到最终的配置中。

如果这个值是一个函数,则会接收被解析的配置作为参数。该函数既可以修改配置并不返回任何东西,也可以返回一个被克隆或合并过的配置版本。

chainWebpack

是一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改。

css.requireModuleExtension

默认情况下,只有 *.module.[ext] 结尾的文件才会被视作 CSS Modules 模块。设置为 false 后你就可以去掉文件名中的 .module 并将所有的 *.(css|scss|sass|less|styl(us)?) 文件视为 CSS Modules 模块。

css.extract

是否将组件中的 CSS 提取至一个独立的 CSS 文件中 (而不是动态注入到 JavaScript 中的 inline 代码)。

同样当构建 Web Components 组件时它总是会被禁用 (样式是 inline 的并注入到了 shadowRoot 中)。

当作为一个库构建时,你也可以将其设置为 false 免得用户自己导入 CSS。

提取 CSS 在开发环境模式下是默认不开启的,因为它和 CSS 热重载不兼容。然而,你仍然可以将这个值显性地设置为 true 在所有情况下都强制提取。

css.sourceMap

是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能。

css.loaderOptions

向 CSS 相关的 loader 传递选项。例如:

module.exports = {
css: {
loaderOptions: {
css: {
// 这里的选项会传递给 css-loader
},
postcss: {
// 这里的选项会传递给 postcss-loader
}
}
}
}

devServer

有些值像 host、port 和 https 可能会被命令行参数覆写。

有些值像 publicPath 和 historyApiFallback 不应该被修改,因为它们需要和开发服务器的 publicPath 同步以保障正常的工作。

devServer.proxy

如果你的前端应用后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器。这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。

devServer.proxy 可以是一个指向开发环境 API 服务器的字符串:

module.exports = {
devServer: {
proxy: 'http://localhost:4000'
}
}

更多的代理控制行为,也可以使用一个 path: options 成对的对象

module.exports = {
devServer: {
proxy: {
'/api': {
target: '<url>',
ws: true,
changeOrigin: true
},
'/foo': {
target: '<other_url>'
}
}
}
}

pluginOptions

这是一个不进行任何 schema 验证的对象,因此它可以用来传递任何第三方插件选项。例如:

module.exports = {
pluginOptions: {
foo: {
// 插件可以作为 `options.pluginOptions.foo` 访问这些选项。
}
}
}

Babel

Babel 可以通过 babel.config.js 进行配置。

ESLint

ESLint 可以通过 .eslintrc 或 package.json 中的 eslintConfig 字段来配置。

TypeScript

TypeScript 可以通过 tsconfig.json 来配置。

3.实例演示

vue.config.js

(基本讲解在注释,详细讲解在实例下)

module.exports = {
lintOnSave: true, // ------------------------ 设置在开发环境下每次保存代码都启用eslint验证
productionSourceMap: false, // -------------- 设置生产环境的 source map 开启与关闭
css: { // ----------------------------------- 全局引入公共样式文件
loaderOptions: {
sass: {
data: `@import "@src/css/base.scss";`
}
}
}
chainWebpack: (config) => { // -------------- webpack 配置
config.externals({ // --------------------- 忽略打包的文件
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios',
'element-ui': 'ELEMENT',
})
const entry = config.entry('app') // ------ 入口起点
entry
.add('babel-polyfill') // --------------- 添加插件,用于实现浏览器不支持原生功能的代码,例如对于一些不支持ES6的浏览器
.end()
entry
.add('classlist-polyfill') // ----------- 解决部分浏览器不支持一些方法,添加以后达到能支持的效果,例如element.classlist.add()方法在ie9中是不支持
.end()
entry
.add('@/mock') // ----------------------- 添加mock
.end()
},
devServer: { // ----------------------------- 代理
// 端口配置
port: 1888,
// 反向代理配置
proxy: {
'/api': {
target: 'https://saber.bladex.vip',
ws: true, // ------------------------- 代理 websockets
pathRewrite: { //------------------- 重写
'^/api': '/'
}
}
}
}
}

3.1 配置难点解析:

  • lintOnSave:是否在开发环境下每次保存代码时都启用 eslint验证
false: 关闭每次保存都进行检测
true:开启每次保存都进行检测,效果与warning一样
warning: 开启每次保存都进行检测,lint 错误将显示到控制台命令行,而且编译并不会失败。
error: 开启每次保存都进行检测,lint 错误将显示到浏览器页面上,且编译失败。
default: 同’error’
  • productionSourceMap:设置生产环境的 source map 开启与关闭

用法:

module.exports = {
publicPath: './', // 基本路径
outputDir: 'dist', // 输出文件目录
assetsDir: './assets',
indexPath: 'index.html',
filenameHashing: true, // 生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存
lintOnSave: false, // eslint-loader 是否在保存的时候检查
productionSourceMap: true, // 生产环境是否生成 sourceMap 文件
}

什么是 source map?

source map 直译过来就是资源地图。所以,source map的作用就是定位。source map定位的时浏览器控制台输出语句在项目文件的位置。

例如:

vue-cli3访问不到public目录下的json数据

打包后:

没有开启 productionSourceMap的:

vue-cli3访问不到public目录下的json数据

打开的:

vue-cli3访问不到public目录下的json数据 可以看出,开启productionSourceMap后,浏览器控制台明确的告诉我们test这条结果的输出语句在main.js的20行。这就是source map的作用,对于开发人员差错时非常有用的。

下面看一下开启/关闭productionSourceMap 打包出来的项目文件对比:

打开的:

vue-cli3访问不到public目录下的json数据

关闭的:

vue-cli3访问不到public目录下的json数据

可以看出,开启productionSourceMap后,打包生成的 js 文件都有一个 .map 文件。这里要注意,只有 js 才有 .map 文件。

到此基本配置讲解结束。

3.2 开发环境和生产环境切换写法

module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 为生产环境修改配置...
} else {
// 为开发环境修改配置...
}
}
}

3.3 configureWebpack 与 chainWebpack的区别

博客园:vue项目中 configureWebpack 与 chainWebpack的区别及配置方式 - 小阿飞ZJF - 博客园

configureWebpackchainWebpack的作用相同,唯一的区别就是他们修改webpack配置方式不同:

  • chainWebpack通过链式编程的形式,来修改默认的webpack配置
  • configureWebpack通过操作对象的形式,来修改默认的webpack配置

(1)chainWebpack方式:

vue.config.js中configureWebpack与chainWebpack区别 - zcm花开不败 - 博客园

module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
// 修改他的选项
return options
})
}
}

(2)以下都是configureWebpack 配置方式:

configureWebpack 对象形式

module.exports = {
	configureWebpack:{
	 resolve: {
	 // 别名配置
	alias: {
	'assets': '@/assets',
	'common': '@/common',
	'components': '@/components',
	'network': '@/network',
	'configs': '@/configs',
	'views': '@/views',
	'plugins': '@/plugins',
	 }
	}
	}
}

configureWebpack 函数形式

module.exports = {
	configureWebpack:(config) => {
	if (process.env.NODE_ENV === 'production') {
	// 为生产环境修改配置...
	config.mode = 'production'
	} else {
	// 为开发环境修改配置...
	config.mode = 'development'
	}
	// 开发生产共同配置别名
	Object.assign(config.resolve, {
	alias: {
	'@': path.resolve(__dirname, './src'),
	'assets': path.resolve(__dirname, './src/assets'),
	'common': path.resolve(__dirname, './src/common'),
	'components': path.resolve(__dirname, './src/components'),
	'network': path.resolve(__dirname, './src/network'),
	'configs': path.resolve(__dirname, './src/configs'),
	'views': path.resolve(__dirname, './src/views'),
	'plugins': path.resolve(__dirname, './src/plugins'),
	}
	})
	}
}