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 相关文章推荐
学习ExtJS fit布局使用说明
Oct 08 Javascript
javascript与asp.net(c#)互相调用方法
Dec 13 Javascript
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之三
Jan 03 Javascript
禁用页面部分JavaScript方法的具体实现
Jul 31 Javascript
JavaScript访问CSS属性的几种方式介绍
Jul 21 Javascript
jQuery标签替换函数replaceWith()的使用例子
Aug 28 Javascript
7个让JavaScript变得更好的注意事项
Jan 28 Javascript
完美实现八种js焦点轮播图(下篇)
Apr 20 Javascript
基于JavaScript实现Tab选项卡切换效果
Nov 24 Javascript
javascript基本数据类型和转换
Mar 17 Javascript
简单实现vue中的依赖收集与响应的方法
Feb 18 Javascript
弱类型语言javascript开发中的一些坑实例小结【变量、函数、数组、对象、作用域等】
Aug 07 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
require(),include(),require_once()和include_once()区别
2008/03/27 PHP
深入php-fpm的两种进程管理模式详解
2013/06/03 PHP
解析smarty模板中类似for的功能实现
2013/06/18 PHP
yii实现CheckBox复选框在同一行显示的方法
2014/12/03 PHP
Yii2中datetime类的使用
2016/12/17 PHP
PHP查询分页的实现代码
2017/06/09 PHP
JavaScript Sort 表格排序
2009/10/31 Javascript
JavaScript 数组详解
2013/10/10 Javascript
js 使FORM表单的所有元素不可编辑的示例代码
2013/10/17 Javascript
jQuery异步验证用户名是否存在示例代码
2014/05/21 Javascript
jquery easyui datagrid实现增加,修改,删除方法总结
2016/05/25 Javascript
jQuery遍历json的方法(推荐)
2016/06/12 Javascript
jquery组件WebUploader文件上传用法详解
2020/10/23 Javascript
详解使用vue实现tab 切换操作
2017/07/03 Javascript
详解如何使用webpack+es6开发angular1.x
2017/08/16 Javascript
electron-vue利用webpack打包实现多页面的入口文件问题
2019/05/12 Javascript
关于vue3默认把所有onSomething当作v-on事件绑定的思考
2020/05/15 Javascript
原生js canvas实现鼠标跟随效果
2020/08/02 Javascript
python私有属性和方法实例分析
2015/01/15 Python
Python下载网络文本数据到本地内存的四种实现方法示例
2018/02/05 Python
python2和python3的输入和输出区别介绍
2018/11/20 Python
关于Python内存分配时的小秘密分享
2019/09/05 Python
基于Python新建用户并产生随机密码过程解析
2019/10/08 Python
如何将你的应用迁移到Python3的三个步骤
2019/12/22 Python
TensorFlow梯度求解tf.gradients实例
2020/02/04 Python
对tensorflow 中tile函数的使用详解
2020/02/07 Python
css3 仿写阿里云水纹效果的示例代码
2018/02/10 HTML / CSS
突袭HTML5之Javascript API扩展2—地理信息服务及地理位置API学习
2013/01/31 HTML / CSS
专门经营化妆刷的美国彩妆品牌:Sigma Beauty
2017/09/11 全球购物
美国瑜伽品牌:Gaiam
2017/10/31 全球购物
毕业生精彩的自我评价分享
2013/10/06 职场文书
普师专业个人自荐信范文
2013/11/26 职场文书
学习新党章思想汇报
2014/01/09 职场文书
竞争性谈判邀请书
2014/02/06 职场文书
新郎婚礼答谢词
2015/01/04 职场文书
同学聚会致辞集锦
2015/07/28 职场文书