diff --git a/packages/@vue/cli-plugin-typescript/__tests__/tsPluginBabel.spec.js b/packages/@vue/cli-plugin-typescript/__tests__/tsPluginBabel.spec.js
index 4f8583b0a6..6319dd5aa0 100644
--- a/packages/@vue/cli-plugin-typescript/__tests__/tsPluginBabel.spec.js
+++ b/packages/@vue/cli-plugin-typescript/__tests__/tsPluginBabel.spec.js
@@ -17,9 +17,8 @@ test('using correct loader', async () => {
   const config = service.resolveWebpackConfig()
   // eslint-disable-next-line no-shadow
   const rule = config.module.rules.find(rule => rule.test.test('foo.ts'))
-  expect(rule.use[0].loader).toMatch(require.resolve('cache-loader'))
-  expect(rule.use[1].loader).toMatch(require.resolve('babel-loader'))
-  expect(rule.use[2].loader).toMatch(require.resolve('ts-loader'))
+  expect(rule.use[0].loader).toMatch(require.resolve('babel-loader'))
+  expect(rule.use[1].loader).toMatch(require.resolve('ts-loader'))
 })
 
 const creatorOptions = {
diff --git a/packages/@vue/cli-plugin-typescript/index.js b/packages/@vue/cli-plugin-typescript/index.js
index ed94d3f7f5..33abae3788 100644
--- a/packages/@vue/cli-plugin-typescript/index.js
+++ b/packages/@vue/cli-plugin-typescript/index.js
@@ -30,16 +30,6 @@ module.exports = (api, projectOptions) => {
       tsxRule.use(name).loader(loader).options(options)
     }
 
-    addLoader({
-      name: 'cache-loader',
-      loader: require.resolve('cache-loader'),
-      options: api.genCacheConfig('ts-loader', {
-        'ts-loader': require('ts-loader/package.json').version,
-        'typescript': require('typescript/package.json').version,
-        modern: !!process.env.VUE_CLI_MODERN_BUILD
-      }, 'tsconfig.json')
-    })
-
     if (useThreads) {
       addLoader({
         name: 'thread-loader',
diff --git a/packages/@vue/cli-plugin-typescript/package.json b/packages/@vue/cli-plugin-typescript/package.json
index 65504daf82..c78a117cba 100644
--- a/packages/@vue/cli-plugin-typescript/package.json
+++ b/packages/@vue/cli-plugin-typescript/package.json
@@ -27,7 +27,6 @@
     "@types/webpack-env": "^1.15.2",
     "@vue/cli-shared-utils": "^5.0.0-beta.3",
     "babel-loader": "^8.2.2",
-    "cache-loader": "^4.1.0",
     "fork-ts-checker-webpack-plugin": "^6.1.0",
     "globby": "^11.0.2",
     "thread-loader": "^3.0.0",
diff --git a/packages/@vue/cli-service/lib/config/base.js b/packages/@vue/cli-service/lib/config/base.js
index 7deef3b312..2a6a4253e5 100644
--- a/packages/@vue/cli-service/lib/config/base.js
+++ b/packages/@vue/cli-service/lib/config/base.js
@@ -18,6 +18,9 @@ module.exports = (api, options) => {
         .rule('esm')
           .test(/\.m?jsx?$/)
           .resolve.set('fullySpecified', false)
+
+      webpackConfig
+        .cache({ type: 'filesystem' })
     }
 
     webpackConfig
@@ -57,12 +60,6 @@ module.exports = (api, options) => {
     // vue-loader --------------------------------------------------------------
     if (vueMajor === 2) {
       // for Vue 2 projects
-      const vueLoaderCacheConfig = api.genCacheConfig('vue-loader', {
-        'vue-loader': require('@vue/vue-loader-v15/package.json').version,
-        '@vue/component-compiler-utils': require('@vue/component-compiler-utils/package.json').version,
-        'vue-template-compiler': require('vue-template-compiler/package.json').version
-      })
-
       webpackConfig.resolve
         .alias
           .set(
@@ -75,17 +72,13 @@ module.exports = (api, options) => {
       webpackConfig.module
         .rule('vue')
           .test(/\.vue$/)
-          .use('cache-loader')
-            .loader(require.resolve('cache-loader'))
-            .options(vueLoaderCacheConfig)
-            .end()
           .use('vue-loader')
             .loader(require.resolve('@vue/vue-loader-v15'))
             .options(Object.assign({
               compilerOptions: {
                 whitespace: 'condense'
               }
-            }, vueLoaderCacheConfig))
+            }))
 
       webpackConfig
         .plugin('vue-loader')
@@ -101,11 +94,6 @@ module.exports = (api, options) => {
             .prepend(path.resolve(__dirname, './vue-loader-v15-resolve-compat'))
     } else if (vueMajor === 3) {
       // for Vue 3 projects
-      const vueLoaderCacheConfig = api.genCacheConfig('vue-loader', {
-        'vue-loader': require('vue-loader/package.json').version,
-        '@vue/compiler-sfc': require('@vue/compiler-sfc/package.json').version
-      })
-
       webpackConfig.resolve
         .alias
           .set(
@@ -118,14 +106,9 @@ module.exports = (api, options) => {
       webpackConfig.module
         .rule('vue')
           .test(/\.vue$/)
-          .use('cache-loader')
-            .loader(require.resolve('cache-loader'))
-            .options(vueLoaderCacheConfig)
-            .end()
           .use('vue-loader')
             .loader(require.resolve('vue-loader'))
             .options({
-              ...vueLoaderCacheConfig,
               babelParserPlugins: ['jsx', 'classProperties', 'decorators-legacy']
             })
             .end()
diff --git a/packages/@vue/cli-service/package.json b/packages/@vue/cli-service/package.json
index fc6977e90d..bdd29fb008 100644
--- a/packages/@vue/cli-service/package.json
+++ b/packages/@vue/cli-service/package.json
@@ -40,7 +40,6 @@
     "address": "^1.1.2",
     "autoprefixer": "^10.2.4",
     "browserslist": "^4.16.3",
-    "cache-loader": "^4.1.0",
     "case-sensitive-paths-webpack-plugin": "^2.3.0",
     "cli-highlight": "^2.1.10",
     "clipboardy": "^2.3.0",