经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
详解vue-cli3多页应用改造
来源:jb51  时间:2019/6/4 15:27:04  对本文有异议

需求

一个平台P,包含产品a、b、c、d、e。各产品UI样式风格统一,且会用到公共配置(HOST、是否添加埋点js)、组件(头部导航、表格、搜索框)、方法(请求拦截、生成UUID)。

现状:由于历史遗留原因,各产品为独立SPA、各自维护,配置、组件也都自成一体,只是大概样式上保持了一致,但细节(比如同一面包屑样式,左边距5px、8px都有)都不一致。
这种情况下,改组件、改配置都得一改改多个地方,且有些项目是vue-cli2、有些是vue-cli3,项目间依赖包的版本也不一致,维护起来非常不友好。

目标:整合各产品单页应用为MPA,提取公共文件(主题、配置、组件、方法),减少规范性东西的维护成本。

目录结构对比

整合前

  1. bds-bank-fe
  2. README.md
  3. // 静态资源输出目录
  4. └───dist
  5. └───index.html + static // 平台首页
  6. └───label // 产品a
  7. └───index.html + static
  8. └───metrics // 产品b
  9. └───service // 产品c
  10. └───help // 产品d
  11. // 项目路径
  12. └───help-center // 产品d
  13. └───portal-page // 平台首页
  14. └───service-doc // 产品c
  15. └───unify-label // 产品a
  16. └───unify-metrics // 产品b
  17. └───build
  18. └───config
  19. └───src

整合后

  1. // 静态资源输出目录
  2. └───dist
  3. └───index.html
  4. └───label.html
  5. └───metric.html
  6. └───service.html
  7. └───stocktake.html
  8. └───css
  9. └───js
  10. └───img
  11. ├── public
  12. └───favicon.ico
  13. └───index.html
  14. // 项目路径
  15. ├── src
  16.    └── assets
  17.    └── components
  18.    ├── pages
  19.    ├── index
  20.    ├── label
  21.    ├── metric
  22.    ├── service
  23.    ├── stocktake

实现

vue-cli 3.0官方支持多页,重点在于vue.config.js文件中pages这个配置项,每个页面单独配置entry、template、filename等。pages配置说明

  1. // 官网示例如下
  2. module.exports = {
  3. pages: {
  4. index: {
  5. // page 的入口
  6. entry: 'src/index/main.js',
  7. // 模板来源
  8. template: 'public/index.html',
  9. // 在 dist/index.html 的输出
  10. filename: 'index.html',
  11. // 当使用 title 选项时,
  12. // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
  13. title: 'Index Page',
  14. // 在这个页面中包含的块,默认情况下会包含
  15. // 提取出来的通用 chunk 和 vendor chunk。
  16. chunks: ['chunk-vendors', 'chunk-common', 'index']
  17. },
  18. // 当使用只有入口的字符串格式时,
  19. // 模板会被推导为 `public/subpage.html`
  20. // 并且如果找不到的话,就回退到 `public/index.html`。
  21. // 输出文件名会被推导为 `subpage.html`。
  22. subpage: 'src/subpage/main.js'
  23. }
  24. }

Step1: 创建新项目

选择需要的Babel、Router、Vuex、eslint...

具体步骤参考官网:创建一个项目

Step2: 修改配置文件vue.config.js

在根目录下新建public文件夹,包含favicon.ico和index.html两个文件。

index文件内容如下:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width,initial-scale=1.0">
  7. <link rel="icon" href="<%= BASE_URL %>favicon.ico" rel="external nofollow" >
  8. <title>P-公共服务平台</title>
  9. </head>
  10. <body>
  11. <noscript>
  12. <strong>
  13. We're sorry but page doesn't work properly without JavaScript enabled. Please enable it to continue.
  14. </strong>
  15. </noscript>
  16. <div id="app"></div>
  17. <!-- built files will be auto injected -->
  18. </body>
  19. </html>

然后,在根目录下新建vue.config.js

  1. const glob = require('glob')
  2. const path = require('path')
  3. const resolve = (dir) => path.join(__dirname, dir)
  4.  
  5. const PAGES_PATH = './src/pages/*/*.js'
  6.  
  7. module.exports = {
  8. pages: setPages(),
  9. // TODO:以下内容非生成多页应用必须配置
  10. lintOnSave: true,
  11. productionSourceMap: false,
  12. chainWebpack: config => {
  13. /**
  14. * 自动化导入文件
  15. */
  16. const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
  17. types.forEach(
  18. type => addStyleResource(config.module.rule('less').oneOf(type)))
  19. /**
  20. * 添加别名
  21. */
  22. config.resolve.alias
  23. .set('@index', resolve('src/pages/index'))
  24. .set('@label', resolve('src/pages/label'))
  25. .set('@metrics', resolve('src/pages/metric'))
  26. .set('@service', resolve('src/pages/service'))
  27. .set('@stocktake', resolve('src/pages/stocktake'))
  28. /**
  29. * 菜单icon处理为svg-sprite
  30. */
  31. config.module
  32. .rule('svg')
  33. .exclude
  34. .add(resolve('src/assets/icons/menus'))
  35. .end()
  36. config.module
  37. .rule('svg-sprite-loader')
  38. .test(/\.svg$/)
  39. .include
  40. .add(resolve('src/assets/icons/menus')) // 处理目录
  41. .end()
  42. .use('svg-sprite-loader')
  43. .loader('svg-sprite-loader')
  44. .options({
  45. symbolId: 'icon-[name]'
  46. })
  47. }
  48. }
  49.  
  50. /**
  51. * 组装页面
  52. */
  53. function setPages () {
  54. let pages = {}
  55. glob.sync(PAGES_PATH).forEach(filepath => {
  56. let fileList = filepath.split('/')
  57. let fileName = fileList[fileList.length - 2]
  58.  
  59. pages[fileName] = {
  60. entry: filepath,
  61. template: 'public/index.html',
  62. filename: `${fileName}.html`,
  63. // title:
  64. chunks: ['chunk-vendors', 'chunk-common', fileName]
  65. }
  66. })
  67. return pages
  68. }
  69.  
  70. /**
  71. * 注入公共less
  72. * @param rule
  73. */
  74. function addStyleResource (rule) {
  75. rule.use('style-resource')
  76. .loader('style-resources-loader')
  77. .options({
  78. patterns: [
  79. path.resolve(__dirname, 'src/assets/styles/variable.less')
  80. ]
  81. })
  82. }

Step3: 拷贝原项目src目录至pages下,大概长这样

Step4: 各产品原项目下package.json依赖包都挪到根目录下package.json,重新安装

PS:由于依赖向上升级,某些老版本依赖包可能会存在升级引发的问题,需要细心走查一遍。这里由于业务不一样,就不详细赘述了

然后npm start,完美启动~

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号