我正在使用Vue 2构建一个多页面应用程序,使用Webpack和CommonsChunkPlugin来分离共享功能。在common.js
包中我有Vue,一些Vue组件,一个字体加载器和一个对象,它具有初始化我导出的Vue实例的功能,以防特定页面需要扩展该实例。具有额外交互性的页面使用导入的函数来初始化Vue并将mixin作为参数传递。
为了防止new Vue
和另一个入口点同时调用common.js
,我在window.m
中将全局变量0
设置为global.js
,在其他入口点增加它,global.js
只有new Vue
才会运行0
。
这感觉非常糟糕,我想知道如何更好地设置我的项目结构。
webpack.babel.js
const webpack = require('webpack')
const path = require('path')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
entry: {
common: './src/js/global.js',
home: './src/js/home.js',
imp_single: './src/js/imp_single.js',
parent_single: './src/js/parent_single.js',
faq: './src/js/faq.js'
},
output: {
path: __dirname + '/dist/js',
filename: '[name].bundle.js'
},
devtool: 'sourcemap',
module: {
rules: [
{ // eslint
enforce: 'pre',
test: /\.(vue|js)$/,
loader: 'eslint-loader',
exclude: /node_modules/,
options: {
formatter: require('eslint-friendly-formatter')
}
},
{
loader: 'babel-loader',
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/,
test: /\.(vue|js)$/,
query: {
presets: ['es2015', 'stage-2']
}
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
js: 'babel-loader'
}
}
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
filename: 'common.js',
minChunks: 0
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
})
],
resolve: {
extensions: ['.js', '.vue', '.json'],
modules: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules')
],
alias: {
vue: 'vue/dist/vue.common.js',
src: path.resolve(__dirname, '/src'),
components: path.resolve(__dirname, '/src/components')
}
}
}

global.js
import WebFont from 'webfontloader'
import Vue from 'vue'
// Vue Components
import accordion from './components/accordion'
import dropdown from './components/dropdown'
import progressbar from './components/progressbar'
import quiz from './components/quiz'
import timeline from './components/timeline'
// Setting a global variable to check for other mixins. If there's additional functionality, let the other bundle initialize Vue
window.m = 0
// Disable typography immediately to avoid FOUT
document.getElementsByTagName('html')[0].classList.value = 'wf-loading'
// Load our fonts
WebFont.load({
typekit: {
id: 'xxxxxxx',
families: ['Calluna', 'Open Sans', 'Bookmania', 'Freight Text Pro']
},
classes: false,
active () {
document.getElementsByTagName('html')[0].classList.value = 'wf-active'
setTimeout(function () {
document.getElementsByTagName('html')[0].classList.value = ''
}, 500)
}
})
const global = {
init (mixin = []) {
new Vue({ // eslint-disable-line no-new
el: '#sos',
components: {
accordion: accordion,
dropdown: dropdown,
progressbar: progressbar,
quiz: quiz,
timeline: timeline
},
data () {
return {
hrStatus: false
}
},
methods: {
helplines () {
this.hrStatus = !this.hrStatus
}
},
mixins: [mixin]
})
}
}
document.addEventListener('DOMContentLoaded', () => {
// Global Vue, extended by other pages
if (window.m === 0) {
global.init()
}
})
export default global

home.js:
import sos from './global'
// TODO Find a better way to do this
window.m++
document.addEventListener('DOMContentLoaded', () => {
sos.init({
data: {
forgotText: 'Forgot Password?',
forgot: false
},
methods: {
who () {
// Shows the parent/implementer buttons
this.forgot = !this.forgot
// Update text
if (this.forgotText === 'Forgot Password?') {
this.forgotText = 'Who are you?'
}
else {
this.forgotText = 'Forgot Password?'
}
},
parentFAQ () {
// Toggle the 'who are you' buttons
this.who()
// This relies on the forgot password FAQ being at the top. Might have to find a better way
if (this.$children[0].open === false) {
this.$children[0].toggle()
}
// Distance from top, then scroll to it
let top = this.$children[0].$el.offsetTop
window.scrollBy(0, top)
}
}
})
})