项目上线
服务器地址 ip:192.168.31.31 域名yingkong.com
1.有服务器,
2.已经部署好了环境 和域名解析
3.通过工具把dist目录中的代码,上传到服务器目录中(website)
而服务器中的代码是可以被访问的
当用户访问域名,域名就会被映射到服务器目录中的website,来访问
vue.config.js
publicPath
默认值 “/“,
设置这个属性,会让所有的输出资源路径都会在前面加上publicPath的值
这个可以通过 npm run build后,在打包后的目录中查看,index.html中就可以看见引用资源的路径前面被加上publicPath的值
问:当本地开发没有问题后,想看线上的怎么办。
确定代码上传到服务器后,修改publicPath 指定线上的服务的地址
这样访问index.html,就是访问远程服务器中的index.html(相关资源也是从远程服务器中访问)
实现本地访问服务器资源
线上服务器就是,相当于对外网的一个本地服务。
浏览器中输入域名后,通过dns解析成ip后,由ip访问服务器
域名—增强用户体验
publicPath的值修改为远程服务器ip,来访问服务器中的代码
outputDir
default:’dist’,
修改后不会对项目有任何影响,只是将打包文件名(输出目录)改变
assetsDir
控制输出资源位置的
不支持绝对路径,不能创建文件夹
default:’’
一般不修改,用来设置资源文件目录
放置生成的静态资源(js、css、img、fonts)的(相对于outputDir)目录
注:生成的资源覆盖filename或chunkFilename时,assetsDir会被忽略
indexPath
default:’index.html’
可以是一个绝对路径
用来设置index.html 的路径
indexPath:”./html/index.html” ——》在dist目录下创建一个html文件,并将index.html放到html中,但这样后资源文件路径用的还是原来的,所以会引用不了静态文件
filenameHashing
default:”true”
项目打包时,只要文件有变化,就会在文件后面生成一个文件hashing后缀添加到文件名上
如:index.html文件内容改变了就会变成—》 index.ad83.html
浏览器输入url后需要执行的过程:
1.DNS解析—》域名解析生成唯一ip,服务器的ip相当于门牌号
.com —->顶级域名后缀 .cn —->次级域名(国内域名) .net
ip对应类一个服务器,通过ip发送请求
3.服务器收到请求后,响应请求,
4.浏览器加载首页(link,img ,src,script)
浏览器第一次打开页面会比较慢,这是因为打开时会将上面的过程全部执行一遍,执行完后将请求到的文件放入缓存。缓存(将上面的文件保存,当请求相同的页面时,如果有缓存就会直接使用缓存中的文件,以减少打开网页时间)。
每当打开一个已经保存了缓存的网页时,浏览器会通过请求到的文件名与缓存中的文件名做对比,如果不一样,就重新请求这个文件,其余文件还是使用缓存中的文件。而项目上线时,项目并不会自动将修改过的文件重新命名,但可以通过filenameHashing给每一个修改过的文件后添加一个hashing,来改变文件名。避免项目更新上线后,用户访问网页时,因为网页请求的文件名与缓存中的文件名一样,而导致网页还是使用上一次的就页面样式(需要用户自己清楚缓存才能显示新页面效果——但让用户自己清理是不合理的,所以通过filenameHashing防止出现这样的情况)。
pages
用来做多页面的,一个页面就要有一个页面你入口
(多页面特点,每个一面的结构都一样,功能也不一样)
- Type: Object
- Default: undefined在
multi-page 模式下构建应用。每个“page”应该有一个对应的 JavaScript 入口文件。其值应该是一个对象,对象的 key 是入口的名字,value 是:
- 一个指定了 entry, template, filename, title 和 chunks 的对象 (除了 entry 之外都是可选的);
或一个指定其 entry 的字符串
module.exports = {
pages: {
index: {
// page 的入口
entry: 'src/index/main.js',
// 模板来源(打包后的index.html的模板)
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'
}
}
我们不难发现, pages 对象中的 key 就是入口的别名,而其 value 对象其实是入口 entry 和模板属性的合并,这样我们下面介绍的获取多入口和多模板的方法就可以合并成一个函数来进行多页的处理,合并后的 setPages 方法如下
// pages 多入口配置
exports.setPages = configs => {
let entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
let map = {}
entryFiles.forEach(filePath => {
let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
let tmp = filePath.substring(0, filePath.lastIndexOf('\/'))
let conf = {
// page 的入口
entry: filePath,
// 模板来源
template: tmp + '.html',
// 在 dist/index.html 的输出
filename: filename + '.html',
// 页面模板需要加对应的js脚本,如果不加这行则每个页面都会引入所有的js脚本
chunks: ['manifest', 'vendor', filename],
inject: true,
};
if (configs) {
conf = merge(conf, configs)
}
if (process.env.NODE_ENV === 'production') {
conf = merge(conf, {
minify: {
removeComments: true, // 删除 html 中的注释代码
collapseWhitespace: true, // 删除 html 中的空白符
// removeAttributeQuotes: true // 删除 html 元素中属性的引号
},
chunksSortMode: 'manual'// 按 manual 的顺序引入
})
}
map[filename] = conf
})
return map
}
上述代码我们 return 出的 map 对象就是 pages 所需要的配置项结构,我们只需在 vue.config.js 中引用即可 ```javascript / vue.config.js /
const utils = require(‘./build/utils’)
module.exports = { …
pages: utils.setPages(),
… }
这样我们多页应用基于 pages 配置的改进就大功告成了,当你运行打包命令来查看输出结果的时候,你会发现和之前的方式相比并没有什么变化,这就说明这两种方式都适用于多页的构建,但是这里还是推荐大家使用更便捷的 pages 配置
<a name="McB25"></a>
### **多入口**
在单页应用中,我们的入口文件只有一个, CLI 默认配置的是 main.js ,但是到了多页应用,我们的入口文件便包含了 page1.js 、 page2.js 、 index.js 等,数量取决于 pages 文件夹下目录的个数,这时候为了项目的可拓展性,我们需要自动计算入口文件的数量并解析路径配置到 webpack 中的 entry 属性上,如:
```javascript
module.exports = {
...
entry: {
page1: '/xxx/pages/page1/page1.js',
page2: '/xxx/pages/page2/page2.js',
index: '/xxx/pages/index/index.js',
},
...
}
那么我们如何读取并解析这样的路径呢,这里就需要使用工具和函数来解决了。我们可以在根目录新建 build 文件夹存放 utils.js 这样共用的 webpack 功能性文件,并加入多入口读取解析方法
/* utils.js */
const path = require('path');
// glob 是 webpack 安装时依赖的一个第三方模块,该模块允许你使用 * 等符号,
// 例如 lib/*.js 就是获取 lib 文件夹下的所有 js 后缀名的文件
const glob = require('glob');
// 取得相应的页面路径,因为之前的配置,所以是 src 文件夹下的 pages 文件夹
const PAGE_PATH = path.resolve(__dirname, '../src/pages');
/*
* 多入口配置
* 通过 glob 模块读取 pages 文件夹下的所有对应文件夹下的 js * 后缀文件,如果该文件存在
* 那么就作为入口处理
*/
exports.getEntries = () => {
let entryFiles = glob.sync(PAGE_PATH + '/*/*.js') // 同步读取所有入口文件
let map = {}
// 遍历所有入口文件
entryFiles.forEach(filePath => {
// 获取文件名
let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
// 以键值对的形式存储
map[filename] = filePath
})
return map
}
多模板
相对于多入口来说,多模板的配置也是大同小异,这里所说的模板便是每个 page 下的 html 模板文件,而模板文件的作用主要用于 webpack 中 html-webpack-plugin 插件的配置,其会根据模板文件生产一个编译后的 html 文件并自动加入携带 hash 的脚本和样式,基本配置如下
/* webpack 配置文件 */
const HtmlWebpackPlugin = require('html-webpack-plugin') // 安装并引用插件
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
title: 'My Page', // 生成 html 中的 title
filename: 'demo.html', // 生成 html 的文件名
template: 'xxx/xxx/demo.html', // 模板路径
chunks: ['manifest', 'vendor', 'demo'], // 所要包含的模块
inject: true, // 是否注入资源
})
]
...
}
以上是单模板的配置,那么如果是多模板只要继续往 plugins 数组中添加 HtmlWebpackPlugin 即可,但是为了和多入口一样能够灵活的获取 pages 目录下所有模板文件并进行配置,我们可以在 utils.js 中添加多模板的读取解析方法
/* utils.js */
// 多页面输出配置
// 与上面的多页面入口配置相同,读取 page 文件夹下的对应的 html 后缀文件,然后放入数组中
exports.htmlPlugin = configs => {
let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
let arr = []
entryHtml.forEach(filePath => {
let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
let conf = {
template: filePath, // 模板路径
filename: filename + '.html', // 生成 html 的文件名
chunks: ['manifest', 'vendor', filename],
inject: true,
}
// 如果有自定义配置可以进行 merge
if (configs) {
conf = merge(conf, configs)
}
// 针对生产环境配置
if (process.env.NODE_ENV === 'production') {
conf = merge(conf, {
minify: {
removeComments: true, // 删除 html 中的注释代码
collapseWhitespace: true, // 删除 html 中的空白符
// removeAttributeQuotes: true // 删除 html 元素中属性的引号
},
chunksSortMode: 'manual' // 按 manual 的顺序引入
})
}
arr.push(new HtmlWebpackPlugin(conf))
})
return arr
}
- 以上我们仍然是使用 glob 读取所有模板文件,然后将其遍历并设置每个模板的 config ,同时针对一些自定义配置和生产环境的配置进行了 merge 处理,其中自定义配置的功能我会在下节进行介绍,这里介绍一下生产环境下 minify 配置的作用:将 html-minifier 的选项作为对象来缩小输出。
- html-minifier 是一款用于缩小 html 文件大小的工具,其有很多配置项功能,包括上述所列举的常用的删除注释、空白、引号等。
- 当我们编写完了多模板的方法后,我们同样可以在 vue.config.js 中进行配置,与多入口不同的是我们在 configureWebpack 中不能直接替换 plugins 的值,因为它还包含了其他插件 ```javascript / vue.config.js /
const utils = require(‘./build/utils’)
module.exports = { …
configureWebpack: config => { config.entry = utils.getEntries() // 直接覆盖 entry 配置
// 使用 return 一个对象会通过 webpack-merge 进行合并,plugins 不会置空 return { plugins: […utils.htmlPlugin()] } },
… }
如此我们多页应用的多入口和多模板的配置就完成了,这时候我们运行命令 yarn build 后你会发现 dist 目录下生成了 3 个 html 文件,分别是 index.html 、 page1.html 和 page2.html
<a name="M6nlO"></a>
## lintOnSave
快速定位到错误--基本不改
- Type: boolean | 'warning' | 'default' | 'error'
- Default: 'default'
是否在开发环境下通过 [eslint-loader](https://github.com/webpack-contrib/eslint-loader) 在每次保存时 lint 代码。这个值会在 [@vue/cli-plugin-eslint](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint) 被安装之后生效。(校验代码--有错报错,有警告报警告)<br />设置为 true 或 'warning' 时,eslint-loader 会将 lint 错误输出为编译警告。默认情况下,警告仅仅会被输出到命令行,且不会使得编译失败。<br />如果你希望让 lint 错误在开发时直接显示在浏览器中,你可以使用 lintOnSave: 'default'。这会强制 eslint-loader 将 lint 错误输出为编译错误,同时也意味着 lint 错误将会导致编译失败。<br />设置为 error 将会使得 eslint-loader 把 lint 警告也输出为编译错误,这意味着 lint 警告将会导致编译失败。<br />或者,你也可以通过设置让浏览器 overlay 同时显示警告和错误:
```javascript
// vue.config.js
module.exports = {
devServer: {
overlay: {
warnings: true,
errors: true
}
}
}
当 lintOnSave 是一个 truthy 的值时,eslint-loader 在开发和生产构建下都会被启用。如果你想要在生产构建时禁用 eslint-loader,你可以用如下配置:
// vue.config.js
module.exports = {
//判断是生产模式还是开发模式(env.NODE_ENV -- 》环境变量)
lintOnSave: process.env.NODE_ENV !== 'production'
}
runtimeCompiler
- Type: boolean
- Default: false
是否使用包含运行时编译器的 Vue 构建版本。设置为 true 后你就可以在 Vue 组件中使用 template 选项了,但是这会让你的应用额外增加 10kb 左右。
runtimeCompiler 为true时,可以在这样使用template
export default{
template:..
}
transpileDependencies
- Type: boolean | Array
- Default: false —>只编译src下面的代码—-true时全部编译
默认情况下 babel-loader 会忽略所有 node_modules 中的文件。你可以启用本选项,以避免构建后的代码中出现未转译的第三方依赖。不过,对所有的依赖都进行转译可能会降低构建速度。如果对构建性能有所顾虑,你可以只转译部分特定的依赖:给本选项传一个数组,列出需要转译的第三方包包名或正则表达式即可。
productionSourceMap
想要看见source map报的错误,要将lintOnSave关闭
打包后的代码和源代码的关系映射
- Type: boolean
- Default: true
如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建
crossorigin
影响html的编译输出
一般用不到
作用:打包生成的html里面的资源引入标签上加上一个crossrigin=”anonymous”,用来解决跨域(引入第三方的资源时)
interity
configureWebpack
chainWebpack
css.modules
启动css的模块化,避免样式覆盖的影响
从 v4 起已弃用,请使用css.requireModuleExtension。 在 v3 中,这个选项含义与 css.requireModuleExtension 相反。
你可以通过