老項目平滑遷移 vue-cli3 日誌

升級背景

公司項目是用 vue-cli 搭建的,至今已經有2年了熱更新也愈來愈慢,正好 vue cli3 也出來,據說編譯速度大大提高,就想把項目移植到 vue cli3php

現狀

技術: "webpack": "^3.6.0", "vue": "^2.5.2"css

  1. 代碼量愈來愈大,編譯速度也愈來愈慢,打包時間快一分鐘,熱更新也愈來愈慢,影響開發效率
  2. 沒有引入 eslint 語法檢查, 代碼風格不一
  3. webpack 配置繁瑣
  4. 愈來愈多的UI庫支持vue cli3

升級目的

  1. 提高編譯速度
  2. vue cli3 建立項目時,引入 eslint,統一代碼風格,方便代碼 review(新手前端不想單獨引入)
  3. 全部配置vue cli3 已經作了處理,額外配置在vue.config.js中處理便可
  4. 適應技術發展的潮流 🐶

項目升級

vue cl3 建立項目

vue create hello-world
複製代碼

詳細步驟參考vue cli3文檔html

我用的配置是vue-router, vuex, less, babel, eslint前端

文件遷移

src 目錄

簡單粗暴把src移植過來,vue

複製src/pages,src/App.vue, src/index.html

複製src/main.js

報錯:jquery

控制檯報錯
main.js:121 Uncaught SyntaxError: Unexpected token !
    at Object../src/main.js (app.js:2481)
    at __webpack_require__ (app.js:770)
    at fn (app.js:130)
    at Object.1 (app.js:2555)
    at __webpack_require__ (app.js:770)
    at app.js:908
    at app.js:911

命令行報錯
* cube-ui in ./src/main.js
* cube-ui/lib/picker/index.js in ./src/main.js
* cube-ui/lib/picker/picker.min.css in ./src/main.js
* cube-ui/lib/picker/picker.min.js in ./src/main.js
* cube-ui/lib/picker/style.css in ./src/main.js
* mint-ui in ./src/main.js
* mint-ui/lib/style.css in ./src/main.js
* vconsole in ./src/main.js
* vue-lazyload in ./src/main.js
* vue-resource in ./src/main.js

複製代碼

緣由:沒有引入第三方庫和文件webpack

解決:ios

  1. 引入對應的less文件和js文件
  2. 安裝第三方庫
npm i --save vue-resource vue-lazyload  mint-ui vconsole
複製代碼
  1. cube ui 引入 cube ui 在vue cli3中的引入方式和vue cli有所不一樣,具體步驟查看文檔
vue add cube-ui
複製代碼

我這裏是全局引入,由於原來的代碼裏也是全局引用的,其實應該按需引入的,這個等遷移工做完成後再優化,升級工做期間就不對業務代碼作太大改動了web

全局引入後,src目錄會多一個cube-ui.js文件vue-router

  1. 此時重啓服務後,報錯
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

(found in <Root>)
複製代碼

緣由:引入的vue.js版本和main.js裏的寫法不匹配

解決:修改main.js

// 原來
new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})
// 修改
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
複製代碼
  1. 成功編譯

複製路由文件

vue cli的路由文件是放在 router 文件夾的, vue cli3 的路由在src/router.js, 我沿用vue cli的文件結構,依舊放在 router 文件夾裏 引入路由文件後,報錯:缺失components文件,接下來就

複製components文件夾

控制檯瘋狂報錯,仔細看了下,有如下幾種

  1. 文件名引入大小寫問題
  2. 自定義指令文件, mixins文件還未引入
  3. 組件內引用的一些第三方庫還沒安裝 npm i @chenfengyuan/vue-qrcode axios clipboard html2canvas particles.js swiper vue-awesome-swiper weixin-js-sdk --save
  4. less變量引用報錯

解決:在vue.config.js引入全局less變量,參考vue cli3文檔

const path = require('path')
module.exports = {
  chainWebpack: config => {
    const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
    types.forEach(type =>
      addStyleResource(config.module.rule('less').oneOf(type))
    )
    config.plugins.delete('prefetch')
  },
  css: {
    loaderOptions: {
      stylus: {
        'resolve url': true,
        import: []
      }
    }
  },
  pluginOptions: {
    'cube-ui': {
      postCompile: true,
      theme: false
    }
  }
}

function addStyleResource (rule) {
  rule
    .use('style-resource')
    .loader('style-resources-loader')
    .options({
      patterns: [
        path.resolve(__dirname, 'src/assets/css/variable.less') // 須要全局導入的less
      ]
    })
}

