详解vue-cli3多页应用改造


Posted in Javascript onJune 04, 2019

需求

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

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

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

目录结构对比

整合前

详解vue-cli3多页应用改造

bds-bank-fe
│  README.md
│
│// 静态资源输出目录
│
└───dist
│  └───index.html + static // 平台首页
│  └───label // 产品a
│  │  └───index.html + static
│  └───metrics // 产品b
│  └───service // 产品c
│  └───help // 产品d
│
│// 项目路径
│
└───help-center // 产品d
└───portal-page // 平台首页
└───service-doc // 产品c
└───unify-label // 产品a
└───unify-metrics // 产品b
│  └───build
│  └───config
│  └───src

整合后

详解vue-cli3多页应用改造

│// 静态资源输出目录
│
└───dist
│  └───index.html
│  └───label.html
│  └───metric.html
│  └───service.html
│  └───stocktake.html
│  └───css
│  └───js
│  └───img
├── public
│  └───favicon.ico
│  └───index.html
│
│// 项目路径
│
├── src
│   └── assets
│   └── components
│   ├── pages
│     ├── index
│     ├── label
│     ├── metric
│     ├── service
│     ├── stocktake

实现

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

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

Step1: 创建新项目

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

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

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

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

详解vue-cli3多页应用改造

index文件内容如下:

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

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

const glob = require('glob')
const path = require('path')
const resolve = (dir) => path.join(__dirname, dir)

const PAGES_PATH = './src/pages/*/*.js'

module.exports = {
 pages: setPages(),
 // TODO:以下内容非生成多页应用必须配置
 lintOnSave: true,
 productionSourceMap: false,
 chainWebpack: config => {
  /**
   * 自动化导入文件
   */
  const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
  types.forEach(
   type => addStyleResource(config.module.rule('less').oneOf(type)))
  /**
   * 添加别名
   */
  config.resolve.alias
   .set('@index', resolve('src/pages/index'))
   .set('@label', resolve('src/pages/label'))
   .set('@metrics', resolve('src/pages/metric'))
   .set('@service', resolve('src/pages/service'))
   .set('@stocktake', resolve('src/pages/stocktake'))
  /**
   * 菜单icon处理为svg-sprite
   */
  config.module
   .rule('svg')
   .exclude
   .add(resolve('src/assets/icons/menus'))
   .end()
  config.module
   .rule('svg-sprite-loader')
   .test(/\.svg$/)
   .include
   .add(resolve('src/assets/icons/menus')) // 处理目录
   .end()
   .use('svg-sprite-loader')
   .loader('svg-sprite-loader')
   .options({
    symbolId: 'icon-[name]'
   })
 }
}

/**
 * 组装页面
 */
function setPages () {
 let pages = {}
 glob.sync(PAGES_PATH).forEach(filepath => {
  let fileList = filepath.split('/')
  let fileName = fileList[fileList.length - 2]

  pages[fileName] = {
   entry: filepath,
   template: 'public/index.html',
   filename: `${fileName}.html`,
   // title:
   chunks: ['chunk-vendors', 'chunk-common', fileName]
  }
 })
 return pages
}

/**
 * 注入公共less
 * @param rule
 */
function addStyleResource (rule) {
 rule.use('style-resource')
  .loader('style-resources-loader')
  .options({
   patterns: [
    path.resolve(__dirname, 'src/assets/styles/variable.less')
   ]
  })
}

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

详解vue-cli3多页应用改造

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

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

然后npm start,完美启动~

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

