vue-cli單頁應(yīng)用改成多頁應(yīng)用配置詳解
前言
從接觸vue開始用的是vue-cli直接搭建單頁應(yīng)用,參考配合著vue-router開發(fā)起來簡直爽到吊炸天,但是由于項目越來越復(fù)雜了,單頁用起來可能有點力不從心,能不能弄成多頁面呢,查了相關(guān)資料得到的結(jié)論是完全可以的,能多頁面多入口,并且可以使用組件,還引入jQuery,這簡直完美了,這個demo是從我已經(jīng)改造完成的項目中摘出來的,現(xiàn)在演示下怎么把基于vue2的vue-cli單頁模板改造成多頁面,并且多入口的項目。
技術(shù)棧
- vue: 2.0.1
- vue-resource:1.0.3
- vue-router:2.0.0
- webpack:1.13.2
- gulp:3.9.1
- ES6
運行
git clone https://github.com/dawnyu/vue-cli-multipage.git npm install npm run build npm run dev
改造后的目錄

可以多目錄生成目標文件
公共的js和樣式圖標放到assets文件夾即可
修改點
build/utils.js
var path = require('path')
var config = require('../config')
var glob = require('glob')
// 將樣式提取到單獨的css文件中,而不是打包到j(luò)s文件或使用style標簽插入在head標簽中
var ExtractTextPlugin = require('extract-text-webpack-plugin')
exports.assetsPath = function(_path) {
var assetsSubDirectory = process.env.NODE_ENV === 'production' ?
config.build.assetsSubDirectory :
config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function(options) {
options = options || {}
// generate loader string to be used with extract text plugin
function generateLoaders(loaders) {
var sourceLoader = loaders.map(function(loader) {
var extraParamChar
if (/\?/.test(loader)) {
loader = loader.replace(/\?/, '-loader?')
extraParamChar = '&'
} else {
loader = loader + '-loader'
extraParamChar = '?'
}
return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
}).join('!')
if (options.extract) {
return ExtractTextPlugin.extract('vue-style-loader', sourceLoader)
} else {
return ['vue-style-loader', sourceLoader].join('!')
}
}
// http://vuejs.github.io/vue-loader/configurations/extract-css.html
return {
css: generateLoaders(['css']),
postcss: generateLoaders(['css']),
less: generateLoaders(['css', 'less']),
sass: generateLoaders(['css', 'sass?indentedSyntax']),
scss: generateLoaders(['css', 'sass']),
stylus: generateLoaders(['css', 'stylus']),
styl: generateLoaders(['css', 'stylus'])
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function(options) {
var output = []
var loaders = exports.cssLoaders(options)
for (var extension in loaders) {
var loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
loader: loader
})
}
return output
}
//增加獲取多入口的方法 注意 這個參數(shù)是個數(shù)組
exports.getEntry = function(globPaths) {
var entries = {},
basename, tmp, pathname;
for (globPath of globPaths) {
glob.sync(globPath).forEach(function(entry) {
basename = path.basename(entry, path.extname(entry));
tmp = entry.split('/').splice(-3);
pathname = tmp.splice(0, 1) + '/' + basename; // 正確輸出js和html的路徑
entries[pathname] = entry;
});
}
console.log(entries);
return entries;
}
webpack.base.conf.js
var path = require('path')
var config = require('../config')
var webpack = require('webpack')
var merge = require('webpack-merge')
var utils = require('./utils')
var projectRoot = path.resolve(__dirname, '../') ///——driname當前目錄
var chunks = Object.keys(utils.getEntry(['./src/module/**/*.js', './src/m/**/*.js']));
// 將樣式提取到單獨的css文件中,而不是打包到j(luò)s文件或使用style標簽插入在head標簽中
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: utils.getEntry(['./src/module/**/*.js', './src/m/**/*.js']),//傳入需要打包的入口,我這里是pc端和手機端入口打到一個包里
output: {
path: config.build.assetsRoot,
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath, //根名稱可配置
filename: '[name].js'
},
resolve: {
extensions: ['', '.js', '.vue'],
fallback: [path.join(__dirname, '../node_modules')],
alias: {
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
'components': path.resolve(__dirname, '../src/components'),
'jquery': 'jquery'
}
},
resolveLoader: {
fallback: [path.join(__dirname, '../node_modules')]
},
module: {
loaders: [{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel',
include: projectRoot,
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url',
query: {
limit: 30000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
eslint: {
formatter: require('eslint-friendly-formatter')
},
vue: {
loaders: utils.cssLoaders(),
postcss: [
require('autoprefixer')({
browsers: ['last 2 versions']
})
]
},
plugins: [
// new webpack.optimize.CommonsChunkPlugin('static/build.js'),
// 提取公共模塊
new webpack.optimize.CommonsChunkPlugin({
name: 'vendors', // 公共模塊的名稱
chunks: chunks, // chunks是需要提取的模塊
minChunks: chunks.length
}),
// 配置提取出的樣式文件
new ExtractTextPlugin('css/[name].css'),
//引入jqury
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
],
}
webpack.dev.conf.js
var config = require('../config')
var webpack = require('webpack')
var merge = require('webpack-merge')
var utils = require('./utils')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function(name) {
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})
module.exports = merge(baseWebpackConfig, {
module: {
loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
},
// eval-source-map is faster for development
devtool: '#eval-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
// new HtmlWebpackPlugin({
// filename: 'index.html',
// template: 'index.html',
// inject: true
// })
]
})
var pages = utils.getEntry(['./src/module/**/*.html', './src/m/**/*.html']);
for (var pathname in pages) {
// 配置生成的html文件,定義路徑等
var conf = {
filename: pathname + '.html',
template: pages[pathname], // 模板路徑
favicon: './src/assets/images/wechat.png',
inject: true // js插入位置
};
if (pathname in module.exports.entry) {
conf.chunks = ['vendors', pathname];
conf.hash = true;
}
module.exports.plugins.push(new HtmlWebpackPlugin(conf));
}
webpack.prod.conf.js
var path = require('path')
var config = require('../config')
var utils = require('./utils')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var env = process.env.NODE_ENV === 'testing' ?
require('../config/test.env') :
config.build.env
module.exports = merge(baseWebpackConfig, {
module: {
loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
},
devtool: config.build.productionSourceMap ? '#source-map' : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
vue: {
loaders: utils.cssLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
},
plugins: [
// http://vuejs.github.io/vue-loader/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_debugger: true,
drop_console: true
}
}),
new webpack.optimize.OccurenceOrderPlugin(),
// extract css into its own file
new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
// new HtmlWebpackPlugin({
// filename: process.env.NODE_ENV === 'testing' ?
// 'index.html' : config.build.index,
// template: 'index.html',
// favicon: './src/assets/images/tjd.ico',
// 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'
// }),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function(module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
})
]
})
if (config.build.productionGzip) {
var CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
var pages = utils.getEntry(['./src/module/**/*.html', './src/m/**/*.html']);
for (var pathname in pages) {
// 配置生成的html文件,定義路徑等
var conf = {
filename: pathname + '.html',
template: pages[pathname], // 模板路徑
favicon: './src/assets/images/wechat.png',
inject: true // js插入位置
};
if (pathname in pages) {
conf.chunks = ['vendors', pathname];
conf.hash = true;
}
module.exports.plugins.push(new HtmlWebpackPlugin(conf));
}
git地址:https://github.com/dawnyu/vue-cli-multipage.git
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue3 elementUI如何修改el-date-picker默認時間
這篇文章主要介紹了Vue3 elementUI如何修改el-date-picker默認時間,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08
詳解@Vue/Cli 3 Invalid Host header 錯誤解決辦法
這篇文章主要介紹了詳解@Vue/Cli 3 Invalid Host header 錯誤解決辦法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01

