准备工作

在本地用vue-cli新建一个项目,首先安装vue-cil,命令:

  1. npm install -g vue-cli

新建一个vue项目,创建一个基于"webpack"的项目,项目名为vuedemo:

  1. vue init webpack vuedemo

这里有一个地方需要改一下,在执行npm install命令之前,在package.json里添加一个依赖,后面会用到。

修改webpack配置

项目目录

  1. ├── README.md
  2. ├── build
  3. ├── build.js
  4. ├── check-versions.js
  5. ├── dev-client.js
  6. ├── dev-server.js
  7. ├── utils.js
  8. ├── vue-loader.conf.js
  9. ├── webpack.base.conf.js
  10. ├── webpack.dev.conf.js
  11. └── webpack.prod.conf.js
  12. ├── config
  13. ├── dev.env.js
  14. ├── index.js
  15. └── prod.env.js
  16. ├── package.json
  17. ├── src
  18. ├── assets
  19. └── logo.png
  20. ├── components
  21. ├── Hello.vue
  22. └── cell.vue
  23. └── pages
  24. ├── cell
  25. ├── cell.html
  26. ├── cell.js
  27. └── cell.vue
  28. └── index
  29. ├── index.html
  30. ├── index.js
  31. ├── index.vue
  32. └── router
  33. └── index.js
  34. └── static

在这一步里我们需要改动的文件都在build文件下,分别是:

  • utils.js
  • webpack.base.conf.js
  • webpack.dev.conf.js
  • webpack.prod.conf.js

utils.js文件

  1. // utils.js文件
  2.  
  3. var path = require('path')
  4. var config = require('../config')
  5. var ExtractTextPlugin = require('extract-text-webpack-plugin')
  6.  
  7. exports.assetsPath = function (_path) {
  8. var assetsSubDirectory = process.env.NODE_ENV === 'production' ?
  9. config.build.assetsSubDirectory :
  10. config.dev.assetsSubDirectory
  11. return path.posix.join(assetsSubDirectory, _path)
  12. }
  13.  
  14. exports.cssLoaders = function (options) {
  15. options = options || {}
  16.  
  17. var cssLoader = {
  18. loader: 'css-loader',
  19. options: {
  20. minimize: process.env.NODE_ENV === 'production',
  21. sourceMap: options.sourceMap
  22. }
  23. }
  24.  
  25. // generate loader string to be used with extract text plugin
  26. function generateLoaders(loader, loaderOptions) {
  27. var loaders = [cssLoader]
  28. if (loader) {
  29. loaders.push({
  30. loader: loader + '-loader',
  31. options: Object.assign({}, loaderOptions, {
  32. sourceMap: options.sourceMap
  33. })
  34. })
  35. }
  36.  
  37. // Extract CSS when that option is specified
  38. // (which is the case during production build)
  39. if (options.extract) {
  40. return ExtractTextPlugin.extract({
  41. use: loaders,
  42. fallback: 'vue-style-loader'
  43. })
  44. } else {
  45. return ['vue-style-loader'].concat(loaders)
  46. }
  47. }
  48.  
  49. // https://vue-loader.vuejs.org/en/configurations/extract-css.html
  50. return {
  51. css: generateLoaders(),
  52. postcss: generateLoaders(),
  53. less: generateLoaders('less'),
  54. sass: generateLoaders('sass', { indentedSyntax: true }),
  55. scss: generateLoaders('sass'),
  56. stylus: generateLoaders('stylus'),
  57. styl: generateLoaders('stylus')
  58. }
  59. }
  60.  
  61. // Generate loaders for standalone style files (outside of .vue)
  62. exports.styleLoaders = function (options) {
  63. var output = []
  64. var loaders = exports.cssLoaders(options)
  65. for (var extension in loaders) {
  66. var loader = loaders[extension]
  67. output.push({
  68. test: new RegExp('\\.' + extension + '$'),
  69. use: loader
  70. })
  71. }
  72. return output
  73. }
  74.  
  75. /* 这里是添加的部分 ---------------------------- 开始 */
  76.  
  77. // glob是webpack安装时依赖的一个第三方模块,还模块允许你使用 *等符号, 例如lib/*.js就是获取lib文件夹下的所有js后缀名的文件
  78. var glob = require('glob')
  79. // 页面模板
  80. var HtmlWebpackPlugin = require('html-webpack-plugin')
  81. // 取得相应的页面路径,因为之前的配置,所以是src文件夹下的pages文件夹
  82. var PAGE_PATH = path.resolve(__dirname, '../src/pages')
  83. // 用于做相应的merge处理
  84. var merge = require('webpack-merge')
  85.  
  86. //多入口配置
  87. // 通过glob模块读取pages文件夹下的所有对应文件夹下的js后缀文件,如果该文件存在
  88. // 那么就作为入口处理
  89. exports.entries = function () {
  90. var entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
  91. var map = {}
  92. entryFiles.forEach((filePath) => {
  93. var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
  94. map[filename] = filePath
  95. })
  96. return map
  97. }
  98.  
  99. //多页面输出配置
  100. // 与上面的多页面入口配置相同,读取pages文件夹下的对应的html后缀文件,然后放入数组中
  101. exports.htmlPlugin = function () {
  102. let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
  103. let arr = []
  104. entryHtml.forEach((filePath) => {
  105. let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
  106. let conf = {
  107. // 模板来源
  108. template: filePath,
  109. // 文件名称
  110. filename: filename + '.html',
  111. // 页面模板需要加对应的js脚本,如果不加这行则每个页面都会引入所有的js脚本
  112. chunks: ['manifest', 'vendor', filename],
  113. inject: true
  114. }
  115. if (process.env.NODE_ENV === 'production') {
  116. conf = merge(conf, {
  117. minify: {
  118. removeComments: true,
  119. collapseWhitespace: true,
  120. removeAttributeQuotes: true
  121. },
  122. chunksSortMode: 'dependency'
  123. })
  124. }
  125. arr.push(new HtmlWebpackPlugin(conf))
  126. })
  127. return arr
  128. }
  129. /* 这里是添加的部分 ---------------------------- 结束 */

