To upgrade the background

The company’s project is built with VUe-CLI, so far it has been 2 years, and the hot update is getting slower and slower. Just now, Vue CLI3 comes out. I heard that the compilation speed has been greatly improved, so I want to transplant the project to Vue CLI3

The status quo

Technology: “webpack”: “^3.6.0”, “vue”: “^2.5.2”

  1. As more and more code is generated, the compilation speed is slower and slower, the packaging time is one minute faster, and hot updates are slower and slower, affecting the development efficiency
  2. No introductioneslintSyntax check, different code styles
  3. webpackConfigure trival
  4. More and more UI libraries support Vue CLI3

Upgrade purpose

  1. Improved compilation speed
  2. invue cli3When creating a project, importeslint, unified code style, convenient codereview(New front-end doesn’t want to be introduced separately)
  3. All configurationvue cli3The extra configuration can be handled in vue.config.js
  4. Adapt to the trend of technological development 🐶

The project to upgrade

Vue CL3 create project

vue create hello-world
Copy the code

For details, refer to the Vue CLI3 documentation

The configurations I use are VUe-Router, vuex, less, Babel, esLint

File transfer

SRC directory

Simply porting SRC,

Copy SRC /pages, SRC/app. vue, SRC /index.html

Copy the SRC/main. Js

Error:

Console error 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 Object1. (app.js:2555)
    at __webpack_require__ (app.js:770)
    at app.js:908
    at app.js:911Command line error * cube- UIin ./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

Copy the code

Reason: No third-party libraries and files have been introduced

Solution:

  1. Import the corresponding LESS file and JS file
  2. Installing third-party Libraries
npm i --save vue-resource vue-lazyload  mint-ui vconsole
Copy the code
  1. The introduction of cube UI in Vue CLI3 is different from that of the Vue CLI. For details, see the documentation
vue add cube-ui
Copy the code

I use global import here, because the original code is also global reference, in fact, should be introduced as needed, this will be optimized after the migration work is completed, during the upgrade work will not make too much change to the business code

Once global is introduced, the SRC directory will have an additional cube-ui.js file

  1. An error message is displayed after the service is restarted
[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>)
Copy the code

Cause: The introduced vue. Js version does not match the main.js script

Solution: Modify main.js

/ / the original
new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>'.components: { App }
})
/ / modify
new Vue({
  router,
  store,
  render: h= > h(App)
}).$mount('#app')
Copy the code
  1. Compile successfully

Copying routing files

The route file of Vue CLI is stored in router folder, the route of Vue CLI3 is stored in SRC /router.js, I use the file structure of Vue CLI, still stored in router folder, error: missing components file, next

Copy the Components folder

Console crazy error, look carefully, there are the following

  1. File names introduce case problems
  2. Custom instruction files, mixins files have not been introduced
  3. Some third-party libraries referenced within the component have not yet been installednpm i @chenfengyuan/vue-qrcode axios clipboard html2canvas particles.js swiper vue-awesome-swiper weixin-js-sdk --save
  4. Error reporting less variable reference

Solution: introduce global less variable in vue.config.js, refer to vue CLI3 documentation

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') // Globally imported less is required]})}Copy the code

JQuery reference

The project also uses jquery😭, used in many places

Solution:

  1. npm install jquery --save
  2. checkpackage.jsonLet’s see if I’ve introduced it
  3. .eslintrc.jsFile,envaddjquery:true
  4. Vue.config.js adds plug-ins
const webpack = require('webpack')
module.exports = {
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        $: 'jquery'.jQuery: 'jquery'.'windows.jQuery': 'jquery'}})]},Copy the code
  1. The main. Js:import $ from 'jquery'

Store file import

My store file is stored in the Store folder. After migrating it, I can change the import path of main.js

At this point, the project will basically compile normally and you can see the basic outline of the page, but there are still problems such as the size of the UI style is not correct, and the request is cross-domain

Cross domain

It is configured in vue.config.js

  devServer: {
    port: 8080.proxy: {
      '/apis': {
        target: 'http://dev.xxx.com'.changeOrigin: true.pathRewrite: {
          '/apis': ' '}}}}Copy the code

rem

Modify postcss. Config. Js

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

Copy the code

Ok, at this point, the style is fine and the request can be sent and received normally.

On the surface, it looks no different from normal projects, but when I open the console, I see an error.

vue-awesome-swiper

Swiper.vue? 56a2:97 Uncaught (in promise) TypeError: _this.swiper.lockSwipes is not a function
    at eval(Swiper.vue? 56a2:97)Copy the code

LockSwipes API has been replaced with allowSlideNext

Solution:

this.swiper.lockSwipes() 
/ / replace
this.swiper.allowSlideNext = false
Copy the code

The icon is a bit out of place in some places

The default style of cube-UI introduced globally is the cause of this problem. Add a sentence to the reset.less file

  body {
    line-height: initial;
  }
Copy the code

Compile successfully

At this point, the project is running successfully under Vue CLI3. A little bit here and there, yeah, no mistakes, so what about the packing

packaging

Packaging configuration

The original packaging configuration was in config/index.js

const path = require('path')

module.exports = {
  build: {
    // Template for index.html
    index: path.resolve(__dirname, '.. /dist/index.html'),
    // Paths
    // Outputs the static resource path
    assetsRoot: path.resolve(__dirname, '.. /.. /.. /.. /resource'),
    // Outputs the static resource subdirectory
    assetsSubDirectory: 'static'.assetsPublicPath: 'resource/',}}Copy the code

The index.html generated after the project is packaged is different from the directory of the generated static resource, and the static resource path referenced by the packaged HTML file must be relative (because the development, test and production all use the same code).

The configuration in vue.config.js also needs to be modified:

{
  publicPath: process.env.NODE_ENV === 'production' ? './resource' : '/'.indexPath: path.resolve(__dirname, 'dist/index.php'),// Output the HTML directory
  outputDir: path.resolve(__dirname, '.. /.. /.. /resource'),// Static resource directory
  assetsDir: 'static'.// Static resource subdirectory
}
Copy the code

The documentation for vue CLI3 simply mentions publicPath, assetsDir.. Google for a long time, checked the data for a long time, finally let me find the answer 😭

CSS minification error

NPM run build

Error:

CSS minification error: Cannot read property 'type' of undefined. File: css/doubleEleven.08c6b745.css
Copy the code

It took me half a day to find this error. There was very little information about this error. Finally, I saw it on an issue of Vue CLI3, which was closed due to non-standard questioning.

Although I don’t know why, I tried to look up the project code and found:

transform: rotate3d(0, 1, 00deg);
Copy the code

Correct immediately, package again, package successfully, and run well in the development, test environment, yeah ️✌️

conclusion

😂 upgrade vue CLI3 after the code check really strict a lot of, above the error in the original edit package no problem, here is the true form of the show, but finally completed the upgrade, in the debugging obviously feel hot update speed improved a lot.

At this point, the migration is complete, of course, some of the code still needs to be stored in Lint or manually formatted, but that will come later.