同步操作将从 三人行/appindex-pcindex 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
vue 多页面(pc, 移动)切换包括 js 对应打包,完美方案
软件架构说明
git clone 链接
npm install
npm run dev
在不改变 vue 路由的前提下,自动切换与设备匹配的页面 不同设备的页面引入的模块代码要进行分离,避免引入无关代码,影响效率
调整目录结构:为了完全分离不同设备的页面,在 src 下新建 pages 目录,其下再按设备建立页面目录,比如 pages/pc、 pages/mobile 等 调整 webpack 打包配置
1) 入口(build/webpack.base.conf.js 中的 entry)设置多入口,入口 js 为相应设备页面目录下的 main.js。
2) 超文本插件(build/webpack.dev.conf.js 和 build/webpack.prod.conf.js -> plugins ->HtmlWebpackPlugin)设置多个 HtmlWebpackPlugin,每个对应一个设备页面目录下的 index.html。
3) 第三方模块打包(build/webpack.prod.conf.js -> plugins -> CommonsChunkPlugin)(可选)如果需要对依赖的第三方模块进行分离,可以设置多个 CommonsChunkPlugin,每个对应一个设备页面的第三方模块。由于这个设置并不会影响实际加载的文件总大小,所以该设置为可选。
|- pages
| |- pc
| | |- assets
| | |- components
| | |- router
| | |- App.vue
| | |- index.html
| | |- main.js
| |-mobile
| | |- assets
| | |- components
| | |- router
| | |- App.vue
| | |- index.html
| | |- main.js
|- main.js
其实就是把原来 src 下的目录结构移到“src/pages/<设备类型>/”下面,并增加 index.html 入口页面模板,index.html 可以从工程目录下复制。删除原来 src 下面的目录,只留下 main.js 文件和新建的 pages 目录。
修改 src/main.js,清空原有所有内容,替换为以下代码:
const isPc = () => {
return !isMobile()
}
const isMobile = () => {
return /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i.test(navigator.userAgent)
}
const params = window.location.search + window.location.hash
if (isPc()) {
window.location.href = 'pc_index.html' + params
} else if (isMobile()) {
window.location.href = 'mobile_index.html' + params
}
这里面页面的名称要根据设备名称命名,与src/pages下面的目录名称一致。
在build/utils.js中增加以下代码:
var glob = require('glob')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var merge = require('webpack-merge')
//页面根目录
var PAGE_ROOT_PATH = path.resolve(__dirname, '../src/pages')
//取页面清单
function getPages() {
let entryHtmlFiles = glob.sync(PAGE_ROOT_PATH + '/*/index.html')
let pages = []
entryHtmlFiles.forEach((filePath) => {
let pagePath = filePath.substring(0, filePath.lastIndexOf('\/'))
let pageName = pagePath.substring(pagePath.lastIndexOf('\/') + 1)
pages.push(pageName)
})
return pages
}
//生成入口
exports.entries = function () {
var map = {}
getPages().forEach((pageName) => {
let filePath = PAGE_ROOT_PATH + '/' + pageName + '/main.js'
map['app_' + pageName] = filePath
})
return map
}
在build/webpack.base.conf.js中修改entry:
module.exports = {
...
entry: Object.assign({app: './src/main.js'}, utils.entries()),
...
}
在build/utils.js中增加以下代码:(在本文3.3.1基础上修改)
exports.htmlPlugins = function () {
let plugins = []
getPages().forEach((pageName) => {
let templateFilePath = PAGE_ROOT_PATH + '/' + pageName + '/index.html'
let outputFileName = pageName + '_index.html'
let conf = {
template: templateFilePath,
filename: outputFileName,
chunks: ['manifest', 'vendor', 'vendor_' + pageName, 'app_' + pageName],
inject: true
}
if (process.env.NODE_ENV === 'production') {
conf = merge(conf, {
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
})
}
plugins.push(new HtmlWebpackPlugin(conf))
})
return plugins
}
修改bin/webpack.dev.conf.js:
plugins: [
...
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
chunks: ['app'], //修改这里
inject: true
}),
...
].concat(utils.htmlPlugins()) //修改这里
修改bin/webpack.prod.conf.js:
plugins: [
...
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
chunks: ['app'], //修改这里
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
...
].concat(utils.htmlPlugins()) //修改这里
修改bin/webpack.prod.conf.js:
plugins: [
...
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor_pc',
chunks: ['app_pc'],
minChunks(module) {
console.log(module.resource)
return module.resource && /\.js$/.test(module.resource) && module.resource.indexOf(path.join(__dirname, '../node_modules')) == 0
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor_mobile',
chunks: ['app_mobile'],
minChunks(module) {
return module.resource && /\.js$/.test(module.resource) && module.resource.indexOf(path.join(__dirname, '../node_modules')) == 0
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
chunks: ['vendor_pc', 'vendor_mobile'],
minChunks: 2
}),
...
]
注意:三段创建CommonsChunkPlugin插件实例的代码顺序不能颠倒,要保证设备页面入口的vendor在公共vendor之前。chunk名称要与pages下面目录名称一致
原理解释:CommonsChunkPlugin根据创建时的选项,自动提取公共代码,生成独立的js文件(chunk)。 选项及作用如下:
name:可以是已经存在的chunk(一般指入口文件)对应的name,那么就会把公共模块代码合并到这个chunk上;否则,会创建名字为name的commons chunk进行合并。
filename:指定commons chunk的文件名。
chunks:指定source chunk,即指定从哪些chunk当中去找公共模块,省略该选项的时候,默认就是entry chunks。
minChunks:既可以是数字,也可以是函数,还可以是Infinity。
数字:模块被多少个chunk公共引用才被抽取出来成为commons chunk。
函数:接受 (module, count) 两个参数,返回一个布尔值,你可以在函数内进行你规定好的逻辑来决定某个模块是否提取成为commons chunk。
Infinity:只有当入口文件(entry chunks) >= 3 才生效,用来在第三方库中分离自定义的公共模块。
上面的设置,实际完成下面步骤: 1) 从app_pc这个入口里面提取第三方模块,生成vendor_pc。 2) 从app_mobile这个入口里面提取第三方模块,生成vendor_mobile。 3) 从vendor_pc和vendor_mobile中提取公共模块,生成vendor。
src下代码全部移到了src/pages/<设备名称>下面,所以如果使用了相对路径,则不会有问题。
但是如果使用了路径别名“@”(代表src),则会受到影响。建议把用到“@”的地方更换为相对路径。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。