webpack.base.conf.js 文件

  1. // webpack.base.conf.js 文件
  2.  
  3. var path = require('path')
  4. var utils = require('./utils')
  5. var config = require('../config')
  6. var vueLoaderConfig = require('./vue-loader.conf')
  7.  
  8. function resolve(dir) {
  9. return path.join(__dirname, '..', dir)
  10. }
  11.  
  12. module.exports = {
  13. /* 修改部分 ---------------- 开始 */
  14. entry: utils.entries(),
  15. /* 修改部分 ---------------- 结束 */
  16. output: {
  17. path: config.build.assetsRoot,
  18. filename: '[name].js',
  19. publicPath: process.env.NODE_ENV === 'production' ?
  20. config.build.assetsPublicPath :
  21. config.dev.assetsPublicPath
  22. },
  23. resolve: {
  24. extensions: ['.js', '.vue', '.json'],
  25. alias: {
  26. 'vue$': 'vue/dist/vue.esm.js',
  27. '@': resolve('src'),
  28. 'pages': resolve('src/pages'),
  29. 'components': resolve('src/components')
  30. }
  31. },
  32. module: {
  33. rules: [{
  34. test: /\.vue$/,
  35. loader: 'vue-loader',
  36. options: vueLoaderConfig
  37. },
  38. {
  39. test: /\.js$/,
  40. loader: 'babel-loader',
  41. include: [resolve('src'), resolve('test')]
  42. },
  43. {
  44. test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  45. loader: 'url-loader',
  46. options: {
  47. limit: 10000,
  48. name: utils.assetsPath('img/[name].[hash:7].[ext]')
  49. }
  50. },
  51. {
  52. test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  53. loader: 'url-loader',
  54. options: {
  55. limit: 10000,
  56. name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
  57. }
  58. }
  59. ]
  60. }
  61. }

