sea.js項(xiàng)目遷移到webpack

項(xiàng)目背景

最近參與一個(gè)舊項(xiàng)目功能遷移的工作,舊項(xiàng)目使用到sea.js、 layerjquery、 art-templatebootstrap、jquey.ztree等,新項(xiàng)目是基于vue-cliwebpack模板生成的項(xiàng)目。舊項(xiàng)目的功能是穩(wěn)定可靠且通過了充分的測試,且這部分功能其中的業(yè)務(wù)自己也并不熟悉。使用常規(guī)的vue開發(fā)方式重寫整塊功能需要極大的勇氣以及耗費(fèi)大量的時(shí)間精力,且結(jié)果往往吃力不討好。鑒于自己對(duì)于sea.js,jquery生態(tài)以及webpack,vue有比較深入的的了解認(rèn)識(shí),一番評(píng)估下,認(rèn)為這種方案是可行的且能夠在不改動(dòng)業(yè)務(wù)邏輯代碼進(jìn)行快速遷移。

那么現(xiàn)在我們就開始吧。

項(xiàng)目的目錄和代碼結(jié)構(gòu)

先簡單介紹一下項(xiàng)目目錄和代碼結(jié)構(gòu),舊項(xiàng)目每一個(gè)功能模塊以main.js為入口。main.js用define聲明了一個(gè)模塊,用require引用兩個(gè)模塊的代碼,并對(duì)外暴露了一個(gè)入口renderHtml。因?yàn)榕f項(xiàng)目都是這樣模塊的化的寫法,從而為不動(dòng)業(yè)務(wù)代碼遷移到webpack成為了可能。

  • 舊項(xiàng)目功能模塊
image.png
  • main.js
image.png
  • 新項(xiàng)目目錄結(jié)構(gòu),標(biāo)準(zhǔn)的vue-cli生成的,對(duì)于vue-cli可以移步這里,查看更多信息
image.png

與vue組件整合

原來的sea.js的項(xiàng)目的功能對(duì)外暴露一個(gè)renderHtml方法,假設(shè)這個(gè)功能名稱one,內(nèi)部經(jīng)過一系列處理后會(huì)把html代碼渲染到id為one的元素節(jié)點(diǎn)下。故我們寫一個(gè)vue組件,對(duì)one這個(gè)功能做一個(gè)引用,并在掛載生命周期開始執(zhí)行,就完成了對(duì)該功能的引用。新項(xiàng)目中其他地方需要這一塊的功能,就直接使用應(yīng)用vue這個(gè)組件就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>

在實(shí)際開發(fā)調(diào)試過程中main.js中的代碼可以一點(diǎn)點(diǎn)加入,以便快速定位問題并解決。
那么實(shí)際上會(huì)遇到哪些問題并如何解決呢,下面會(huì)闡述移植過程中的解決方法。

在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>

這樣在項(xiàng)目中就可以直接使用layer和等全局變量了,另外使用全局變量eslint會(huì)報(bào)警告的,所以記得在.eslintrc.js配置一下忽略layer和全局變量

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

sea.js模塊代碼處理

因?yàn)閣ebpack打包的文件已經(jīng)是模塊化的,并不需要define來定義模塊,故刪除js代碼中的define包裹函數(shù)

define(function(require, exports, module) {
// 內(nèi)部的code需要保留
})

sea.js中使用的是require引用文件,這個(gè)在webpack打包天然支持
但是module.exports或者exports輸出對(duì)外暴露方法,默認(rèn)的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前綴。
實(shí)際調(diào)試過程中,用瀏覽器訪問頁面,凡是出現(xiàn)404的資源引用,搜索一下對(duì)應(yīng)的代碼,通通加上/static/前綴。

art-template處理

舊項(xiàng)目中會(huì)使用art-template讓模板html與數(shù)據(jù)融合,然后渲染到頁面上。代碼如下

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

值得高興的是,art-template的最新版本支持webpack預(yù)處理。
先安裝一下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文件,現(xiàn)在的tpl文件不再使用url地址,而是使用相對(duì)文件路徑,且因?yàn)閣ebpack已經(jīng)在打包的時(shí)候預(yù)編譯,就無需compile了。最后的代碼如下

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

bootstrap.css處理

細(xì)心的同學(xué),會(huì)發(fā)現(xiàn)bootstrap.css并沒有在index.html引用。因?yàn)閎ootstrap.css內(nèi)置的樣式,其樣式名稱會(huì)對(duì)已存在的樣式產(chǎn)生影響。
故需要給bootstap樣式加上作用域,并在需要的功能模塊加上對(duì)應(yīng)樣式名稱
新建一個(gè)文件my-bootstrap.scss,拷貝完整的bootstrap.css樣式到其中,并在項(xiàng)目中引用my-bootstrap.scss
my-bootstrap.scss

.bs-m-wrapper {
    // 這里拷貝完整的bootstrap.css樣式
}

這樣子在需要功能模塊上最外層元素加入bs-m-wrapper樣式就可以看到原來的效果了。
特別注意的layer的彈窗是放在body下的,所有需要對(duì)彈窗也統(tǒng)一加上該樣式。

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

ajax請(qǐng)求處理

新的項(xiàng)目接口也發(fā)生了變化,原來的認(rèn)證信息放在cookie中,但新的接口使用了token機(jī)制,在header加入token進(jìn)行認(rèn)證校驗(yàn)。
故需要全局?jǐn)r截ajax請(qǐng)求,增加頭部信息。

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

值得注意的是在調(diào)用$.ajax方法的時(shí)候,如果有beforeSend屬性,全局的beforeSend會(huì)被覆蓋,導(dǎo)致無法加上我們需要的token信息。故需要手動(dòng)調(diào)用一下全局的beforeSend。如下所示

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

至此,我們就完成了功能的從sea.js遷移到webpack項(xiàng)目中了。

結(jié)語

這種方式可以快速遷移一些復(fù)雜的功能,但美酒雖好,也不要貪杯。畢竟一個(gè)項(xiàng)目用到更多的庫,使用非主流的寫法,對(duì)項(xiàng)目成員的要求也越高,可維護(hù)性也就越低。
一路前行,且行且珍惜。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 基于Vue的一些資料 內(nèi)容 UI組件 開發(fā)框架 實(shí)用庫 服務(wù)端 輔助工具 應(yīng)用實(shí)例 Demo示例 element★...
    嘗了又嘗閱讀 1,277評(píng)論 0 1
  • GitChat技術(shù)雜談 前言 本文較長,為了節(jié)省你的閱讀時(shí)間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,876評(píng)論 7 110
  • 寫在前面的話 閱讀本文之前,先看下面這個(gè)webpack的配置文件,如果每一項(xiàng)你都懂,那本文能帶給你的收獲也許就比較...
    不忘初心_9a16閱讀 3,326評(píng)論 0 16
  • 目錄 上一章 下一章 隨著年齡漸長,我們學(xué)會(huì)了篩選感官記憶,略去無關(guān)緊要的細(xì)枝末節(jié),只記住有關(guān)的部分,直到成為習(xí)慣...
    洛洛莉ya閱讀 20,214評(píng)論 13 18
  • 你的人生輸在嘴上了嘛? 今天我說的這個(gè)嘴巴,不是講話的嘴巴,而是你吃飯的嘴巴,很多人奇怪了,大象你是不是在搞笑?我...
    高大勝閱讀 2,126評(píng)論 0 16

友情鏈接更多精彩內(nèi)容