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

babel-loader cache won't be updated after updating transpileDep with npm #4438

Closed
fangbinwei opened this issue Aug 14, 2019 · 9 comments · Fixed by #5113
Closed

babel-loader cache won't be updated after updating transpileDep with npm #4438

fangbinwei opened this issue Aug 14, 2019 · 9 comments · Fixed by #5113

Comments

@fangbinwei
Copy link
Collaborator

fangbinwei commented Aug 14, 2019

Version

4.0.0-beta.3

Reproduction link

https://github.com/fangbinwei/vue-cli-cache-loader-bug

Environment info

  System:
    OS: macOS 10.14.5
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  Binaries:
    Node: 11.12.0 - ~/.nvm/versions/node/v11.12.0/bin/node
    Yarn: 1.13.0 - /usr/local/bin/yarn
    npm: 6.7.0 - ~/.nvm/versions/node/v11.12.0/bin/npm
  Browsers:
    Chrome: 76.0.3809.100
    Firefox: Not Found
    Safari: 12.1.1
  npmPackages:
    @vue/babel-helper-vue-jsx-merge-props:  1.0.0
    @vue/babel-plugin-transform-vue-jsx:  1.0.0
    @vue/babel-preset-app:  4.0.0-beta.3
    @vue/babel-preset-jsx:  1.1.0
    @vue/babel-sugar-functional-vue:  1.0.0
    @vue/babel-sugar-inject-h:  1.0.0
    @vue/babel-sugar-v-model:  1.0.0
    @vue/babel-sugar-v-on:  1.1.0
    @vue/cli-overlay:  4.0.0-beta.3
    @vue/cli-plugin-babel: ^4.0.0-beta.3 => 4.0.0-beta.3
    @vue/cli-plugin-eslint: ^4.0.0-beta.3 => 4.0.0-beta.3
    @vue/cli-service: ^4.0.0-beta.3 => 4.0.0-beta.3
    @vue/cli-shared-utils:  4.0.0-beta.3
    @vue/component-compiler-utils:  2.6.0 (3.0.0)
    @vue/preload-webpack-plugin:  1.1.1
    @vue/web-component-wrapper:  1.2.0
    eslint-plugin-vue: ^5.0.0 => 5.2.3
    vue: ^2.6.10 => 2.6.10
    vue-eslint-parser:  5.0.0
    vue-hot-reload-api:  2.3.3
    vue-loader:  15.7.1
    vue-style-loader:  4.1.2
    vue-template-compiler: ^2.6.10 => 2.6.10
    vue-template-es2015-compiler:  1.9.1
  npmGlobalPackages:
    @vue/cli: 4.0.0-beta.3

Steps to reproduce

git clone to local

npm install
// check page
npm run serve

npm i sleepwalker-fakezz@2.0.0

//check page
npm run serve

What is expected?

the cache of vue-loader and babel-loader both will be updated.

In other words, the page show string old template old js before i update transpileDep. I hope the page can show string new template new js if I run dev server after updating transpileDep.

What is actually happening?

only vue-loader cache can be updated, but babel loader cache remains the old version.

the page show string new template old js . things related with template of .vue can be updated, but js code in <script> of .vue and somewhere else remains the old version

But, use yarn to install deps, everything is ok. It seems yarn delete the node_module/.cache after yarn add

related issue #3635, #2450

Background

our team use transpileDependencies to import our private library which is released frequently. Team member usually forget to delete cache file after they update library, and get Inexplicable result after running dev server. We use npm because of some history reason.

@fangbinwei
Copy link
Collaborator Author

fangbinwei commented Aug 14, 2019

I think this PR #3865 fix the problem of vue-loader cache.
But for babel-loader cache, the hash(cacheIdentifier) won't be changed, because the content of configFiles is always come from babel.config.js(if existed)

.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'
]))

if I do like this to generate new cache file when lockfiles have been updated , the problem can be solved. But I am not sure if it's elegant.

