sea.js项目迁移到webpack

项目背景

最近参与一个旧项目功能迁移的工作,旧项目使用到sea.jslayerjqueryart-templatebootstrapjquey.ztree等,新项目是基于vue-cliwebpack模板生成的项目。旧项目的功能是稳定可靠且通过了充分的测试,且这部分功能其中的业务自己也并不熟悉。使用常规的vue开发方式重写整块功能需要极大的勇气以及耗费大量的时间精力,且结果往往吃力不讨好。鉴于自己对于sea.js,jquery生态以及webpack,vue有比较深入的的了解认识,一番评估下,认为这种方案是可行的且能够在不改动业务逻辑代码进行快速迁移。

那么现在我们就开始吧。

项目的目录和代码结构

先简单介绍一下项目目录和代码结构,旧项目每一个功能模块以main.js为入口。main.js用define声明了一个模块,用require引用两个模块的代码,并对外暴露了一个入口renderHtml。因为旧项目都是这样模块的化的写法,从而为不动业务代码迁移到webpack成为了可能。

  • 旧项目功能模块
image.png
  • main.js
image.png
  • 新项目目录结构,标准的vue-cli生成的,对于vue-cli可以移步这里,查看更多信息
image.png

与vue组件整合

原来的sea.js的项目的功能对外暴露一个renderHtml方法,假设这个功能名称one,内部经过一系列处理后会把html代码渲染到id为one的元素节点下。故我们写一个vue组件,对one这个功能做一个引用,并在挂载生命周期开始执行,就完成了对该功能的引用。新项目中其他地方需要这一块的功能,就直接使用应用vue这个组件就OK了。

vue代码大致如下

<template>
  <div class="one-wrapper">
    <div class="bs-vlan-wrapper content" id="one">
    </div>
  </div>
</template>
<script>
import One from './main'
export default {
  mounted () {
    One.renderHtml()
  }
}
</script>

在实际开发调试过程中main.js中的代码可以一点点加入,以便快速定位问题并解决。
那么实际上会遇到哪些问题并如何解决呢,下面会阐述移植过程中的解决方法。

在index.html引入需要的文件

把需要的资源文件放置在static目录下,包括依赖的js,css文件,图片。然后把需要css和js引入到index.html文件中

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title></title>
    <link href="/static/js/layer/skin/layer.css" rel="stylesheet" text="text/css">
    <link href="/static/js/ztree/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" text="text/css"></link>
    <link href="/static/js/font-awesome/css/font-awesome.min.css" rel="stylesheet" text="text/css">
  </head>
  <body>
    <div id="app"></div>
    <script src="/static/js/jquery/jquery-2.2.3.min.js"></script>
    <script src="/static/js/layer/layer.js"></script>
    <script src="/static/js/ztree/js/jquery.ztree.all.min.js"></script>
    <script src="/static/js/bootstrap/js/bootstrap.min.js"></script>
    <!-- built files will be auto injected -->
  </body>
</html>

这样在项目中就可以直接使用layer和等全局变量了,另外使用全局变量eslint会报警告的,所以记得在.eslintrc.js配置一下忽略layer和全局变量

// .eslintrc.js
globals: {
  layer: false,
  $: false,
},

sea.js模块代码处理

因为webpack打包的文件已经是模块化的,并不需要define来定义模块,故删除js代码中的define包裹函数

define(function(require, exports, module) {
// 内部的code需要保留
})

sea.js中使用的是require引用文件,这个在webpack打包天然支持
但是module.exports或者exports输出对外暴露方法,默认的babel的配置是无法支持,故需要改变.babelrc配置。
做法是删除presets env 下的 module=false,即可以支持。
最终.babelrc的如下所示

{
  "presets": [
    ["env", {
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-vue-jsx", "transform-runtime"]
}

图片处理

我们把图片放到/static下后,图片的访问路径多了/static前缀,故需要扫描css样式中以及代码中的图片路径就都加一下/static前缀。
实际调试过程中,用浏览器访问页面,凡是出现404的资源引用,搜索一下对应的代码,通通加上/static/前缀。

art-template处理

旧项目中会使用art-template让模板html与数据融合,然后渲染到页面上。代码如下

var htmlTpl = require('/template/html.tpl')
var htmlTplRender = template.compile(htmlTpl);
layer.open({
  content: htmlTplRender(),
}

值得高兴的是,art-template的最新版本支持webpack预处理。
先安装一下art-tempate-loader

npm install art-template
npm install art-template-loader --save-dev

并在webpack.base.config.js加入以下loader

module.exports = {
    module: {
       {
            test: /\.tpl$/,
            loader: "art-template-loader",
            options: {
            }
        }]
    },
}

最后引入tpl文件,现在的tpl文件不再使用url地址,而是使用相对文件路径,且因为webpack已经在打包的时候预编译,就无需compile了。最后的代码如下

var htmlTplRender = require('/template/html.tpl');
layer.open({
content: htmlTplRender(),
}

bootstrap.css处理

细心的同学,会发现bootstrap.css并没有在index.html引用。因为bootstrap.css内置的样式,其样式名称会对已存在的样式产生影响。
故需要给bootstap样式加上作用域,并在需要的功能模块加上对应样式名称
新建一个文件my-bootstrap.scss,拷贝完整的bootstrap.css样式到其中,并在项目中引用my-bootstrap.scss
my-bootstrap.scss

.bs-m-wrapper {
    // 这里拷贝完整的bootstrap.css样式
}

这样子在需要功能模块上最外层元素加入bs-m-wrapper样式就可以看到原来的效果了。
特别注意的layer的弹窗是放在body下的,所有需要对弹窗也统一加上该样式。

layer.open({
  skin: 'bs-m-wrapper',
})

ajax请求处理

新的项目接口也发生了变化,原来的认证信息放在cookie中,但新的接口使用了token机制,在header加入token进行认证校验。
故需要全局拦截ajax请求,增加头部信息。

$.ajaxSetup({
  beforeSend: function(request, opt) {
    request.setRequestHeader("token", "my token...");
  },
})

值得注意的是在调用$.ajax方法的时候,如果有beforeSend属性,全局的beforeSend会被覆盖,导致无法加上我们需要的token信息。故需要手动调用一下全局的beforeSend。如下所示

$.ajax({
  beforeSend: function(request, opt) {
    $.ajaxSettings.beforeSend(request, opt);
    // other
  },
});

至此,我们就完成了功能的从sea.js迁移到webpack项目中了。

结语

这种方式可以快速迁移一些复杂的功能,但美酒虽好,也不要贪杯。毕竟一个项目用到更多的库,使用非主流的写法,对项目成员的要求也越高,可维护性也就越低。
一路前行,且行且珍惜。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341

推荐阅读更多精彩内容

  • 基于Vue的一些资料 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 element★...
    尝了又尝阅读 1,139评论 0 1
  • GitChat技术杂谈 前言 本文较长,为了节省你的阅读时间,在文前列写作思路如下: 什么是 webpack,它要...
    萧玄辞阅读 12,663评论 7 110
  • 写在前面的话 阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较...
    不忘初心_9a16阅读 3,230评论 0 17
  • 目录 上一章 下一章 随着年龄渐长,我们学会了筛选感官记忆,略去无关紧要的细枝末节,只记住有关的部分,直到成为习惯...
    洛洛莉ya阅读 20,130评论 13 18
  • 你的人生输在嘴上了嘛? 今天我说的这个嘴巴,不是讲话的嘴巴,而是你吃饭的嘴巴,很多人奇怪了,大象你是不是在搞笑?我...
    高大胜阅读 1,992评论 0 16