vue-cli单页应用改成多页应用配置详解
发布时间 - 2026-01-11 02:20:58 点击率:次前言

从接触vue开始用的是vue-cli直接搭建单页应用,参考配合着vue-router开发起来简直爽到吊炸天,但是由于项目越来越复杂了,单页用起来可能有点力不从心,能不能弄成多页面呢,查了相关资料得到的结论是完全可以的,能多页面多入口,并且可以使用组件,还引入jQuery,这简直完美了,这个demo是从我已经改造完成的项目中摘出来的,现在演示下怎么把基于vue2的vue-cli单页模板改造成多页面,并且多入口的项目。
技术栈
- 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文件中,而不是打包到js文件或使用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
}
//增加获取多入口的方法 注意 这个参数是个数组
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文件中,而不是打包到js文件或使用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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# vue-cli单页改成多页应用
# vue-cli
# 多页应用
# vue 单页应用和多页应用的优劣
# webpack4.0+vue2.0利用批处理生成前端单页或多页应用的方法
# 详解vue-cli3多页应用改造
# Vue CLI3基础学习之pages构建多页应用
# 详解Vue CLI3 多页应用实践和源码设计
# 手把手教你vue-cli单页到多页应用的方法
# Vue单页及多页应用全局配置404页面实践记录
# 详解如何使用 vue-cli 开发多页应用
# vue 如何从单页应用改造成多页应用
# 的是
# 而不是
# 多页
# 是个
# 是从
# 可以使用
# 相关资料
# 打到
# 力不从心
# 包里
# 大家多多
# 能多
# 弄成
# 我已经
# 这简直
# configurations
# scss
# stylus
# indentedSyntax
# postcss
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
如何快速查询域名建站关键信息?
油猴 教程,油猴搜脚本为什么会网页无法显示?
Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
太平洋网站制作公司,网络用语太平洋是什么意思?
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
Laravel distinct去重查询_Laravel Eloquent去重方法
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】
千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】
独立制作一个网站多少钱,建立网站需要花多少钱?
如何在IIS7中新建站点?详细步骤解析
香港服务器租用费用高吗?如何避免常见误区?
Laravel如何实现用户密码重置功能?(完整流程代码)
长沙做网站要多少钱,长沙国安网络怎么样?
如何快速搭建自助建站会员专属系统?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件
Swift中循环语句中的转移语句 break 和 continue
大型企业网站制作流程,做网站需要注册公司吗?
如何在建站之星绑定自定义域名?
千库网官网入口推荐 千库网设计创意平台入口
Laravel如何使用模型观察者?(Observer代码示例)
公司网站制作需要多少钱,找人做公司网站需要多少钱?
,南京靠谱的征婚网站?
详解MySQL数据库的安装与密码配置
Android自定义控件实现温度旋转按钮效果
如何在宝塔面板中创建新站点?
宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法
Python正则表达式进阶教程_复杂匹配与分组替换解析
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道
如何利用DOS批处理实现定时关机操作详解
Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】
Laravel如何优化应用性能?(缓存和优化命令)
详解Android图表 MPAndroidChart折线图
高端企业智能建站程序:SEO优化与响应式模板定制开发
C++用Dijkstra(迪杰斯特拉)算法求最短路径
EditPlus中的正则表达式实战(6)
Laravel如何实现模型的全局作用域?(Global Scope示例)
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
简单实现Android文件上传
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
如何快速搭建二级域名独立网站?
Laravel Docker环境搭建教程_Laravel Sail使用指南
如何用免费手机建站系统零基础打造专业网站?
Laravel Octane如何提升性能_使用Laravel Octane加速你的应用

