vue-cli单页应用改成多页应用配置详解


Posted in Javascript onJuly 14, 2017

前言

从接触vue开始用的是vue-cli直接搭建单页应用,参考配合着vue-router开发起来简直爽到吊炸天,但是由于项目越来越复杂了,单页用起来可能有点力不从心,能不能弄成多页面呢,查了相关资料得到的结论是完全可以的,能多页面多入口,并且可以使用组件,还引入jQuery,这简直完美了,这个demo是从我已经改造完成的项目中摘出来的,现在演示下怎么把基于vue2的vue-cli单页模板改造成多页面,并且多入口的项目。

技术栈

  1. vue: 2.0.1
  2. vue-resource:1.0.3
  3. vue-router:2.0.0
  4. webpack:1.13.2
  5. gulp:3.9.1
  6. ES6

运行

git clone https://github.com/dawnyu/vue-cli-multipage.git
npm install 
npm run build
npm run dev

改造后的目录

vue-cli单页应用改成多页应用配置详解

可以多目录生成目标文件

公共的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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
对象无length属性时IE6/IE7中无法将其转换成伪数组(ArrayLike)
Jul 31 Javascript
基于jQuery的动态增删改查表格信息,可左键/右键提示(原创自Zjmainstay)
Jul 31 Javascript
不使用浏览器运行javascript代码的方法
Jul 24 Javascript
LABjs、RequireJS、SeaJS的区别
Mar 04 Javascript
jqGrid读取选择的多行的某个属性代码
May 18 Javascript
javascript浏览器兼容教程之事件处理
Jun 09 Javascript
jquery仿百度百科底部浮动导航特效
Aug 08 Javascript
jQuery解决input超多的表单提交
Aug 10 Javascript
jQuery Ajax Post 回调函数不执行问题的解决方法
Aug 15 Javascript
javascript实现二叉树的代码
Jun 08 Javascript
vue数据更新UI不刷新显示的解决办法
Aug 06 Javascript
Node.js 中如何收集和解析命令行参数
Jan 08 Javascript
Vue filters过滤器的使用方法
Jul 14 #Javascript
vue.js如何更改默认端口号8080为指定端口的方法
Jul 14 #Javascript
Vue computed计算属性的使用方法
Jul 14 #Javascript
JS实现上传图片的三种方法并实现预览图片功能
Jul 14 #Javascript
JS实现数组去重方法总结(六种方法)
Jul 14 #Javascript
Javascript中Promise的四种常用方法总结
Jul 14 #Javascript
js学习心得_一个简单的动画库封装tween.js
Jul 14 #Javascript
You might like
支持oicq头像的留言簿(二)
2006/10/09 PHP
PHP 数组排序方法总结 推荐收藏
2010/06/30 PHP
解决nginx不支持thinkphp中pathinfo的问题
2015/07/21 PHP
图文介绍PHP添加Redis模块及连接
2015/07/28 PHP
thinkPHP5 ACL用户权限模块用法详解
2017/05/10 PHP
PHP addslashes()函数讲解
2019/02/03 PHP
Laravel框架控制器的middleware中间件用法分析
2019/09/30 PHP
jQuery修改class属性和CSS样式整理
2015/01/30 Javascript
js实现鼠标感应图片展示的方法
2015/02/27 Javascript
JS显示下拉列表框内全部元素的方法
2015/03/31 Javascript
jQuery实现鼠标经过提示信息的地图热点效果
2015/04/26 Javascript
JavaScript开发者必备的10个Sublime Text插件
2016/02/27 Javascript
jQuery实现图像旋转动画效果
2016/05/29 Javascript
8 行 Node.js 代码实现代理服务器
2016/12/05 Javascript
Vue-resource实现ajax请求和跨域请求示例
2017/02/23 Javascript
Node.js中使用mongoose操作mongodb数据库的方法
2017/09/12 Javascript
vue和webpack安装命令详解
2018/06/15 Javascript
vue-router中的hash和history两种模式的区别
2018/07/17 Javascript
JS前端知识点总结之内置对象,日期对象和定时器相关操作
2019/07/05 Javascript
Python struct模块解析
2014/06/12 Python
Python+django实现文件下载
2016/01/17 Python
详解Python网络爬虫功能的基本写法
2016/01/28 Python
pandas 取出表中一列数据所有的值并转换为array类型的方法
2018/04/11 Python
Python空间数据处理之GDAL读写遥感图像
2019/08/01 Python
Python 剪绳子的多种思路实现(动态规划和贪心)
2020/02/24 Python
Python装饰器用法与知识点小结
2020/03/09 Python
CSS3——齿轮转动关键代码
2013/05/02 HTML / CSS
内刊编辑求职自荐书范文
2014/02/19 职场文书
小学毕业典礼主持词
2014/03/27 职场文书
大学生简短的自我评价
2014/09/12 职场文书
员工自我工作评价
2015/03/06 职场文书
高质量“欢迎词”
2019/04/03 职场文书
分析MySQL抛出异常的几种常见解决方式
2021/05/18 MySQL
如何判断pytorch是否支持GPU加速
2021/06/01 Python
SqlServer数据库远程连接案例教程
2021/07/15 SQL Server
MySQL配置主从服务器(一主多从)
2021/08/07 MySQL