webpack.dev.conf.js 文件

  1. var utils = require('./utils')
  2. var webpack = require('webpack')
  3. var config = require('../config')
  4. var merge = require('webpack-merge')
  5. var baseWebpackConfig = require('./webpack.base.conf')
  6. var HtmlWebpackPlugin = require('html-webpack-plugin')
  7. var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
  8.  
  9. // add hot-reload related code to entry chunks
  10. Object.keys(baseWebpackConfig.entry).forEach(function (name) {
  11. baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
  12. })
  13.  
  14. module.exports = merge(baseWebpackConfig, {
  15. module: {
  16. rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
  17. },
  18. // cheap-module-eval-source-map is faster for development
  19. devtool: '#cheap-module-eval-source-map',
  20. plugins: [
  21. new webpack.DefinePlugin({
  22. 'process.env': config.dev.env
  23. }),
  24. // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
  25. new webpack.HotModuleReplacementPlugin(),
  26. new webpack.NoEmitOnErrorsPlugin(),
  27. // https://github.com/ampedandwired/html-webpack-plugin
  28. /* 注释这个区域的文件 ------------- 开始 */
  29. // new HtmlWebpackPlugin({
  30. // filename: 'index.html',
  31. // template: 'index.html',
  32. // inject: true
  33. // }),
  34. /* 注释这个区域的文件 ------------- 结束 */
  35. new FriendlyErrorsPlugin()
  36.  
  37. /* 添加 .concat(utils.htmlPlugin()) ------------------ */
  38. ].concat(utils.htmlPlugin())
  39. })

webpack.prod.conf.js 文件

  1. var path = require('path')
  2. var utils = require('./utils')
  3. var webpack = require('webpack')
  4. var config = require('../config')
  5. var merge = require('webpack-merge')
  6. var baseWebpackConfig = require('./webpack.base.conf')
  7. var CopyWebpackPlugin = require('copy-webpack-plugin')
  8. var HtmlWebpackPlugin = require('html-webpack-plugin')
  9. var ExtractTextPlugin = require('extract-text-webpack-plugin')
  10. var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
  11.  
  12. var env = config.build.env
  13.  
  14. var webpackConfig = merge(baseWebpackConfig, {
  15. module: {
  16. rules: utils.styleLoaders({
  17. sourceMap: config.build.productionSourceMap,
  18. extract: true
  19. })
  20. },
  21. devtool: config.build.productionSourceMap ? '#source-map' : false,
  22. output: {
  23. path: config.build.assetsRoot,
  24. filename: utils.assetsPath('js/[name].[chunkhash].js'),
  25. chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  26. },
  27. plugins: [
  28. // http://vuejs.github.io/vue-loader/en/workflow/production.html
  29. new webpack.DefinePlugin({
  30. 'process.env': env
  31. }),
  32. new webpack.optimize.UglifyJsPlugin({
  33. compress: {
  34. warnings: false
  35. },
  36. sourceMap: true
  37. }),
  38. // extract css into its own file
  39. new ExtractTextPlugin({
  40. filename: utils.assetsPath('css/[name].[contenthash].css')
  41. }),
  42. // Compress extracted CSS. We are using this plugin so that possible
  43. // duplicated CSS from different components can be deduped.
  44. new OptimizeCSSPlugin({
  45. cssProcessorOptions: {
  46. safe: true
  47. }
  48. }),
  49. // generate dist index.html with correct asset hash for caching.
  50. // you can customize output by editing /index.html
  51. // see https://github.com/ampedandwired/html-webpack-plugin
  52.  
  53. /* 注释这个区域的内容 ---------------------- 开始 */
  54. // new HtmlWebpackPlugin({
  55. // filename: config.build.index,
  56. // template: 'index.html',
  57. // inject: true,
  58. // minify: {
  59. // removeComments: true,
  60. // collapseWhitespace: true,
  61. // removeAttributeQuotes: true
  62. // // more options:
  63. // // https://github.com/kangax/html-minifier#options-quick-reference
  64. // },
  65. // // necessary to consistently work with multiple chunks via CommonsChunkPlugin
  66. // chunksSortMode: 'dependency'
  67. // }),
  68. /* 注释这个区域的内容 ---------------------- 结束 */
  69.  
  70. // split vendor js into its own file
  71. new webpack.optimize.CommonsChunkPlugin({
  72. name: 'vendor',
  73. minChunks: function (module, count) {
  74. // any required modules inside node_modules are extracted to vendor
  75. return (
  76. module.resource &&
  77. /\.js$/.test(module.resource) &&
  78. module.resource.indexOf(
  79. path.join(__dirname, '../node_modules')
  80. ) === 0
  81. )
  82. }
  83. }),
  84. // extract webpack runtime and module manifest to its own file in order to
  85. // prevent vendor hash from being updated whenever app bundle is updated
  86. new webpack.optimize.CommonsChunkPlugin({
  87. name: 'manifest',
  88. chunks: ['vendor']
  89. }),
  90. // copy custom static assets
  91. new CopyWebpackPlugin([{
  92. from: path.resolve(__dirname, '../static'),
  93. to: config.build.assetsSubDirectory,
  94. ignore: ['.*']
  95. }])
  96. /* 该位置添加 .concat(utils.htmlPlugin()) ------------------- */
  97. ].concat(utils.htmlPlugin())
  98. })
  99.  
  100. if (config.build.productionGzip) {
  101. var CompressionWebpackPlugin = require('compression-webpack-plugin')
  102.  
  103. webpackConfig.plugins.push(
  104. new CompressionWebpackPlugin({
  105. asset: '[path].gz[query]',
  106. algorithm: 'gzip',
  107. test: new RegExp(
  108. '\\.(' +
  109. config.build.productionGzipExtensions.join('|') +
  110. ')$'
  111. ),
  112. threshold: 10240,
  113. minRatio: 0.8
  114. })
  115. )
  116. }
  117.  
  118. if (config.build.bundleAnalyzerReport) {
  119. var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  120. webpackConfig.plugins.push(new BundleAnalyzerPlugin())
  121. }
  122.  
  123. module.exports = webpackConfig

至此,webpack的配置就结束了。

文件结构

  1. ├── src
  2. ├── assets
  3. └── logo.png
  4. ├── components
  5. ├── Hello.vue
  6. └── cell.vue
  7. └── pages
  8. ├── cell
  9. ├── cell.html
  10. ├── cell.js
  11. └── cell.vue
  12. └── index
  13. ├── index.html
  14. ├── index.js
  15. ├── index.vue
  16. └── router
  17. └── index.js

src就是我所使用的工程文件了,assets,components,pages分别是静态资源文件、组件文件、页面文件。

原先,入口文件只有一个main.js,但现在由于是多页面,因此入口页面多了,我目前就是两个:index和cell,之后如果打包,就会在dist文件下生成两个HTML文件:index.htmlcell.html(可以参考一下单页面应用时,打包只会生成一个index.html,区别在这里)。

页面跳转问题

既然是多页面,肯定涉及页面之间的互相跳转,就按照我这个项目举例,从index.html文件点击a标签跳转到cell.html。

一般都认为这样写:

  1. <!-- index.html -->
  2. <a href='../cell/cell.html'></a>

但这样写,不论是在开发环境还是最后测试,都会报404,找不到这个页面。

改成这样既可:

  1. <!-- index.html -->
  2. <a href='cell.html'></a>

如果想跳转到另外一个路由配置的某个模块,如账号中心,如下例子:

  1. <a class="home_account" href="login.html#/inner/acount/acountCenter">{{userInfo.phone}}</a>

参考地址

