详解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 相关文章推荐
[IE&amp;FireFox兼容]JS对select操作
Jan 07 Javascript
利用javascript打开模态对话框(示例代码)
Jan 11 Javascript
ZeroClipboard插件实现多浏览器复制功能(支持firefox、chrome、ie6)
Aug 30 Javascript
JS+CSS实现带关闭按钮DIV弹出窗口的方法
Feb 27 Javascript
整理Javascript事件响应学习笔记
Dec 02 Javascript
js实现点击切换checkbox背景图片的简单实例
May 08 Javascript
微信小程序删除处理详解
Aug 16 Javascript
angularJS开发注意事项
May 26 Javascript
vue中子组件调用兄弟组件方法
Jul 06 Javascript
微信小程序实现留言板
Oct 31 Javascript
使用jQuery动态设置单选框的选中效果
Dec 06 jQuery
通过GASP让vue实现动态效果实例代码详解
Nov 24 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
亚洲咖啡有什么?亚洲咖啡产地介绍 亚洲咖啡有什么特点?
2021/03/05 新手入门
解析Extjs与php数据交互(增删查改)
2013/06/25 PHP
PHP包含文件函数include、include_once、require、require_once区别总结
2014/04/05 PHP
PHP记录页面停留时间的方法
2016/03/30 PHP
PHP实现二维数组按某列进行排序的方法
2016/11/18 PHP
PHP检测数据类型的几种方法(总结)
2017/03/04 PHP
PHP7如何开启Opcode打造强悍性能详解
2018/05/11 PHP
JQuery CSS样式控制 学习笔记
2009/07/23 Javascript
显示js对象所有属性和方法的函数
2009/10/16 Javascript
深入理解JavaScript定时机制
2010/10/29 Javascript
在JavaScript里嵌入大量字符串常量的实现方法
2013/07/07 Javascript
JavaScript中的数学运算介绍
2014/12/29 Javascript
JS网页在线获取鼠标坐标值的方法
2015/02/28 Javascript
Angularjs中使用Filters详解
2016/03/11 Javascript
第一次接触神奇的Bootstrap表单
2016/07/27 Javascript
JavaScript编写一个简易购物车功能
2016/09/17 Javascript
vue中for循环更改数据的实例代码(数据变化但页面数据未变)
2017/09/15 Javascript
node.js多个异步过程中判断执行是否完成的解决方案
2017/12/10 Javascript
JavaScript实现读取与输出XML文件数据的方法示例
2018/06/05 Javascript
Vue.js递归组件实现组织架构树和选人功能案例分析
2019/07/03 Javascript
[44:15]DOTA2上海特级锦标赛主赛事日 - 5 败者组决赛Liquid VS EG第二局
2016/03/06 DOTA
Python遍历zip文件输出名称时出现乱码问题的解决方法
2015/04/08 Python
不可错过的十本Python好书
2017/07/06 Python
python自定义函数实现一个数的三次方计算方法
2019/01/20 Python
Python3基础教程之递归函数简单示例
2019/06/07 Python
python 实现提取log文件中的关键句子,并进行统计分析
2019/12/24 Python
python如何安装下载后的模块
2020/07/03 Python
一款利用纯css3实现的超炫3D表单的实例教程
2014/12/01 HTML / CSS
2014年党课学习材料
2014/05/11 职场文书
品牌服务方案
2014/06/03 职场文书
授权委托书(公民个人适用)
2014/09/19 职场文书
个人欠款协议书范本2014
2014/11/02 职场文书
给老婆的检讨书(搞笑版)
2015/05/06 职场文书
Python re.sub 反向引用的实现
2021/07/07 Python
Python实现位图分割的效果
2021/11/20 Python
python读取mat文件生成h5文件的实现
2022/07/15 Python