Javascript 相关文章推荐
JS DOM 操作实现代码
Aug 01 Javascript
jQuery最佳实践完整篇
Aug 20 Javascript
使用UglifyJS合并/压缩JavaScript的方法
Mar 07 Javascript
浅析XMLHttpRequest的缓存问题
Dec 13 Javascript
浏览器缩放检测的js代码
Sep 28 Javascript
js实现使用鼠标拖拽切换图片的方法
May 04 Javascript
浅谈js和css内联外联注意事项
Jun 30 Javascript
jQuery鼠标事件总结
Oct 13 Javascript
AngularJS全局scope与Isolate scope通信用法示例
Nov 22 Javascript
浅谈Vue父子组件和非父子组件传值问题
Aug 22 Javascript
vue路由事件beforeRouteLeave及组件内定时器的清除方法
Sep 29 Javascript
浅谈Vue.js 中的 v-on 事件指令的使用
Nov 25 Javascript
javascript异步处理与Jquery deferred对象用法总结
Jun 04 #jQuery
浅谈react-router@4.0 使用方法和源码分析
Jun 04 #Javascript
vue axios post发送复杂对象问题
Jun 04 #Javascript
vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略
Jun 04 #Javascript
vue实现分环境打包步骤(给不同的环境配置相对应的打包命令)
Jun 04 #Javascript
JavaScript实现页面中录音功能的方法
Jun 04 #Javascript
vue elementUI 表单校验功能之数组多层嵌套
Jun 04 #Javascript
You might like
PHP中如何判断AJAX提交的数据
2012/02/05 PHP
form表单传递数组数据、php脚本接收的实例
2017/02/09 PHP
PHP从尾到头打印链表实例讲解
2018/09/27 PHP
ThinkPHP3.2.3框架邮件发送功能图文实例详解
2019/04/23 PHP
关于PHP中interface的用处详解
2020/07/26 PHP
在一个form用一个SUBMIT(或button)分别提交到两个处理表单页面的代码
2007/02/15 Javascript
js继承的实现代码
2010/08/05 Javascript
实现动画效果核心方式的js代码
2013/09/27 Javascript
js中的eventType事件及其浏览器支持性介绍
2013/11/29 Javascript
原生js实现fadein 和 fadeout淡入淡出效果
2014/06/05 Javascript
AngularJS中的模块详解
2015/01/29 Javascript
JS区分浏览器页面是刷新还是关闭
2016/04/17 Javascript
Jquery实现的简单轮播效果【附实例】
2016/04/19 Javascript
jQuery+json实现动态创建复杂表格table的方法
2016/10/25 Javascript
Ztree新增角色和编辑角色回显问题的解决
2016/10/25 Javascript
Angular 4.x 动态创建表单实例
2017/04/25 Javascript
浅谈 Vue 项目优化的方法
2017/12/16 Javascript
Vue过渡效果之CSS过渡详解(结合transition,animation,animate.css)
2020/02/05 Javascript
jquery实现的放大镜效果示例
2020/02/24 jQuery
vue-video-player实现实时视频播放方式(监控设备-rtmp流)
2020/08/10 Javascript
JS数据类型分类及常用判断方法
2020/11/19 Javascript
vue3.0 自适应不同分辨率电脑的操作
2021/02/06 Vue.js
在CentOS上配置Nginx+Gunicorn+Python+Flask环境的教程
2016/06/07 Python
使用Python+selenium实现第一个自动化测试脚本
2020/03/17 Python
Python可视化工具如何实现动态图表
2020/10/23 Python
Django+Django-Celery+Celery的整合实战
2021/01/20 Python
CSS3制作Dropdown下拉菜单的方法
2015/07/18 HTML / CSS
.net工程师笔试题
2012/06/09 面试题
幼儿教师培训感言
2014/03/08 职场文书
学校法制宣传月活动总结
2014/07/03 职场文书
村干部群众路线整改措施思想汇报
2014/10/12 职场文书
基层工作经历证明
2015/06/19 职场文书
2016年度先进班组事迹材料
2016/03/01 职场文书
Django使用redis配置缓存的方法
2021/06/01 Redis
springboot+WebMagic+MyBatis爬虫框架的使用
2021/08/07 Java/Android
Netty客户端接入流程NioSocketChannel创建解析
2022/03/25 Java/Android