老项目平滑迁移 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下或者手动修复下格式,这个就后续再作啦。

相关文章
相关标签/搜索