genCacheConfig (id, partialIdentifier, configFiles = []) {

    const variables = {
      // ...
      configFiles: ''
    }

    for (const file of configFiles) {
      const content = readConfig(file)
      if (content) {
        variables.configFiles += content.replace(/\r\n?/g, '\n')
      }
    }

@LinusBorg
Copy link
Member

we could likely just add api.service.pkg.dependencies to the cache inputs

@CommanderXL
Copy link

@fangbinwei Well, I don't think it's the bug of vue-loader cache or some other packages.Cache loader use mtime of a file to decide to use cache content or not.In your test project(https://github.com/fangbinwei/vue-cli-cache-loader-bug). You can use fs.stasSync api to test your 'sleepwalker-fakezz' package.You will find the mtime of index.js file don't change in the version 1.0.0 and 2.0.0。So cache-loader will use the cache of 1.0.0 not 2.0.0 to build the project.

@sodatea
Copy link
Member

sodatea commented Jan 27, 2020

Lockfiles have already been taken into account since 3.7.0 so I think it's not related to the cache config. #3865

@sodatea
Copy link
Member

sodatea commented Jan 27, 2020

webpack-contrib/cache-loader#34 mtime is unreliable since npm 5.8. But that shouldn't affect the Vue CLI cache because we've already taken lockfile into account. Maybe it's a bug in vue-loader cache. Will investigate later.

@sodatea sodatea removed the has PR label Jan 27, 2020
@sodatea
Copy link
Member

sodatea commented Jan 27, 2020

But it only breaks when babel plugin presents…

@sodatea
Copy link
Member

sodatea commented Jan 27, 2020

😂So it's a bug in the implementation. Lockfiles are not read sometimes.
https://github.com/vuejs/vue-cli/pull/3865/files#diff-04612bf191a2c1a06ac248910d9e9415R189

Lockfiles and configFiles need to be treated differently. Config files have priorities so only the first encountered one needs to be read; all lock files should be taken into account.

@CommanderXL
Copy link

@sodatea

In the PluginAPI.js of @vue/cli-service, variables.configFiles get the content will break out of the for...of cycle.So it can't read the package-lock.json file.

 for (const file of configFiles) {
  const content = readConfig(file)
  if (content) {
    variables.configFiles = content.replace(/\r\n?/g, '\n')
    break
  }
}

I just see the code you have commit.You add the dependencies property to variables for hash.I think this could make sure for the new hash after updating package-lock.json and packge.json.

Thanks.

@fangbinwei
Copy link
Collaborator Author

fangbinwei commented Jan 28, 2020

Thanks for your reply @CommanderXL . So it seems that mtime is the root cause ? The mtime of transpileDep affects the webpack watch mode/ HMR and cache-loader. Caching depends on lock file can solve this issue in some degree.

Config files have priorities so only the first encountered one needs to be read;

But for cli-plugin-babel, config files are babel.config.js and .browserslistrc. I believe it's not priority relationships, and these config files should be considered both.

If I place config in dedicated config files, the modification of .browserslistrc will be ignored because of cache hit in webpack build process.

Suddenly, I found you have changed the implementation 🤣 @sodatea

pksunkara pushed a commit that referenced this issue Jan 30, 2020
* fix: correctly calculate cacheIdentifier from lockfiles

follow up of #3865
fixes #4438

* Revert "fix: correctly calculate cacheIdentifier from lockfiles"

This reverts commit dbce88b.

* fix: should take all configFiles and lockfiles into account

The previous implementation is based on the assumption that config files
have precendences, e.g. `.eslintrc.js` will take higher precendence
over `.eslintrc`, and only one will take effect.

This is not accurate however. For example, babel relies on both babel
config and browserslist config, so we need to deal with 2 config files.
mactanxin pushed a commit to mactanxin/vue-cli that referenced this issue Feb 11, 2020
* fix: correctly calculate cacheIdentifier from lockfiles

follow up of vuejs#3865
fixes vuejs#4438

* Revert "fix: correctly calculate cacheIdentifier from lockfiles"

This reverts commit dbce88b.

* fix: should take all configFiles and lockfiles into account

The previous implementation is based on the assumption that config files
have precendences, e.g. `.eslintrc.js` will take higher precendence
over `.eslintrc`, and only one will take effect.

This is not accurate however. For example, babel relies on both babel
config and browserslist config, so we need to deal with 2 config files.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants