Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VUE CLI3缓存旧版本的VUE组件(npm包)问题 #2

Open
ziyi2 opened this issue Mar 27, 2019 · 2 comments
Open

VUE CLI3缓存旧版本的VUE组件(npm包)问题 #2

ziyi2 opened this issue Mar 27, 2019 · 2 comments
Labels

Comments

@ziyi2
Copy link
Owner

ziyi2 commented Mar 27, 2019

发现问题

在使用VUE CLI3生成项目时,引入未打包的组件(这里的组件发布成了npm包,抛出的仍然是原生态的.vue文件,由于该组件采用VUE CLI3调试和生成,且目标环境是VUE CLI3,因此组件可以和VUE CLI3业务代码完美契合,同时也可以防止二次打包问题,当然有使用一些VUE CLI3不包含的特殊webpack loader的VUE组件仍然是推荐打包后发布),发现组件的版本更新后,启动项目显示的仍然是旧版本的组件

组件(npm包)结构

├── packages             
   └── xxx
      ├── src                 
        └── xxx.vue       
      ├── theme                 
        └── index.scss      
      ├── index.js                
      └── package.json 

package.json中的main字段指向了index.js

VUE CLI项目中引入

// src/main.js
import xxx from 'xxx'
import 'xxx/theme/index.scss'

Vue.use(xxx)

定位问题

第一反应是与缓存相关,于是使用VUE CLI3/开发/webpack相关/审查项目的 webpack 配置中的vue inspect功能输出了当前项目的Webpack配置,寻找出与cache-loader相关的配置信息:

 /* config.module.rule('vue') */
 {
   test: /\.vue$/,
   use: [
     /* config.module.rule('vue').use('cache-loader') */
     {
       loader: 'cache-loader',
       options: {
         cacheDirectory: 'G:\\dolphin-vuc-cli3\\dolphin_issc\\node_modules\\.cache\\vue-loader',
         cacheIdentifier: 'b466c286'
       }
     },
     /* config.module.rule('vue').use('vue-loader') */
     {
       loader: 'vue-loader',
       options: {
         compilerOptions: {
           preserveWhitespace: false
         },
         cacheDirectory: 'G:\\dolphin-vuc-cli3\\dolphin_issc\\node_modules\\.cache\\vue-loader',
         cacheIdentifier: 'b466c286'
       }
     }
   ]
 },

/* config.module.rule('js') */
{
   test: /\.m?jsx?$/,
   exclude: [
     function () { /* omitted long function */ }
   ],
   use: [
     /* config.module.rule('js').use('cache-loader') */
     {
       loader: 'cache-loader',
       options: {
         cacheDirectory: 'G:\\dolphin-vuc-cli3\\dolphin_issc\\node_modules\\.cache\\babel-loader',
         cacheIdentifier: 'b77d1c56'
       }
     },
     /* config.module.rule('js').use('babel-loader') */
     {
       loader: 'babel-loader'
     }
   ]
 },

发现cache-loader匹配了/\.vue$//\.m?jsx?$/文件,因此需要去除cache-loader并观察是否是该loader引起的问题。

更改webpack配置文件

由于VUE CLI3项目使用webpack-chain链式操作在源码中动态生成Webpack配置,因此有两种方式更改VUE CLI3项目的配置信息:

  • vue.config.js:使用webpack-chainvue.config.js中覆盖默认的config.module.rule('vue')config.module.rule('js'),去除两者的缓存配置。
  • @vue/cli-service、@vue/cli-plugin-babel:更改config.module.rule('vue')config.module.rule('js')配置所在的源码文件。

这里采用第二种方式进行验证,去除config.module.rule('vue')中的缓存配置:

// @vue/cli-service/lib/config/base.js
webpackConfig.module
 .rule('vue')
   .test(/\.vue$/)
   // .use('cache-loader')
   //   .loader('cache-loader')
   //   .options(vueLoaderCacheConfig)
   //   .end()
   .use('vue-loader')
     .loader('vue-loader')
     .options(Object.assign({
       compilerOptions: {
         preserveWhitespace: false
       }
     // 第一次尝试的时候没注释这里,只注释了cache-loader,导致问题一直排查不出来
     // 花费了两个晚上时间,代价有点大(因为第一次尝试就将vue-loader排除在外)
     // }, vueLoaderCacheConfig))
     }))

去除config.module.rule('js')中的缓存配置:

// @vue/cli-plugin-babel/index.js
const jsRule = webpackConfig.module
     .rule('js')
       .test(/\.m?jsx?$/)
       .exclude
         .add(filepath => {
           // always transpile js in vue files
           if (/\.vue\.jsx?$/.test(filepath)) {
             return false
           }
           // exclude dynamic entries from cli-service
           if (filepath.startsWith(cliServicePath)) {
             return true
           }
           
           // check if this is something the user explicitly wants to transpile
           if (transpileDepRegex && transpileDepRegex.test(filepath)) {
             return false
           }
           // Don't transpile node_modules
           return /node_modules/.test(filepath)
         })
         .end()
       // .use('cache-loader')
       //   .loader('cache-loader')
       //   .options(api.genCacheConfig('babel-loader', {
       //     '@babel/core': require('@babel/core/package.json').version,
       //     '@vue/babel-preset-app': require('@vue/babel-preset-app/package.json').version,
       //     'babel-loader': require('babel-loader/package.json').version,
       //     modern: !!process.env.VUE_CLI_MODERN_BUILD,
       //     browserslist: api.service.pkg.browserslist
       //   }, [
       //     'babel.config.js',
       //     '.browserslistrc'
       //   ]))
       //   .end()

更改源码后,验证发现是cache-loader引起的问题,缩小范围发现是vue-loader的缓存配置引起的问题。

结论

VUE CLI3缓存旧版本的VUE组件(npm包)是由于vue-loader中配置了缓存而引起的,并且发现VUE CLI3的 源码中并没有可以关闭该缓存的配置项,因此这里提供了以下解决方案:

1、对VUE CLI官方提出 issue ,等待官方解决该问题(目前仍然没有解决)。

2、如果需要更新组件版本,首先删除node_modules下的.cache文件,然后更新组件版本启动项目。

3、更给vue.config.js,去除config.module.rule('vue')中的缓存配置。

参考链接

@ziyi2
Copy link
Owner Author

ziyi2 commented Mar 27, 2019

@ziyi2
Copy link
Owner Author

ziyi2 commented Apr 13, 2019

#4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant