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

可以多目錄生成目標(biāo)文件
公共的js和樣式圖標(biāo)放到assets文件夾即可
修改點(diǎn)
build/utils.js
var path = require('path')
var config = require('../config')
var glob = require('glob')
// 將樣式提取到單獨(dú)的css文件中,而不是打包到j(luò)s文件或使用style標(biāo)簽插入在head標(biāo)簽中
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
}
//增加獲取多入口的方法 注意 這個(gè)參數(shù)是個(gè)數(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當(dāng)前目錄
var chunks = Object.keys(utils.getEntry(['./src/module/**/*.js', './src/m/**/*.js']));
// 將樣式提取到單獨(dú)的css文件中,而不是打包到j(luò)s文件或使用style標(biāo)簽插入在head標(biāo)簽中
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: utils.getEntry(['./src/module/**/*.js', './src/m/**/*.js']),//傳入需要打包的入口,我這里是pc端和手機(jī)端入口打到一個(gè)包里
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
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- vue 單頁(yè)應(yīng)用和多頁(yè)應(yīng)用的優(yōu)劣
- webpack4.0+vue2.0利用批處理生成前端單頁(yè)或多頁(yè)應(yīng)用的方法
- 詳解vue-cli3多頁(yè)應(yīng)用改造
- Vue CLI3基礎(chǔ)學(xué)習(xí)之pages構(gòu)建多頁(yè)應(yīng)用
- 詳解Vue CLI3 多頁(yè)應(yīng)用實(shí)踐和源碼設(shè)計(jì)
- 手把手教你vue-cli單頁(yè)到多頁(yè)應(yīng)用的方法
- Vue單頁(yè)及多頁(yè)應(yīng)用全局配置404頁(yè)面實(shí)踐記錄
- 詳解如何使用 vue-cli 開(kāi)發(fā)多頁(yè)應(yīng)用
- vue 如何從單頁(yè)應(yīng)用改造成多頁(yè)應(yīng)用
相關(guān)文章
Vue3 elementUI如何修改el-date-picker默認(rèn)時(shí)間
這篇文章主要介紹了Vue3 elementUI如何修改el-date-picker默認(rèn)時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
詳解@Vue/Cli 3 Invalid Host header 錯(cuò)誤解決辦法
這篇文章主要介紹了詳解@Vue/Cli 3 Invalid Host header 錯(cuò)誤解決辦法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
Vue打包為相對(duì)路徑的具體實(shí)現(xiàn)方法
在Vue.js項(xiàng)目中,構(gòu)建后的資源文件(如CSS、JavaScript文件、圖片等)通常會(huì)被放置在指定的目錄下,為了確保這些文件能夠被正確加載,Vue CLI 提供了配置選項(xiàng)來(lái)指定這些文件的路徑,本文給大家介紹了Vue打包為相對(duì)路徑的具體實(shí)現(xiàn)方法,需要的朋友可以參考下2024-09-09