vue+vuecli+webapck2实现多页面应用的更多相关文章

  1. vue+vuecli+webapck2项目配置文件详解

    1.文件结构 ├─build │ ├─build.js │ ├─check-versions.js │ ├─dev-client.js │ ├─dev-server.js │ ├─utils.js │ ...

  2. 使用Vue和djangoframwork完成登录页面构建 001

    使用Vue和djangoframwork完成登录页面构建 001 环境的搭建 首先,我在我的电脑的F盘创建了一个文件夹 forNote,进入到这个文件夹中 F:\forNote> vue环境的搭 ...

  3. 基于VUE选择上传图片并在页面显示(图片可删除)

    demo例子: 依赖文件 : http://files.cnblogs.com/files/zhengweijie/jquery.form.rar HTML文本内容: <template> ...

  4. vue+vue-cli+淘宝lib-flexible做移动端自适应

    总结用vue+vue-cli+淘宝lib-flexible做移动端自适应方案: 1.安装淘宝lib-flexible npm install lib-flexible --save 2.在入口文价ma ...

  5. vue中如何缓存一些页面

    在vue中,有时候我们只想缓存页面中的一些组件或页面,这个时候怎么办呢,我们就需要用判断来加载keep-alive. 例如: // router.js { path: "/driving_l ...

  6. Vue数据产生变化需要页面渲染完之后执行某操作

    1.数据产生变化或者页面需要vue数据渲染完之后加载的东西 Vue.nextTick(function () { alert(123); }); 2 调用vue方法 --------------Vue ...

  7. 8种Vue中数据更新了但页面没有更新的情况

    目录 1.Vue 无法检测实例被创建时不存在于 data 中的 属性 2. Vue 无法检测'对象属性'的添加或移除 3.Vue 不能检测利用数组索引直接修改一个数组项 4.Vue 不能监测直接修改数 ...

  8. vue+vuecli+webpack中使用mockjs模拟后端数据

    前言 使用mockjs可以事先模拟数据,前提是和后端约定好了数据接口,怎样的数据.使用mock就可以生成你要的数据了,从而实现开发时前后端分离. 其主要功能是: 基于数据模板生成模拟数据. 基于HTM ...

  9. VUE (vue-cli)脚手架项目说明

    1. 概述 1.1 说明 使用vue-cli快速创建的vue项目目录如下: build  -- webpack相关配置以及服务启动文件,配置多依赖于下边的config文件夹中内容 config -- ...

随机推荐

  1. 【RL-TCPnet网络教程】第33章 SMTP简单邮件传输协议基础知识

    第33章      SMTP简单邮件传输协议基础知识 本章节为大家讲解SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)的基础知识,方便后面章节的实战操作. (本 ...

  2. LeetCode724. 寻找数组的中心索引

    1.题目描述 给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法. 我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和. 如果数组不存在中 ...

  3. 如何将项目上传到GitHub?

    如何将项目上传到GitHub? 1.注册GitHub账户 浏览器输入GitHub官网地址:https://github.com/ 进入后点击Sign In 然后点击Create an account ...

  4. Underscore.js 源码学习笔记(下)

    上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...

  5. 死磕 java集合之CopyOnWriteArrayList源码分析

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 CopyOnWriteArrayList是ArrayList的线程安全版本,内部也是通过 ...

  6. C#版 - Leetcode 215. Kth Largest Element in an Array-题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  7. Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)

    剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...

  8. Python和C++的混合编程(使用Boost编写Python的扩展包)

    想要享受更轻松愉悦的编程,脚本语言是首选.想要更敏捷高效,c++则高山仰止.所以我一直试图在各种通用或者专用的脚本语言中将c++的优势融入其中.原来贡献过一篇<c++和js的混合编程>也是 ...

  9. SpringBoot入门教程(二十)Swagger2-自动生成RESTful规范API文档

    Swagger2 方式,一定会让你有不一样的开发体验:功能丰富 :支持多种注解,自动生成接口文档界面,支持在界面测试API接口功能:及时更新 :开发过程中花一点写注释的时间,就可以及时的更新API文档 ...

  10. 初探Java设计模式3:行为型模式(策略,观察者等)

    行为型模式 行为型模式关注的是各个类之间的相互作用,将职责划分清楚,使得我们的代码更加地清晰. 策略模式 策略模式太常用了,所以把它放到最前面进行介绍.它比较简单,我就不废话,直接用代码说事吧. 下面 ...