複製代碼

jQuery引用

項目還用了jquery😭,用的地方還很多

解決:

  1. npm install jquery --save
  2. 檢查下package.json看是否已經引入了
  3. .eslintrc.js 文件中,env 中 添加 jquery:true
  4. vue.config.js 添加插件
const webpack = require('webpack')
module.exports = {
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'windows.jQuery': 'jquery'
      })
    ]
  },
}
複製代碼
  1. main.js: import $ from 'jquery'

store文件引入

個人store文件是放在 store 文件夾的,遷移過去以後再更改main.js的引入路徑便可

到這一步,項目基本就能夠正常編譯了,能夠看到頁面的基本輪廓,但還存在ui樣式尺寸不對,請求跨域了等問題,依次解決

跨域

在vue.config.js中配置

devServer: {
    port: 8080,
    proxy: {
      '/apis': {
        target: 'http://dev.xxx.com',
        changeOrigin: true,
        pathRewrite: {
          '/apis': ''
        }
      }
    }
  }
複製代碼

rem

修改 postcss.config.js

module.exports = {
  plugins: {
    autoprefixer: {},
    'postcss-px2rem': {
      remUnit: 75
    }
  }
}

複製代碼

好咯,到這一步,樣式正常啦,請求也能夠正常發送接收啦。

表面上看起來和正常的項目沒什麼區別了,但是一打開控制檯,又看到一個報錯..

vue-awesome-swiper

Swiper.vue?56a2:97 Uncaught (in promise) TypeError: _this.swiper.lockSwipes is not a function
    at eval (Swiper.vue?56a2:97)
複製代碼

是swiper插件的報錯,上網找了下緣由:swiper 新版本沒有了lockSwipes這個api,替換成了 allowSlideNext

解決:

this.swiper.lockSwipes() 
// 替換成
this.swiper.allowSlideNext = false
複製代碼

某些地方的icon有點錯位

排查了下緣由是全局引入的 cube-ui 的默認樣式引發的,在reset.less文件加了句

body {
    line-height: initial;
  }
複製代碼

成功編譯

至此爲止,項目已經能夠成功在 vue cli3 下跑起來啦。處處點一點,嗯,沒什麼報錯了,接下來就來看看打包部分

打包

打包配置

原先的打包配置是在config/index.js

const path = require('path')

module.exports = {
  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),
    // Paths
    // 輸出靜態資源路徑
    assetsRoot: path.resolve(__dirname, '../../../../resource'),
    // 輸出靜態資源子目錄
    assetsSubDirectory: 'static',
    assetsPublicPath: 'resource/',
  }
}
複製代碼

項目打包後生成的 index.html 和生成的靜態資源的目錄是不一樣的,並且打包好的html文件引用的靜態資源路徑得是相對路徑(由於想開發測試生產都用一套代碼)

在vue.config.js中的配置也須要修改:

{
  publicPath: process.env.NODE_ENV === 'production' ? './resource' : '/',
  indexPath: path.resolve(__dirname, 'dist/index.php'),//輸出html目錄
  outputDir: path.resolve(__dirname, '../../../resource'),// 靜態資源目錄
  assetsDir: 'static',// 靜態資源子目錄
}
複製代碼

vue cli3的文檔只是很簡單的提到publicPath,assetsDir.. 谷歌了半天,查了很久的資料,終於讓我找到了答案😭

CSS minification error

配置完成, npm run build

報錯:

CSS minification error: Cannot read property 'type' of undefined. File: css/doubleEleven.08c6b745.css
複製代碼

這個坑爹的報錯,讓我整整花了半天時間,這個報錯的資料超少,最後是在vue cli3 的一個issue上看到了, 這個issue還由於提問不規範被關閉了,不過讓我看到了條評論是說多是transform:rotate()引發的。

雖然不知道爲何,我仍是試了試查找了下項目代碼,發現:

transform: rotate3d(0, 1, 00deg);
複製代碼

立馬糾正,再次打包,打包成功,而且在開發,測試環境運行良好,耶️✌️

總結

😂升級的vue cli3後代碼校驗果然嚴格的好多,上面的錯誤在原來的編輯打包一點問題都沒有,到這裏就原形畢露了,不過總算完成了升級,在調試時明顯感受熱更新速度提高了好多。

到此爲止,此次的遷移工做就完成咯,固然還有些代碼還得lint下或者手動修復下格式,這個就後續再作啦。

相關文章
相關標籤/搜索