详解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 相关文章推荐
JavaScript中的Screen屏幕对象
Jan 16 Javascript
javascript 最常用的10个自定义函数[推荐]
Dec 26 Javascript
idTabs基于JQuery的根据URL参数选择Tab插件
Apr 11 Javascript
JS动态添加与删除select中的Option对象(示例代码)
Dec 20 Javascript
Underscore.js常用方法总结
Feb 28 Javascript
JS实现CheckBox复选框全选全不选功能
May 06 Javascript
js判断当前页面在移动设备还是在PC端中打开
Jan 06 Javascript
AngularJS向后端ASP.NET API控制器上传文件
Feb 03 Javascript
JS检测是否可以访问公网服务器功能代码
Jun 19 Javascript
微信小程序实现手势滑动卡片效果
Aug 26 Javascript
node.js中对Event Loop事件循环的理解与应用实例分析
Feb 14 Javascript
uniapp实现横向滚动选择日期
Oct 21 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 smarty模板引擎的6个小技巧
2014/04/24 PHP
PHP使用file_get_content设置头信息的方法
2016/02/14 PHP
layui数据表格自定义每页条数limit设置
2019/10/26 PHP
PHP执行普通shell命令流程解析
2020/08/24 PHP
JavaScript toFixed() 方法
2010/04/15 Javascript
jquery动态增加text元素以及删除文本内容实例代码
2013/07/01 Javascript
JS去除右边逗号的简单方法
2013/07/03 Javascript
jquery+ajax+C#实现无刷新操作数据库数据的简单实例
2014/02/08 Javascript
JavaScript获取客户端IP的方法(新方法)
2016/03/11 Javascript
一系列Bootstrap导航条使用方法分享
2016/04/29 Javascript
原生javascript AJAX 三级联动的实现代码
2018/05/04 Javascript
js实现左右两侧浮动广告
2018/07/09 Javascript
layui lay-verify form表单自定义验证规则详解
2019/09/18 Javascript
JavaScript, select标签元素左右移动功能实现
2020/05/14 Javascript
vue中后端做Excel导出功能返回数据流前端的处理操作
2020/09/08 Javascript
微信小程序实现多张图片上传功能
2020/11/18 Javascript
[04:00]DOTA2解说界神雕侠侣 CJ第四天谷子现场过生日
2013/07/30 DOTA
pycharm 使用心得(六)进行简单的数据库管理
2014/06/06 Python
Python可变参数*args和**kwargs用法实例小结
2018/04/27 Python
简单了解django缓存方式及配置
2019/07/19 Python
Python实现微信机器人的方法
2019/09/06 Python
python3:excel操作之读取数据并返回字典 + 写入的案例
2020/09/01 Python
如何用Python徒手写线性回归
2021/01/25 Python
Alexandre Birman美国官网:亚历山大·伯曼
2019/10/30 全球购物
面向对象编程OOP的优点
2013/01/22 面试题
家长学校实施方案
2014/03/15 职场文书
洗车工岗位职责
2014/03/15 职场文书
活动总结报告范文
2014/05/04 职场文书
工程售后服务承诺书
2014/05/21 职场文书
安全生产标语
2014/06/06 职场文书
校运会口号
2014/06/18 职场文书
2014年党员整改措施
2014/10/24 职场文书
党员违纪检讨书怎么写
2014/11/01 职场文书
2014年行风建设工作总结
2014/12/01 职场文书
MYSQL主从数据库同步备份配置的方法
2021/05/26 MySQL
安装Windows Server 2012 R2企业版操作系统并设置好相关参数
2022/04/29 Servers