简介
单页面:所有js和vue文件打包成一个js文件。一个入口,所有的页面跳转通过路由(router-vue)来完成。
多页面:将每一个页面都打包成一个js文件。页面跳转通过页面或者界面将对应的js文件加载渲染生成页面。
所以单页面转多页面的核心是生成独立页面的js。主要通过修改配置文件webpack.config.js来完成。
配置文件
单页面配置文件如下:
var path = require('path')
var webpack = require('webpack')
var bannerPlugin = new webpack.BannerPlugin(
'// { "framework": "Vue" }\n',
{ raw: true }
)
function getBaseConfig () {
return {
entry: {
app: path.resolve('src', 'entry.js')
},
output: {
path: 'dist',
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}, {
test: /\.vue(\?[^?]+)?$/,
loaders: []
}
]
},
vue: {
},
plugins: [bannerPlugin]
}
}
var webConfig = getBaseConfig()
webConfig.output.filename = '[name].web.js'
webConfig.module.loaders[1].loaders.push('vue')
var weexConfig = getBaseConfig()
weexConfig.output.filename = '[name].weex.js'
weexConfig.module.loaders[1].loaders.push('weex')
module.exports = [webConfig, weexConfig]
entry: {
app: path.resolve('src', 'entry.js')
},
这里是页面入口,找到src/entry.js,由此开始编译。
weexConfig.output.filename = '[name].weex.js'
页面出口,生成文件命名为app.weex.js(native版本)或者app.web.js(web版本)。
编译过程大概是编译entry.js时将其文件所引用的文件或者模块打包在一起形成一个文件。这里有根Vue的定义。
多页面配置文件如下:
var path = require('path')
var webpack = require('webpack')
var fs = require('fs-extra');
function getEntryFileContent (entryPath, vueFilePath) {
let relativePath = path.relative(path.join(entryPath, '../'), vueFilePath);
relativePath=relativePath.replace(/\\/ig,'/')
return 'var App = require(\'' + relativePath + '\')\n'
+ 'App.el = \'#root\'\n'
+ 'new Vue(App)\n'
}
var entry = {
entry: path.resolve('./src/entry.js')
};
function walk(dir) {
dir = dir || '.'
let directory = path.join(__dirname, './src', dir);
let entryDirectory = path.join(__dirname, './src/entry');
fs.readdirSync(directory)
.forEach(function(file) {
var fullpath = path.join(directory, file);
var stat = fs.statSync(fullpath);
var extname = path.extname(fullpath);
if (stat.isFile() && (extname === '.we' || extname === '.vue')) {
let entryFile = path.join(entryDirectory, dir, path.basename(file, extname) + '.js')
fs.outputFileSync(entryFile, getEntryFileContent(entryFile, fullpath))
let name = path.join(dir, path.basename(file, extname))
entry[name] = entryFile + '?entry=true';
} else if (stat.isDirectory() && file !== 'build' && file !== 'include') {
var subdir = path.join(dir, file);
walk(subdir);
}
});
}
walk();
var bannerPlugin = new webpack.BannerPlugin(
'// { "framework": "Vue" }\n',
{ raw: true }
)
function getBaseConfig () {
return {
entry: entry,
output: {
path: 'dist',
},
resolve: {
extensions: ['', '.js', '.vue'],
fallback: [path.join(__dirname, './node_modules')],
alias: {
'api': path.resolve(__dirname, './src/api/'),
'views': path.resolve(__dirname, './src/views/'),
'utils': path.resolve(__dirname, './src/utils/')
}
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}, {
test: /\.vue(\?[^?]+)?$/,
loaders: []
}
]
},
vue: [
},
plugins: [bannerPlugin]
}
}
var webConfig = getBaseConfig()
webConfig.output.filename = 'web/[name].js'
webConfig.module.loaders[1].loaders.push('vue')
var weexConfig = getBaseConfig()
weexConfig.output.filename = 'weex/[name].js'
weexConfig.module.loaders[1].loaders.push('weex')
module.exports = [webConfig, weexConfig]
walk();
walk()方法作用,搜索所有vue文件,并生成对应文件名的js,比如src/index.vue会生成一个entry/index.js,文件内容如下:
var App = require('../App.vue')
App.el = '#root'
new Vue(App)
代码里有对源文件的引用和页面渲染位置Dom元素的id root的定义。
将新生成的文件路径填充进页面入口信息的对象entry。
weexConfig.output.filename = 'weex/[name].js'
输出页面文件会根据entry的信息生成对应目录和文件名,dist/weex(web)/index.js。
这些js就是每个vue对应的页面。
这样就完了吗?
修改weex.html
还记得单页是怎么加载js。
<body>
<div id="root"></div>
<script src="./dist/app.web.js"></script>
</body>
单页逻辑简单,只有一个js文件,只需加载一个文件即可;页面跳转考vue-router。
多页有无数页面,这样单个加载并不行,将script改为如下:
<script>
(function () {
function getUrlParam (key) {
var reg = new RegExp('[?|&]' + key + '=([^&]+)')
var match = location.search.match(reg)
return match && match[1]
}
var page = getUrlParam('page')
var defaultPage = './dist/web/index.js'
if (!page) {
var url = location.href.replace(/\?|$/, function(f) {
var query = '?page=' + defaultPage
return f ? query + '&' : query
})
return location.href = url
}
console.log('script');
var bundle = document.createElement('script')
bundle.src = page
document.body.appendChild(bundle)
})();
</script>
上面代码逻辑是默认进入首页
var defaultPage = './dist/web/index.js'
当通过页面跳转时若带有page的链接,会解析出page后面的路径,根据路径去加载对应js。如路径
http://localhost:8080:weex.html?page=./dist/web/views/Counter.js
他的路径是dist/web/views/Counter.js,正好与dist路径下的文件对照。所以会渲染新的js页面。
如何跳转呢?
weex里有内置模块navigator和event(不知道哪来的,可能是老版本的模块,weex最新文档看了一圈,没发现这个模块,但是能用)。可以通过这两个模块实现跳转。
具体的下次内容。